{"record":{"id":"3cc6547052121a87","repo":"angular/angular","slug":"ng02960","errorCode":"NG02960","errorMessage":"${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.","messagePattern":"(.+?) the intrinsic image is significantly larger than necessary\\. \nRendered image size: (.+?)w x (.+?)h\\. \nIntrinsic image size: (.+?)w x (.+?)h\\. \nRecommended intrinsic image size: (.+?)w x (.+?)h\\. \nNote: Recommended intrinsic image size is calculated assuming a maximum DPR of (.+?)\\. To improve loading time, resize the image or consider using the \"ngSrcset\" and \"sizes\" attributes\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts","lineNumber":1164,"sourceCode":"            `does not match the image's intrinsic aspect ratio. ` +\n            `\\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h ` +\n            `(aspect-ratio: ${round(intrinsicAspectRatio)}). \\nRendered image size: ` +\n            `${renderedWidth}w x ${renderedHeight}h (aspect-ratio: ` +\n            `${round(renderedAspectRatio)}). \\nThis issue can occur if \"width\" and \"height\" ` +\n            `attributes are added to an image without updating the corresponding ` +\n            `image styling. To fix this, adjust image styling. In most cases, ` +\n            `adding \"height: auto\" or \"width: auto\" to the image styling will fix ` +\n            `this issue.`,\n        ),\n      );\n    } else if (!dir.ngSrcset && nonZeroRenderedDimensions) {\n      // If `ngSrcset` hasn't been set, sanity check the intrinsic size.\n      const recommendedWidth = RECOMMENDED_SRCSET_DENSITY_CAP * renderedWidth;\n      const recommendedHeight = RECOMMENDED_SRCSET_DENSITY_CAP * renderedHeight;\n      const oversizedWidth = intrinsicWidth - recommendedWidth >= OVERSIZED_IMAGE_TOLERANCE;\n      const oversizedHeight = intrinsicHeight - recommendedHeight >= OVERSIZED_IMAGE_TOLERANCE;\n      if (oversizedWidth || oversizedHeight) {\n        console.warn(\n          formatRuntimeError(\n            RuntimeErrorCode.OVERSIZED_IMAGE,\n            `${imgDirectiveDetails(dir.ngSrc)} the intrinsic image is significantly ` +\n              `larger than necessary. ` +\n              `\\nRendered image size: ${renderedWidth}w x ${renderedHeight}h. ` +\n              `\\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h. ` +\n              `\\nRecommended intrinsic image size: ${recommendedWidth}w x ${recommendedHeight}h. ` +\n              `\\nNote: Recommended intrinsic image size is calculated assuming a maximum DPR of ` +\n              `${RECOMMENDED_SRCSET_DENSITY_CAP}. To improve loading time, resize the image ` +\n              `or consider using the \"ngSrcset\" and \"sizes\" attributes.`,\n          ),\n        );\n      }\n    }\n  };\n\n  const removeLoadListenerFn = renderer.listen(img, 'load', callback);\n","sourceCodeStart":1146,"sourceCodeEnd":1182,"githubUrl":"https://github.com/angular/angular/blob/51cb07e98081ab7e4e84a9e0949266a8e19cca84/packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts#L1146-L1182","documentation":"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.","triggerScenarios":"`<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.","commonSituations":"Serving camera-original exports through the default loader (no CDN resizing); CMS originals used directly; assets over-provisioned for hypothetical 4x DPR screens.","solutions":["Add `ngSrcset` with `sizes` so the browser picks a right-sized variant: `ngSrcset=\"400w, 800w, 1200w\" sizes=\"(max-width: 600px) 400px, 800px\"`","Configure an image loader/CDN (or build-time resizing) so the base ngSrc itself is appropriately sized","Resize the source asset to what real DPRs need (~2x the largest rendered size is the guideline)"],"exampleFix":"<!-- before: 4000x3000 file shown at ~400px -->\n<img ngSrc=\"photo.jpg\" width=\"800\" height=\"600\" />\n\n<!-- after -->\n<img ngSrc=\"photo.jpg\" width=\"800\" height=\"600\"\n     ngSrcset=\"400w, 800w, 1200w\" sizes=\"(max-width: 600px) 400px, 800px\" />","handlingStrategy":"validation","validationCode":"function isIntrinsicOversized(\n  natural: {w: number; h: number},\n  rendered: {w: number; h: number},\n) {\n  const cap = 2;    // RECOMMENDED_SRCSET_DENSITY_CAP\n  const tol = 1000; // OVERSIZED_IMAGE_TOLERANCE\n  return natural.w - cap * rendered.w >= tol || natural.h - cap * rendered.h >= tol;\n}\n// use in a dev/e2e audit over rendered images","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair ngSrc with ngSrcset + sizes for content images","Route images through a resizing loader/CDN instead of serving originals","Cap generated asset widths at ~2x their largest rendered size"],"tags":["ngoptimizedimage","srcset","oversized-image","bandwidth","performance"],"backgroundTag":"oversized-image-asset","analyzedSha":"51cb07e98081ab7e4e84a9e0949266a8e19cca84","analyzedAt":"2026-08-22T07:04:54.531Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}