8000 fix(common): issue a warning instead of an error when `NgOptimizedImage` exceeds the preload limit by alan-agius4 · Pull Request #60879 · angular/angular · GitHub
[go: up one dir, main page]

Skip to content

fix(common): issue a warning instead of an error when NgOptimizedImage exceeds the preload limit #60879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
inject,
Injectable,
Renderer2,
ɵRuntimeError as RuntimeError,
ɵformatRuntimeError as formatRuntimeError,
DOCUMENT,
} from '@angular/core';

Expand All @@ -30,6 +30,7 @@ import {DEFAULT_PRELOADED_IMAGES_LIMIT, PRELOADED_IMAGES} from './tokens';
export class PreloadLinkCreator {
private readonly preloadedImages = inject(PRELOADED_IMAGES);
private readonly document = inject(DOCUMENT);
private errorShown = false;

/**
* @description Add a preload `<link>` to the `<head>` of the `index.html` that is served from the
Expand All @@ -48,17 +49,21 @@ export class PreloadLinkCreator {
* @param sizes The value of the `sizes` attribute passed in to the `<img>` tag
*/
createPreloadLinkTag(renderer: Renderer2, src: string, srcset?: string, sizes?: string): void {
if (ngDevMode) {
if (this.preloadedImages.size >= DEFAULT_PRELOADED_IMAGES_LIMIT) {
throw new RuntimeError(
if (
ngDevMode &&
!this.errorShown &&
this.preloadedImages.size >= DEFAULT_PRELOADED_IMAGES_LIMIT
) {
this.errorShown = true;
console.warn(
formatRuntimeError(
RuntimeErrorCode.TOO_MANY_PRELOADED_IMAGES,
ngDevMode &&
`The \`NgOptimizedImage\` directive has detected that more than ` +
`${DEFAULT_PRELOADED_IMAGES_LIMIT} images were marked as priority. ` +
`This might negatively affect an overall performance of the page. ` +
`To fix this, remove the "priority" attribute from images with less priority.`,
);
}
`The \`NgOptimizedImage\` directive has detected that more than ` +
`${DEFAULT_PRELOADED_IMAGES_LIMIT} images were marked as priority. ` +
`This might negatively affect an overall performance of the page. ` +
`To fix this, remove the "priority" attribute from images with less priority.`,
),
);
}

if (this.preloadedImages.has(src)) {
Expand Down
33 changes: 17 additions & 16 deletions packages/common/test/directives/ng_optimized_image_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ describe('Image directive', () => {
preloadLinks[0]!.remove();
});

it('should error when the number of preloaded images is larger than the limit', () => {
it('should warn when the number of preloaded images is larger than the limit', () => {
// Only run this test in a browser since the Node-based DOM mocks don't
// allow to override `HTMLImageElement.prototype.setAttribute` easily.
if (!isBrowser) return;
Expand All @@ -157,22 +157,23 @@ describe('Image directive', () => {
});

const template = `
<img ngSrc="preloaderror2/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror3/img.png" width="150" height="50" priority>
<img ngSrc="preloaderro4/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror5/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror6/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror7/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror8/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror9/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror10/img.png" width="150" height="50" priority>
`;
<img ngSrc="preloaderror2/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror3/img.png" width="150" height="50" priority>
<img ngSrc="preloaderro4/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror5/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror6/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror7/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror8/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror9/img.png" width="150" height="50" priority>
<img ngSrc="preloaderror10/img.png" width="150" height="50" priority>
`;

expect(() => {
const fixture = createTestComponent(template);
fixture.detectChanges();
}).toThrowError(
'NG02961: The `NgOptimizedImage` directive has detected that more than 5 images were marked as priority. This might negatively affect an overall performance of the page. To fix this, remove the "priority" attribute from images with less priority.',
const consoleWarnSpy = spyOn(console, 'warn');
const fixture = createTestComponent(template);
fixture.detectChanges();
expect(consoleWarnSpy.calls.count()).toBe(1);
expect(consoleWarnSpy.calls.argsFor(0)[0]).toMatch(
/NG02961: The `NgOptimizedImage` directive has detected that more than 5 images were marked as priority/,
);
});
});
Expand Down
0