Closed berwyn closed 1 year ago
Deployed Styleguide and Lab.Notes
File | Before | After |
---|---|---|
components/Image/script.js |
6.7 kB |
0.6%β6.8 kB |
Total (Includes all files) | 1.8 MB |
-0.02%β1.8 MB |
Tarball size | 343.5 kB |
-0.09%β343.2 kB |
π€ This report was automatically generated by pkg-size-action
:tada: This PR is included in version 16.2.0 :tada:
The release is available on:
Your semantic-release bot :package::rocket:
Describe the problem this PR addresses
With the latest release version, image loading has a few snags. This is especially apparent in Safari, where the user agent frequently loads two or more of the images. In my example case, I have an
MImage
withsrc
,srcset
, andsizes
all set, which causes Safari to load two images from thesrcset
in two resolutions. Additionally, the internal cache insideMImage
creates an<image>
tag that loads itssrc
, meaning that every image on the page is loading three separate copies of the same image at different resolutions. This has a huge impact in page load performance, as the number of in-flight requests as well as the amount of data loaded can become quite significant on image-heavy pages.You can observe this in Safari's network tab using the "group by resource" option. Here, you can see two of the variants are loaded as a result of the
<img>
itself, while a 3rd is loaded fromMImage
's hidden<image>
tag.Describe the changes in this PR
This PR does a couple things to
MImage
that change implementation details without touching the public APIloaded
flag is now reactive to theload
event fired on every image as its contents are loaded.<image>
tag used to preload images has been removed. Instead, lazy loaded images will simply lack theirsrc
+srcset
attributes. As theIntersectionObserver
indicates that the image enters the viewport, those attributes will be filled in, allowing the user agent to fetch the image.The end result is that user agents like Safari will now properly load exactly one candidate from the
src
+srcset
tags.Here, you can see Safari's network tab with the same settings shows exactly one version of the image loaded:
Other information
An interesting aside, but the lazyloading process used the
Image
constructor, which maps to the long-deprecated<image>
tag. Normally, if this element was attached to the DOM, the user agent would convert it to an<img>
, but in this case because it remains outside the DOM tree it uses the legacy<image>
behaviour and would not parsesrcset
/sizes
values!