custom-metrics icon indicating copy to clipboard operation
custom-metrics copied to clipboard

[Performance 2024] Added bytesPerPixel (BPP) property to Images custom metric

Open kevinfarrugia opened this issue 1 year ago • 6 comments

Add bytesPerPixel custom metric. This is calculated as (filesize in bits) / (image display height * image display width)

Note that it would return 0 for cross-origin images that do not include the timing-allow-origin header.


Test websites:

  • https://web.dev
  • https://almanac.httparchive.org/

kevinfarrugia avatar May 23 '24 10:05 kevinfarrugia

Custom metrics for https://almanac.httparchive.org/en/2022/

WPT test run results: http://webpagetest.httparchive.org/results.php?test=240523_PB_5

Custom metrics for https://web.dev

WPT test run results: http://webpagetest.httparchive.org/results.php?test=240523_WF_6 Changed custom metrics values:

{
    "_Images": [
        {
            "url": "https://www.gstatic.com/devrel-devsite/prod/vdc54107fd8beee9a25bbc52caca7c5cd8d6bde91b94b693cf51910bd553c2293/web/images/lockup.svg",
            "width": 181,
            "height": 54,
            "naturalWidth": 300,
            "naturalHeight": 89,
            "loading": null,
            "decoding": null,
            "fetchpriority": null,
            "inViewport": true,
            "bytesPerPixel": 0
        },
        {
            "url": "https://www.gstatic.com/devrel-devsite/prod/vdc54107fd8beee9a25bbc52caca7c5cd8d6bde91b94b693cf51910bd553c2293/web/images/lockup.svg",
            "width": 300,
            "height": 89,
            "naturalWidth": 300,
            "naturalHeight": 89,
            "loading": null,
            "decoding": null,
            "fetchpriority": null,
            "inViewport": true,
            "bytesPerPixel": 0
        },
        {
            "url": "https://web.dev/static/images/home-blue_720.png",
            "width": 508,
            "height": 299,
            "naturalWidth": 707,
            "naturalHeight": 416,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": true,
            "bytesPerPixel": 1.4236957838464173
        },
        {
            "url": "https://web.dev/static/images/io/io-ondemand-web_720.jpg",
            "width": 540,
            "height": 304,
            "naturalWidth": 707,
            "naturalHeight": 398,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": 0.9831871345029239
        },
        {
            "url": "https://web.dev/static/images/inp-cwv_720.png",
            "width": 540,
            "height": 332,
            "naturalWidth": 707,
            "naturalHeight": 434,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": 2.3387327086122265
        },
        {
            "url": "https://web.dev/static/images/baseline_480.png",
            "width": 395,
            "height": 223,
            "naturalWidth": 464,
            "naturalHeight": 261,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": 2.050201509905205
        },
        {
            "url": "https://web.dev/static/images/new-to-the-web_480.jpg",
            "width": 395,
            "height": 223,
            "naturalWidth": 464,
            "naturalHeight": 261,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": 2.356723619231424
        },
        {
            "url": "https://web.dev/static/images/css-podcast_480.png",
            "width": 395,
            "height": 223,
            "naturalWidth": 464,
            "naturalHeight": 261,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": 9.727876482942612
        }
    ]
}
Custom metrics for https://almanac.httparchive.org/

WPT test run results: http://webpagetest.httparchive.org/results.php?test=240523_2D_7 Changed custom metrics values:

{
    "_Images": [
        {
            "url": "https://almanac.httparchive.org/static/images/home-hero.png",
            "width": 485,
            "height": 332,
            "naturalWidth": 820,
            "naturalHeight": 562,
            "loading": null,
            "decoding": null,
            "fetchpriority": "high",
            "inViewport": true,
            "bytesPerPixel": 1.8900509253508881
        },
        {
            "url": "https://almanac.httparchive.org/static/images/character-markup.png",
            "width": 109,
            "height": 179,
            "naturalWidth": 154,
            "naturalHeight": 252,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": 4.908410640151709
        },
        {
            "url": "https://almanac.httparchive.org/static/images/character-star.png",
            "width": 109,
            "height": 113,
            "naturalWidth": 245,
            "naturalHeight": 254,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": 9.317203864577413
        },
        {
            "url": "https://almanac.httparchive.org/static/images/character-hat.png",
            "width": 109,
            "height": 122,
            "naturalWidth": 186,
            "naturalHeight": 207,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": 5.995488043314785
        },
        {
            "url": "https://almanac.httparchive.org/static/images/methodology-characters.png",
            "width": 650,
            "height": 234,
            "naturalWidth": 0,
            "naturalHeight": 0,
            "loading": "lazy",
            "decoding": null,
            "fetchpriority": null,
            "inViewport": false,
            "bytesPerPixel": null
        }
    ]
}

github-actions[bot] avatar May 23 '24 10:05 github-actions[bot]

A few questions:

  1. Why encoded body size instead of decoded body size? If specifically interested in encoded I think we should include that in the name.
  2. Does this belong in performance or images custom metrics?
  3. I noticed this is already being calculated (with decoded body size) in responsive_images.js custom metric. Could that be used? Or extended if you really want encoded body size.

tunetheweb avatar May 23 '24 11:05 tunetheweb

  1. Fair point. It isn't clear on https://github.com/w3c/largest-contentful-paint/issues/86 whether it is calculated on encoded or decoded body size. Other tools (for example https://www.phpied.com/quick-bpp-image-entropy-check/) seem to use decodedBodySize so we followed suit.
  2. I'm not sure of the standard being followed TBH. Originally we were going to place it in its own file but thought in the Images.js mde the most sense. The performance.js file doesn't include all images, only LCP elements—TBF we are after BPP on LCP image.
  3. Will check. At a glance it seems to be correct and also checks wptRequest.response_headers for cross-origin resources.

kevinfarrugia avatar May 23 '24 11:05 kevinfarrugia

Oh I missed that this was being added to images.js, I presumed it was for performance.js. Oops. OK seems fine in images.js (unless easy to add to responsive_images.js). Ideally we'd merge that and responsive-images.js I guess, but that seems like a bigger change we'd want to do with the Media chapter.

tunetheweb avatar May 23 '24 11:05 tunetheweb

Fair point. It isn't clear on https://github.com/w3c/largest-contentful-paint/issues/86 whether it is calculated on encoded or decoded body size.

I would imagine it's decoded size.

Other tools (for example https://www.phpied.com/quick-bpp-image-entropy-check/) seem to use decodedBodySize so we followed suit.

But you didn't. You used encoded size?

tunetheweb avatar May 23 '24 11:05 tunetheweb

Other tools (for example https://www.phpied.com/quick-bpp-image-entropy-check/) seem to use decodedBodySize so we followed suit.

But you didn't. You used encoded size?

Sorry I mixed them up. The other tools use encodedBodySize but TBF I am not sure which is correct.

kevinfarrugia avatar May 23 '24 12:05 kevinfarrugia

Closing in favor of using existent responsive_images.js custom metric.

kevinfarrugia avatar May 24 '24 17:05 kevinfarrugia