@@ -169,6 +169,9 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
169169 private imgElement : HTMLImageElement = inject ( ElementRef ) . nativeElement ;
170170 private injector = inject ( Injector ) ;
171171
172+ // a LCP image observer - should be injected only in the dev mode
173+ private lcpObserver = ngDevMode ? this . injector . get ( LCPImageObserver ) : null ;
174+
172175 /**
173176 * Calculate the rewritten `src` once and store it.
174177 * This is needed to avoid repetitive calculations and make sure the directive cleanup in the
@@ -277,10 +280,12 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
277280 // Monitor whether an image is an LCP element only in case
278281 // the `priority` attribute is missing. Otherwise, an image
279282 // has the necessary settings and no extra checks are required.
280- invokeLCPImageObserverCallback (
281- this . injector ,
282- ( observer : LCPImageObserver ) =>
283- observer . registerImage ( this . getRewrittenSrc ( ) , this . rawSrc ) ) ;
283+ if ( this . lcpObserver !== null ) {
284+ const ngZone = this . injector . get ( NgZone ) ;
285+ ngZone . runOutsideAngular ( ( ) => {
286+ this . lcpObserver ! . registerImage ( this . getRewrittenSrc ( ) , this . rawSrc ) ;
287+ } ) ;
288+ }
284289 }
285290 }
286291 this . setHostAttributes ( ) ;
@@ -344,10 +349,8 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
344349
345350 ngOnDestroy ( ) {
346351 if ( ngDevMode ) {
347- if ( ! this . priority && this . _renderedSrc !== null ) {
348- invokeLCPImageObserverCallback (
349- this . injector ,
350- ( observer : LCPImageObserver ) => observer . unregisterImage ( this . _renderedSrc ! ) ) ;
352+ if ( ! this . priority && this . _renderedSrc !== null && this . lcpObserver !== null ) {
353+ this . lcpObserver . unregisterImage ( this . _renderedSrc ) ;
351354 }
352355 }
353356 }
@@ -373,24 +376,6 @@ function inputToBoolean(value: unknown): boolean {
373376 return value != null && `${ value } ` !== 'false' ;
374377}
375378
376- /**
377- * Invokes a function, passing an instance of the `LCPImageObserver` as an argument.
378- *
379- * Notes:
380- * - the `LCPImageObserver` is a tree-shakable provider, provided in 'root',
381- * thus it's a singleton within this application
382- * - the process of `LCPImageObserver` creation and an actual operation are invoked outside of the
383- * NgZone to make sure none of the calls inside the `LCPImageObserver` class trigger unnecessary
384- * change detection
385- */
386- function invokeLCPImageObserverCallback (
387- injector : Injector , operation : ( observer : LCPImageObserver ) => void ) : void {
388- const ngZone = injector . get ( NgZone ) ;
389- return ngZone . runOutsideAngular ( ( ) => {
390- const observer = injector . get ( LCPImageObserver ) ;
391- operation ( observer ) ;
392- } ) ;
393- }
394379
395380/***** Assert functions *****/
396381
0 commit comments