I have a strategy in mind for lazy loading images on a CMS (Sitecore) website, and I'm wondering if I will run into problems with it, since I am not finding examples of it being done.
The point is to improve performance, but reduce the side effect where users can get annoyed by images that are incomplete as the page is scrolled.
The strategy is using loading="lazy" on all images on the page, or only images below the fold, and upon page load, dynamically swap lazy to auto on all of these elements, from which point the browser will decide when to load the images by its own prioritization scheme.
The point is to prioritize images above the fold, but once the prioritized images and everything else are loaded, then tell the browser to load images by its own default loading behavior, so the user will be less likely to encounter incomplete images.
Are there problems I may run into doing this?
I can't imagine I am the first person to try this, but I am not finding examples in my search. Is this strategy established and documented anywhere?
The strategy is using loading="lazy" on all images below the fold, and upon page load, dynamically swap lazy to auto on every image element, from which point the browser will decide when to load the images by it's own prioritization scheme.
You don't need that to do. The browser know better when he should load the image. Just stay with lazy.
Are there problems I may run into doing this?
Yes! When you don't define a width & height for the image. There are some webpages which use achnor navigation. When the browser don't know how much space the image will take, then can happend that you will get some incorrect position when navigating.
Also there are some sideeffects that will load the image later then expected. Inside a slider as an example. But the benefit to not load the image is much more enjoyable then not to lazy loading the image.
Read more about the specific use-cases in this wonderful blog article:
https://web.dev/browser-level-image-lazy-loading/
Related
I am looking at disadvantages of lazy-loading images, and I must be hyper-thorough because we are considering implementing loading="lazy" on many/most images in the site. The reason for that is that I believe I have a strategy that should work.
We are using the browser-native loading="lazy" attribute, since we dropped support for IE recently. Wow, I know.
We are setting all images above the fold to eager, and all images below to lazy, across the entire site.
Then we are listening for the page load event and running a script that converts every image with loading="lazy" to loading="eager" (or auto). So images below the fold will get loaded too, probably in most cases by the time the user scrolls (at least using modern internet connection speeds). The page load event fires after all eager-loaded images have completed, but may/should fire before lazy-loaded images have started, so that is our opportunity to trigger loading below the fold.
One known disadvantage is that lazy-loaded images can cause a layout shift as the user scrolls, since the browser doesn't know the dimensions until the image starts loading. Another disadvantage is that users may be annoyed by images that are not loaded by the time they scroll to the image. This solution addresses both of those problems by converting remaining lazy-loading images to eager as soon as the prioritized images are loaded, to reduce the chance of the user encountering these issues.
There is also the possibility that there may be specific cases where pieces of JavaScript are waiting for an image to load in order to do something with it, and that can sometimes block rendering. Let's treat that as a side issue. I think it's unlikely we'll encounter that in this site, and we'll fix it where it occurs.
A side note, I have also devised a script that observes elements being populated or manipulated on the DOM by external scripts, and converts any newly-added img elements to loading="lazy" (if it occurs before page load), so I am able to guarantee lazy loading on all img elements on the page, and it DOES yield Lighthouse load performance gains of several points.
I am so far not finding many serious and/or likely problems from lazy-loading every or most images on a page, given that it is handled with the strategies that I have devised.
My question is what am I missing. Could this strategy have gaps?
What other considerations do I need to think about? Because I don't want my decisions to cause problems on the site I am working on.
When internet connection is very quick, things are also loading quickly and the user might not even see the status before the images are loaded. However, things are not always so rosy, there might be too many people using the internet and occupying all the bandwidth they can with watching videos, listening to music, chatting with friends.
Your problems start arising when
the users are using too many devices
there is an internet outage during the load of your page
an image is unavailable or slow to load (a very slow third-party UI, perhaps)
Usually, if your design works well and handles these cases in a user-friendly way, then users will notice there was a wait/outage, of course, but will probably not link that to your site. Yet, if your design looks ugly during these phases, then the users will remember that there was an outage/slowness of internet and how ugly your page was.
Since this is something every developer wants to avoid, it makes sense to treat the internet as something that usually works, but always has the potentiality of being down or slow.
As a result, if you know what pictures will appear in the viewport and what pictures will be shown only when the user scrolls, then you can eager-load the pictures the user will see first. Of course, it is not always easy to know what pictures will appear in the viewport, especially if your page looks very differently on different devices. Yet, you could divide your content into two main sections:
the section that is shown even during page load
the section which will be shown only when the page load is complete
you can totally hide the second section and then there would be no visual problems.
Another way to handle this is to know in advance (on server-side) the dimensions of the pictures, hide the picture tags while they are loading and show some placeholder (some "loading" gif, for example) in the place where the pictures will appear and have a load event for all images that are hidden this way which would make sure that the "loading" placeholder will disappear and the actual image appear when the image is loaded. This would ensure that your layout's visual structure is the exact same while it does not have all the images to show yet as when all the images were fully and successfully loaded.
What you may not know if you've never used browser-native lazy loading is that it does not necessarily improve initial load size/time on shorter pages, because it still initiates loading anything closer to the viewport than 3000 pixels, even before the window load event fires. This is what is considered too eager.
Info about this issue: https://calendar.perfplanet.com/2019/native-image-lazy-loading-in-chrome-is-way-too-eager
That can make it useless against Google's Lighthouse performance metrics for shorter pages.
So we are implementing the old-fashioned non-native lazy loading where we have complete control via JavaScript. Our images are served like:
<img data-src="some-image.src" />
<noscript>
<img src="some-image.src" />
</noscript>
...And using JavaScript strategy similar to what was described in the original question here, in addition to the common technique for swapping Image.dataset.src into the Image.src property, or we many use lazySizes.
But I don't get a few things about the functionality of browser-native lazy loading. Particularly, why the browser wouldn't prioritize lazy images above the fold over lazy images below the fold, and not load any lazy image below the fold or fire the load event until everything is loaded above the fold.
And I don't get why lazy loading can't be set with CSS. It would be great if we could apply the loading attribute to sections of a page by CSS selectors alone. Instead we're forced to handle it either with JavaScript or on the server. With CSS it would be as simple as loading: lazy;.
I'm going to look into if these ideas are proposed anywhere. I may also post the code we use in the end.
I currently have a page with about 20 or images with source data pulled from a database.
I display them at width of 100px and I have a hover function that appends an element with the full size image with a width of 250px.
I decided to use the full size version for the original image and just scale it down to 100px instead of using a thumbnail version. My thinking on this was that on this page it is very likely that the user will hover over most of the images so the page would end up having to load the full size version for most of the images anyway so why make them download the thumbnail AND full size version for each element. Also scaling from 250px to 100px didn't seem to display much if any distortion in the smaller element.
Now I am running my page through Google page speed analyzer and it really does not like me using larger than necessary images for the smaller elements. Of course it is ignoring the fact that those larger images are being used for the dynamically created popups.
In order to make my page play nice with Google's page speed tester I am giving in and using thumbnails for the smaller elements but I also want to prefetch the larger image to avoid an annoying delay when the user hovers over the element. This means I am essentially loading 2 versions of the same image just to make Google speed test not yell at me.
This seems ridiculous to me so I wanted to ask if this is really the best way to do this or is there another way to make my page play nice with Google speed test.
Thanks,
Adam
If you know what you're doing, there's no need to be a slave to the PageSpeed score.
Loading two copies of the images could make actual page speed slower. However, it depends on what you are trying to optimize for. Loading thumbnails first and then large versions could be better if you want time to full render to be fast (so the users can see the page) and then load the big images in the background to add interactivity later.
Or is it better to have fast time to interactivity, and time to full render doesn't matter that much. Then maybe having one copy of each image is better.
I know of 3 main ways to shrink images:
Using the img tag WIDTH HEIGHT
Putting all the images in a DIV and then scaling the whole div.
User zooming with ctrl + mouse wheel.
I have some pages with huge amounts of images. What I have noticed is that there is massive speed difference between the methods. Method 1 kills firefox very quickly. Method 3 seems to be the fastest on all broswers I have tried.
Does anyone know of any other methods? And is there a way through javascript/css to specify what the browser zoom level should be so I can at least use the fastest way?
The easist on the client would be scaling the images on the server and sending them to the browser, however it would take some serious CPU power on the server end (unless you cache them, and serve them up afterwards). You can achieve this with PHP quite easily. Depending on your purposes, you could simply write a script that takes all the images in a directory, resizes them and saves them to "thumbs/".
If you don't want to use anything on the server, I would either go with option 1 or question why there are so many images on one page to bein with. Try adding some pagination or something. If the browser slows down while using such a basic method of resizing images, there might be some refactoring in order.
If you're going to be resizing images why not have the images themselves be smaller. That will load the fastest out of any method you try. You can use PHP to create thumbnail sized images, and a link to the full sized image if they need to see it. Remember, even if you resize an image with the height/width the browser still loads the full image.
See http://articles.sitepoint.com/article/image-resizing-php for a tutorial on image resizing in php.
On a website I'm creating, I have about 100 various thumbnails (64x64) that get displayed at different times. On some pages, only 5-15 thumbnails may be displayed. On others, all 100 are loaded.
I'm considering using a technique like CSS sprites to display the images. That is, rather than have image tags for each thumb, do something like:
<span class=thumb1"></span>
And then use CSS to take a slice of one single image with all the thumbs stitched together. That is, one image with all 100 thumbs (in this scenario, a 640x640 image).
My questions:
Is this a good idea?
If yes,
should I do it on all pages the
images occur, or only on the pages
with all the images?
Is there
another technique other than sprites
that may be better than simply
including the images with img tags?
If you think that an ordinary user would visit at least two different pages with these thumbnails than my opinion is that using sprites would really be a good idea!
I would in fact make a single big image with all the thumbnails and then use it in all the pages!
Why?
Fewer http requests (from 100 to 1)! And this is one of the most important thing about web site optimizations (read here from Yahoo Performance Team speed optimization rules )
This way users will download the whole image only the first time and then they will get a super quick loading of that images in all the following pages
The most famous websites on the internet already do that! See sprites used in Yahoo, Amazon or Youtube pages.
You can add other UI or layout images to your sprite
Optimize the resulting PNG:
After you have generated your sprite, if a PNG, you can optimize the PNG even more using this tool: http://www.sitepoint.com/blogs/2009/09/18/squishing-the-last-drops-from-your-pngs/
When not to use sprites:
When part of the images in the sprite change frequently
In this specific case: when the majority of users would need less than the (about) 10% of the images
I'm not quite sure what you mean with "sprites", but this is what I think you mean: instead of 100 images seperately, you create 1 image, with a 10x10 raster. Each coordinate (x,y) contains one of the images you like to show.
Now, if you display an image, you use CSS to set background-location: i.e. x * -64px and y * -64px, perhaps using JavaScript to calculate the x and y for each image-span, or Server-Side scripting to print out a dynamic CSS.
Yes, this is a good idea: it reduces load time, since one only has to download one big image, instead of hundreds of smaller ones.
It depends. If you have caching-abilities for a page, then you can "stitch" all thumbnails into one image file. If you have a very dynamic webpage, then it's quite harsh to build this stitched image every time the thumbnales are updated.
Not sure, if this is what you ment with "sprites", then no, if you ment something else with "sprites", then yes: this answer is an example of one.
It is a good idea if
Speed matters
You don't care about accessibility (screen readers reading the ALT text of an image, etc, all that is gone when you use sprites)
You don't care that your thumbnails are not going to be printed by default in any browser
You can do it without it becoming a maintenance nightmare (which image was on position 461 again?)
As to your second question, it is probably advisable to put all sprites into one or very few container images to minimize loading times.
I have a large, hi-def JavaScript-intensive image banner for a site I'm designing. What is everyone's opinion of using iframes so that you incur the load time only once? Is there a CSS alternative to the iframe?
Feel free to preview the site.
It is very much a work in progress.
I should also have mentioned that I would like the banner rotation to keep moving. When the visitor clicks on a link, the banner rotation starts over. It would be nice if the "animation" kept rotating, regardless of the page the user visits.Blockquote
Well, in that case I would strongly recommend not doing that. The only real way of achieving that is to have the actual website content in the iframe, which means that you suddenly have lots of negative sides to the site: not being able to bookmark urls easily due to the address bar not changing; accessibility concerns; etc
I think you'll find that most people won't care that it reloads again. Once a visitor lands on your website, they'll marvel at the wonderful banner immediately, and then will continue to ignore it while they browse your site - until an image they haven't seen appears and distracts them away from your content.
Keep the rotation random enough, and with enough images, and people will stop to look at it from whatever page they're on.
I find the main challenge with iFrame headers is resizing. Since the font in your header is of static size, I don't see a problem with using an iFrame. Although I'm not sure if it's really intensive enough to be worth it.
Well, the browser appears to cache all seven banner images upon the first load, and runs them out from the cache (for each subsequent page) thereafter. I don't think you have a problem :D
Try it out with Firebug's Net monitoring tool in Firefox.
This may work without CSS also, but if you use CSS to load the background and your server is configured correctly, the image should already only be downloaded once.
Usually the browser will request a resource by asking for it only if it has not been modified since the last time it was downloaded. In this case, the only things sent back and forth are the HTTP headers, no content.
If you want to ensure the image is only downloaded once, add an .htacces or an apache2.conf rule to make the image expire a few days into the future so that users will only request it again if their cache is cleared or the content expiration date passes. An .htaccess file is probably too excessive to use in your case, though results may vary.
You could have it load the main page once, then asynchronously load the other elements when needed (ajax). If you did that, an iFrame would not be necessary. Here is an example of loading only the new material.
While using IFrames as a sort of master page/template for your pages might be a good thing, IFrames have a known negative impact to searchability/SEO.
It might also be unnecessary in the first place because once your images are loaded the first time (and with the large high-def images you have on your site, that would be slow no matter what you do) the images are cached by browsers and will not be reloaded until the user clears their cache or does a Ctrl+F5.