@@ -113,6 +113,13 @@ final class OptimizeHeroImages implements Transformer
113113 */
114114 const NOSCRIPT_IMG_XPATH_QUERY = './noscript/img ' ;
115115
116+ /**
117+ * XPath query to relatively fetch all noscript > img[fetchpriority="high"] elements.
118+ *
119+ * @var string
120+ */
121+ const NOSCRIPT_IMG_FETCHPRIORITY_HIGH_XPATH_QUERY = './noscript/img[@fetchpriority="high"] ' ;
122+
116123 /**
117124 * Regular expression pattern to extract the URL from a CSS background-image property.
118125 *
@@ -215,6 +222,17 @@ private function findHeroImages(Document $document, $maxHeroImageCount)
215222 $ seenParagraphCount ++;
216223 }
217224
225+ if ($ node ->tagName === Extension::IMG && ! $ node ->hasAttribute (Attribute::DATA_HERO )) {
226+ $ highFetchpriorityImage = $ document ->xpath ->query (
227+ self ::NOSCRIPT_IMG_FETCHPRIORITY_HIGH_XPATH_QUERY ,
228+ $ node
229+ )->item (0 );
230+
231+ if ($ highFetchpriorityImage instanceof Element) {
232+ $ node ->appendChild ($ document ->createAttribute (Attribute::DATA_HERO ));
233+ }
234+ }
235+
218236 $ heroImage = $ this ->detectImageWithAttribute ($ node , Attribute::DATA_HERO );
219237 if ($ heroImage ) {
220238 $ heroImages [] = $ heroImage ;
@@ -566,6 +584,14 @@ private function generateImg(HeroImage $heroImage, Document $document)
566584 $ imgElement ->setAttribute (Attribute::LOADING , $ noscript_img ->getAttribute (Attribute::LOADING ));
567585 }
568586
587+ // Preserve the original fetchpriority attribute from the noscript fallback img.
588+ if ($ noscript_img ->hasAttribute (Attribute::FETCHPRIORITY )) {
589+ $ imgElement ->setAttribute (
590+ Attribute::FETCHPRIORITY ,
591+ $ noscript_img ->getAttribute (Attribute::FETCHPRIORITY )
592+ );
593+ }
594+
569595 // Remove any noscript>img when an amp-img is pre-rendered.
570596 $ noscript_img ->parentNode ->parentNode ->removeChild ($ noscript_img ->parentNode );
571597 } elseif (! $ this ->isMarkedAsHeroImage ($ element )) {
0 commit comments