angular/angular · warning

NG02960

NG02960

Error message

${imgDirectiveDetails(dir.ngSrc)} the intrinsic image is significantly larger than necessary. 
Rendered image size: ${renderedWidth}w x ${renderedHeight}h. 
Intrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h. 
Recommended intrinsic image size: ${recommendedWidth}w x ${recommendedHeight}h. 
Note: Recommended intrinsic image size is calculated assuming a maximum DPR of ${RECOMMENDED_SRCSET_DENSITY_CAP}. To improve loading time, resize the image or consider using the "ngSrcset" and "sizes" attributes.

What it means

With no `ngSrcset` set, NgOptimizedImage's dev-mode validator compares the intrinsic file size against a recommended ceiling of 2x the rendered size (RECOMMENDED_SRCSET_DENSITY_CAP = 2, with OVERSIZED_IMAGE_TOLERANCE = 1000px slack). If intrinsic width or height exceeds that recommendation, warning NG02960 (OVERSIZED_IMAGE) fires: the browser downloaded far more image data than any common device pixel ratio needs.

Source

Thrown at packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts:1164

            `does not match the image's intrinsic aspect ratio. ` +
            `\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h ` +
            `(aspect-ratio: ${round(intrinsicAspectRatio)}). \nRendered image size: ` +
            `${renderedWidth}w x ${renderedHeight}h (aspect-ratio: ` +
            `${round(renderedAspectRatio)}). \nThis issue can occur if "width" and "height" ` +
            `attributes are added to an image without updating the corresponding ` +
            `image styling. To fix this, adjust image styling. In most cases, ` +
            `adding "height: auto" or "width: auto" to the image styling will fix ` +
            `this issue.`,
        ),
      );
    } else if (!dir.ngSrcset && nonZeroRenderedDimensions) {
      // If `ngSrcset` hasn't been set, sanity check the intrinsic size.
      const recommendedWidth = RECOMMENDED_SRCSET_DENSITY_CAP * renderedWidth;
      const recommendedHeight = RECOMMENDED_SRCSET_DENSITY_CAP * renderedHeight;
      const oversizedWidth = intrinsicWidth - recommendedWidth >= OVERSIZED_IMAGE_TOLERANCE;
      const oversizedHeight = intrinsicHeight - recommendedHeight >= OVERSIZED_IMAGE_TOLERANCE;
      if (oversizedWidth || oversizedHeight) {
        console.warn(
          formatRuntimeError(
            RuntimeErrorCode.OVERSIZED_IMAGE,
            `${imgDirectiveDetails(dir.ngSrc)} the intrinsic image is significantly ` +
              `larger than necessary. ` +
              `\nRendered image size: ${renderedWidth}w x ${renderedHeight}h. ` +
              `\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h. ` +
              `\nRecommended intrinsic image size: ${recommendedWidth}w x ${recommendedHeight}h. ` +
              `\nNote: Recommended intrinsic image size is calculated assuming a maximum DPR of ` +
              `${RECOMMENDED_SRCSET_DENSITY_CAP}. To improve loading time, resize the image ` +
              `or consider using the "ngSrcset" and "sizes" attributes.`,
          ),
        );
      }
    }
  };

  const removeLoadListenerFn = renderer.listen(img, 'load', callback);

View on GitHub (pinned to 51cb07e980)

Solutions

  1. Add `ngSrcset` with `sizes` so the browser picks a right-sized variant: `ngSrcset="400w, 800w, 1200w" sizes="(max-width: 600px) 400px, 800px"`
  2. Configure an image loader/CDN (or build-time resizing) so the base ngSrc itself is appropriately sized
  3. Resize the source asset to what real DPRs need (~2x the largest rendered size is the guideline)

Example fix

<!-- before: 4000x3000 file shown at ~400px -->
<img ngSrc="photo.jpg" width="800" height="600" />

<!-- after -->
<img ngSrc="photo.jpg" width="800" height="600"
     ngSrcset="400w, 800w, 1200w" sizes="(max-width: 600px) 400px, 800px" />
Defensive patterns

Strategy: validation

Validate before calling

function isIntrinsicOversized(
  natural: {w: number; h: number},
  rendered: {w: number; h: number},
) {
  const cap = 2;    // RECOMMENDED_SRCSET_DENSITY_CAP
  const tol = 1000; // OVERSIZED_IMAGE_TOLERANCE
  return natural.w - cap * rendered.w >= tol || natural.h - cap * rendered.h >= tol;
}
// use in a dev/e2e audit over rendered images

Prevention

When it happens

Trigger: `<img ngSrc="photo.jpg" width="800" height="600">` rendering at roughly 400x300 CSS pixels without `ngSrcset`, where photo.jpg is 4000x3000 — intrinsic exceeds 2x rendered + 1000 in both axes; fires in dev mode after load.

Common situations: Serving camera-original exports through the default loader (no CDN resizing); CMS originals used directly; assets over-provisioned for hypothetical 4x DPR screens.

Related errors


AI-assisted analysis of angular/angular@51cb07e980 (2026-08-22). Data as JSON: /api/errors/3cc6547052121a87. Report an issue: GitHub.