From ae80b50422c2c9c32697c529c34b3c1d46965ee1 Mon Sep 17 00:00:00 2001 From: Yoav Weiss Date: Fri, 29 Oct 2021 14:03:56 -0700 Subject: [PATCH] Reland #2 "[LCP] Add animated image support" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a manual reland of https://chromium-review.googlesource.com/c/chromium/src/+/3247449 The difference from the previous reland is that the browser tests now include 2 separate timeouts and a double rAF, to ensure that the presentation timestamp taken is far enough from both the time the first frame is sent as well as from the time the second frame is sent. More importantly, the test now actually is looking at the UKM metric, rather than at the histogram. Original change's description: > [LCP] Add animated image support > > This CL adds support for better handling of animated images in LCP: > * A new attribute is exposing the first animated frame's paint time > (behind a flag). > * `startTime` is not changed. > * The PageLoadMetrics reported for LCP are set to that first frame paint > time for animated images (behind another flag). > * Entries are not emitted until the image is loaded. > > Relevant spec issue: > https://github.com/WICG/largest-contentful-paint/issues/83 Bug: 1260953 Change-Id: I34070bd90a74ed44281da63b547f13d9669f389b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3250690 Reviewed-by: Nicolás Peña Moreno Commit-Queue: Yoav Weiss Cr-Commit-Position: refs/heads/main@{#936516} --- images/anim-tao.png | Bin 0 -> 460 bytes images/anim-tao.png.headers | 2 ++ images/webp-animated.webp | Bin 0 -> 340 bytes .../observe-animated-image-gif.tentative.html | 27 +++++++++++++++ ...observe-animated-image-webp.tentative.html | 27 +++++++++++++++ .../observe-animated-image.tentative.html | 29 ++++++++++++++++ ...cross-origin-animated-image.tentative.html | 30 ++++++++++++++++ ...s-origin-tao-animated-image.tentative.html | 30 ++++++++++++++++ .../observe-non-animated-image.tentative.html | 27 +++++++++++++++ .../largest-contentful-paint-helpers.js | 32 ++++++++++++++++++ 10 files changed, 204 insertions(+) create mode 100644 images/anim-tao.png create mode 100644 images/anim-tao.png.headers create mode 100644 images/webp-animated.webp create mode 100644 largest-contentful-paint/animated/observe-animated-image-gif.tentative.html create mode 100644 largest-contentful-paint/animated/observe-animated-image-webp.tentative.html create mode 100644 largest-contentful-paint/animated/observe-animated-image.tentative.html create mode 100644 largest-contentful-paint/animated/observe-cross-origin-animated-image.tentative.html create mode 100644 largest-contentful-paint/animated/observe-cross-origin-tao-animated-image.tentative.html create mode 100644 largest-contentful-paint/animated/observe-non-animated-image.tentative.html diff --git a/images/anim-tao.png b/images/anim-tao.png new file mode 100644 index 0000000000000000000000000000000000000000..925e2efc9a97ade490f04d57271adc10b2fe69b6 GIT binary patch literal 460 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!3HE(nbz$CQXGlNAwEEw35Xd!_f9SVQc`IU zF^~{g1Bd|zjLa_>8Ci1NIDx$Bo-U3d6?5L6GvoytbHL!w?6zvIV;iqHq?@gO(Ktbl zoS|)rq)@U)kD_7Q5eZr|_$v>-*5=KZ^ai?#!PC{xWt~$( F698Hck68c! literal 0 HcmV?d00001 diff --git a/images/anim-tao.png.headers b/images/anim-tao.png.headers new file mode 100644 index 00000000000000..0230e176e44567 --- /dev/null +++ b/images/anim-tao.png.headers @@ -0,0 +1,2 @@ +Timing-Allow-Origin: * + diff --git a/images/webp-animated.webp b/images/webp-animated.webp new file mode 100644 index 0000000000000000000000000000000000000000..35a8dfcf34d58060ec70f0a2a04e0d58e357e084 GIT binary patch literal 340 zcmWIYbaV4zWMBw)bqWXzu!!JdU|B|P>F);l9590Z{MS*!B0;1vt zGXn!qpN|tzM4yX+ok3hd%;(wvmN~~P`X2vb?_+b_xHcr*I-p6!<-_fEjddq~hN*SD z*x#_=1f%tZIXZErQ(4dTt19a~HWL-+;f2`%bPy{81JGsx28J&{4%`Md1{Rq&&Br)8)v=KKh9&++1c^WpP^yW)$4OZRe!M0 zE0}Gar~tAd2Iy9xp+E$*fuDf^<_8y$AJ`5sgKbEX!)8O4^vRv~{y8UIh + + + + Largest Contentful Paint: observe image. + + + + + + + + diff --git a/largest-contentful-paint/animated/observe-animated-image-webp.tentative.html b/largest-contentful-paint/animated/observe-animated-image-webp.tentative.html new file mode 100644 index 00000000000000..de59d5c5f78c68 --- /dev/null +++ b/largest-contentful-paint/animated/observe-animated-image-webp.tentative.html @@ -0,0 +1,27 @@ + + + + + Largest Contentful Paint: observe image. + + + + + + + + diff --git a/largest-contentful-paint/animated/observe-animated-image.tentative.html b/largest-contentful-paint/animated/observe-animated-image.tentative.html new file mode 100644 index 00000000000000..cf7d262b0f842a --- /dev/null +++ b/largest-contentful-paint/animated/observe-animated-image.tentative.html @@ -0,0 +1,29 @@ + + + + + Largest Contentful Paint: observe image. + + + + + + + + diff --git a/largest-contentful-paint/animated/observe-cross-origin-animated-image.tentative.html b/largest-contentful-paint/animated/observe-cross-origin-animated-image.tentative.html new file mode 100644 index 00000000000000..993883c607b8f7 --- /dev/null +++ b/largest-contentful-paint/animated/observe-cross-origin-animated-image.tentative.html @@ -0,0 +1,30 @@ + + + + + Largest Contentful Paint: observe image. + + + + + + + + + diff --git a/largest-contentful-paint/animated/observe-cross-origin-tao-animated-image.tentative.html b/largest-contentful-paint/animated/observe-cross-origin-tao-animated-image.tentative.html new file mode 100644 index 00000000000000..137dde66383f77 --- /dev/null +++ b/largest-contentful-paint/animated/observe-cross-origin-tao-animated-image.tentative.html @@ -0,0 +1,30 @@ + + + + + Largest Contentful Paint: observe image. + + + + + + + + + diff --git a/largest-contentful-paint/animated/observe-non-animated-image.tentative.html b/largest-contentful-paint/animated/observe-non-animated-image.tentative.html new file mode 100644 index 00000000000000..6bbc0958b1deb2 --- /dev/null +++ b/largest-contentful-paint/animated/observe-non-animated-image.tentative.html @@ -0,0 +1,27 @@ + + + + + Largest Contentful Paint: observe image. + + + + + + + + diff --git a/largest-contentful-paint/resources/largest-contentful-paint-helpers.js b/largest-contentful-paint/resources/largest-contentful-paint-helpers.js index e12ece0a7561cb..5012faf3b1be33 100644 --- a/largest-contentful-paint/resources/largest-contentful-paint-helpers.js +++ b/largest-contentful-paint/resources/largest-contentful-paint-helpers.js @@ -1,3 +1,6 @@ +const image_delay = 1000; +const delay_pipe_value = image_delay / 1000; + // Receives an image LargestContentfulPaint |entry| and checks |entry|'s attribute values. // The |timeLowerBound| parameter is a lower bound on the loadTime value of the entry. // The |options| parameter may contain some string values specifying the following: @@ -33,4 +36,33 @@ function checkImage(entry, expectedUrl, expectedID, expectedSize, timeLowerBound } else { assert_equals(entry.size, expectedSize); } + if (options.includes('animated')) { + assert_greater_than(entry.loadTime, entry.firstAnimatedFrameTime, + 'firstAnimatedFrameTime should be smaller than loadTime'); + assert_greater_than(entry.renderTime, entry.firstAnimatedFrameTime, + 'firstAnimatedFrameTime should be smaller than renderTime'); + assert_less_than(entry.firstAnimatedFrameTime, image_delay, + 'firstAnimatedFrameTime should be smaller than the delay applied to the second frame'); + assert_greater_than(entry.firstAnimatedFrameTime, 0, + 'firstAnimatedFrameTime should be larger than 0'); + } + if (options.includes('animated-zero')) { + assert_equals(entry.firstAnimatedFrameTime, 0, 'firstAnimatedFrameTime should be 0'); + } } + +const load_and_observe = url => { + return new Promise(resolve => { + (new PerformanceObserver(entryList => { + for (let entry of entryList.getEntries()) { + if (entry.url == url) { + resolve(entryList.getEntries()[0]); + } + } + })).observe({type: 'largest-contentful-paint', buffered: true}); + const img = new Image(); + img.id = 'image_id'; + img.src = url; + document.body.appendChild(img); + }); +};