- Issue created by @kubrick
- Status changed to Needs review
about 1 year ago 2:43am 1 December 2023 - 🇳🇱Netherlands seanB Netherlands
First of all, thanks for bringing this to my attention. We are indeed loading all lazy loaded images directly. Attached is a new version of the patch addressing some issues I had while testing it:
- Browser lazy loading fires before our JS. This causes the default source to be loaded by the browser even though we don't always need it.
- I move the
intersectionObserver
to attach to the image only once so we can do all our calculations (not just the preloading). - I've added an offset to the
intersectionObserver
so we start loading the images slightly before it is actually visible. I've added a check toupdateImage()
to see if an image is visible so we can keep calling this method as often as we like. It will only do things when needed. - I also added a check to see if an image is already being loaded so the different observer won't update the image simultaneously.
- I have removed the preloading entirely, since it doesn't really seem to make a difference and it caused the image to be loaded twice when browser caching is disabled.
The results are amazing. Even a relatively simple page with only a dozen of images went from
418 kB / 925 kB transferred | 403 kB / 1.1 MB resources
to185 kB / 654 kB transferred | 196 kB / 874 kB resources
on first page load.Please review the patch before I commit it. After this one is in I will create a new release.
- 🇧🇪Belgium kubrick
Thanks!
I can't seem to apply the patch. Is this for 1.3.2?
Maybe we don't even need the intersection observer if you got rid of the preloading.
Wouldn't the browser's native support for the lazy attribute take care of everything?
Or do they load immediately if you override the src on the image? - 🇳🇱Netherlands seanB Netherlands
The patch should apply to the latest dev version (you can load that via composer using
dev-1.3.x#ced7e669a0e672d5ceb83dc487c13b00952fd7fc
).We definitely need an intersection observer, since images are immediately loaded when you change the src. That is pretty much the bug we are solving here.
- 🇧🇪Belgium kubrick
During testing I had some images not load because the src did not get set.
I've made some changes to the observers:
- Only add the resize observer once the lazy image hits the intersection observer.
- Remove the check in updateImage() that checks if the image is in the viewport, since this function can't run anymore before the IntersectionObserver fires.
- Remove the intersection observer after the first intersection. (not related to the bug but might be better to remove it once it's not needed anymore)
Here's some videos with the network tab open:
Some images not loading: https://www.dropbox.com/scl/fi/6jrb522ue812ofawvcjbt/1.mov?rlkey=puc0r3v...
New patch: https://www.dropbox.com/scl/fi/xjzx3sq7whqdstglwebvu/2.mov?rlkey=jx1uz80...The smaller images wouldn't really need easy_responsive_images but works as a demo.
- 🇳🇱Netherlands seanB Netherlands
Coul you create an interdiff for the patch?
- 🇧🇪Belgium kubrick
Sure!
I also rerolled the patch since my Prettier changed the formatting on the previous patch.
New at contributing so bear with me 🙈
- Status changed to Fixed
about 1 year ago 11:13pm 19 December 2023 - 🇳🇱Netherlands seanB Netherlands
-
+++ b/js/resizer.js @@ -172,7 +160,10 @@ + intersectionObserver.unobserve(entry.target);
This makes sense, it optimizes the executed JavaScript. Nice!
-
+++ b/js/resizer.js @@ -172,7 +160,10 @@ + resizeObserver.observe(entry.target.parentNode);
This is also pretty clever, it allows us to remove the check in updateImage and also optimizes the JavaScript. thanks!
-
+++ b/js/resizer.js @@ -187,14 +178,16 @@ + intersectionObserver.observe(image);
This seems to be missing the part where we remove the "src" for lazy loaded images. I added that back, since the browser seems to load the original sources before we update the src to the prefered image style. Since the original sources are pretty much immediately replaced, this seems like a nice extra optimization. It needs some extra manual testing though.
I've committed the latest patch with some minor changes. Please help me test the latest commit (
dev-1.3.x#94469349953435ec2a948dcffd4507fd0e12f267
). If you can confirm everything works I will roll a new release. -
- 🇧🇪Belgium kubrick
Thanks! Looking good!
Regarding 3.
I noticed the same issue again with certain smaller images not loading because the src attribute was missing.
This happens if the original image is wider than the width of its parent, so the src does not get re-added in updateImage().I've added a patch that always runs the updateImage logic if the src attribute is missing.
Besides that is also noticed original images sometimes loading even with the removeAttribute('src') line. When they're inside the viewport when the page loads the images are loaded before the JavaScript can remove the src. I don't think removing the src in the Twig templates would be a good fix so probably best to leave it.
- 1448b3f7 committed on 1.3.x
Issue #3400525 by kubrick, seanB: Improve lazy/eager loading
- 1448b3f7 committed on 1.3.x
- 🇳🇱Netherlands seanB Netherlands
Thanks! Nice find! Committed. I'll create a new release now as well.
- Status changed to Fixed
12 months ago 12:04pm 6 January 2024 Automatically closed - issue fixed for 2 weeks with no activity.