MCPcopy
hub / github.com/angular/angular / ImagePerformanceWarning

Class ImagePerformanceWarning

packages/core/src/image_performance_warning.ts:26–205  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

24
25@Service()
26export class ImagePerformanceWarning implements OnDestroy {
27 // Map of full image URLs -> original `ngSrc` values.
28 private window: Window | null = null;
29 private observer: PerformanceObserver | null = null;
30 private options: ImageConfig = inject(IMAGE_CONFIG);
31 private lcpImageUrl?: string;
32
33 public start() {
34 if (
35 (typeof ngServerMode !== 'undefined' && ngServerMode) ||
36 typeof PerformanceObserver === 'undefined' ||
37 (this.options?.disableImageSizeWarning && this.options?.disableImageLazyLoadWarning)
38 ) {
39 return;
40 }
41 this.observer = this.initPerformanceObserver();
42 const doc = getDocument();
43 const win = doc.defaultView;
44 if (win) {
45 this.window = win;
46 // Wait to avoid race conditions where LCP image triggers
47 // load event before it's recorded by the performance observer
48 const waitToScan = () => {
49 setTimeout(this.scanImages.bind(this), SCAN_DELAY);
50 };
51 const setup = () => {
52 // Consider the case when the application is created and destroyed multiple times.
53 // Typically, applications are created instantly once the page is loaded, and the
54 // `window.load` listener is always triggered. However, the `window.load` event will never
55 // be fired if the page is loaded, and the application is created later. Checking for
56 // `readyState` is the easiest way to determine whether the page has been loaded or not.
57 if (doc.readyState === 'complete') {
58 waitToScan();
59 } else {
60 this.window?.addEventListener('load', waitToScan, {once: true});
61 }
62 };
63 // Angular doesn't have to run change detection whenever any asynchronous tasks are invoked in
64 // the scope of this functionality.
65 if (typeof Zone !== 'undefined') {
66 Zone.root.run(() => setup());
67 } else {
68 setup();
69 }
70 }
71 }
72
73 ngOnDestroy() {
74 this.observer?.disconnect();
75 }
76
77 private initPerformanceObserver(): PerformanceObserver | null {
78 if (typeof PerformanceObserver === 'undefined') {
79 return null;
80 }
81 const observer = new PerformanceObserver((entryList) => {
82 const entries = entryList.getEntries();
83 if (entries.length === 0) return;

Callers

nothing calls this directly

Calls 1

injectFunction · 0.90

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…