Tricky Lazy Loading Question - html

Greetings Overflowers,
A result-set grid will be viewing snaps from HTML pages.
Snaps need to reserve original page layout including any tables, images...
Users will scroll through a snap to fully read a snapped page
Snaps can view varying-size windows anywhere in the HTML pages
Question: can lazy loading be implemented such that only viewed windows is loaded without losing the interactivity (e.g. hyperlinks) of snapped HTML pages ? If HTML pages cannot be tailored dynamically and lazy loaded this way, any interactive document format (e.g. PDF, Flash) is welcomed.
Update: Sorry for the confusion. Snaps are not images, they are random viewports anywhere from the HTML pages. In images it is simple, we can load only the portion we need to view. In HTML this is difficult, except when the portion is actually a whole viewable HTML tag element and it fits the needed portion. iframes would only facilitate the window to view the snaps onto, but I do not want to load the whole HTML pages because they are big, but only the needed snaps. The problem snaps can be somewhere in the middle of pages layout divisions where each division is very big. Therefore, fixing the layout size and lazy load their content later on alone would not help. I think layout transformations are necessary but very difficult. I wish I can take a picture of the full HTML pages and take whereever portion I need to view and this image portion keep interactive :)
Thanks !

You can use JavaScript with XMLHttpRequest (XHR) to fetch content asynchronously and place that text on the page (i.e. lazily loading content). I am not familiar with some of the terms that you are using (e.g. what a "snap" is), but if your layout specifies sizes (instead of relying on content, for example, to set the size of a table column), then this lazy loading can be done without re-rendering the layout.

As I interpret it - you have some fixed-size "viewport" div with scrollbars. You have Javascript that monitors the scrolling events of the viewport. You have to (somehow) have some rough idea of what content elements go where on the inner page. If a section is scrolled into view that has not been loaded, then send for it using AJAX. I think the trickiest part of this endeavour would be establishing the rough idea of what content elements go where without completely loading the content page, but perhaps you already have some assumptions you can make about the content.
Edit:
I do not want to load the whole HTML pages because they are big
This seems to indicate that you in fact do have some assumptions about the pages you're working with. How are the pages "big"? Do they have massive tables, massive images, a large number of images, flash content, javascript content...? You might have better success with loading all of the DOM that isn't of a certain tag type, and then selectively loading the rest.

Related

Swapping lazy-loaded images to `loading="auto"` upon page load complete

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/

Image lazy loading strategy; what problems may I encounter?

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.

How to reserve space for iframe content without playing it

I am creating a web page which is a showcase for various kinds of content. Some of the content comes with a HTML page which plays the content (Flash, WebGL) and I am trying to use iframes to load them on the web page. I could maybe add the content straight on my page since I have the actual content, but the editors generate readily usable HTML which works great. Therefore, I wouldn't want to start dissecting what are the important parts to add on my page to get all different types of content to play properly.
Still, all this works fine. The problem is, I don't want the content to play right away and I would like it to reserve the space it needs (i.e. the iframe should match the size of the content to be loaded). I know how to do each of these separately but not together. The idea is that there would be a button which plays the content and the content would start to play in its space without resizing the page.
I see two ways of achieve this, neither of which I know how to do.
Don't load the content before the play button is pressed but read the size of the content somehow.
Load the content and prevent it from activating/playing before the play button is pressed.
Closest to the desired effect I got by using visibility: hidden styling which did reserve the space and on top of that hide the iframe content (doesn't matter to me if its hidden or not) but the content started playing. Another way might be to read width and height values from the HTML file, but this information might be in a separate CSS file or there might several width and height values in the files. It would be a mess if I need to start creating exceptions for all sorts of content I load into iframes.
Is there an easy way to achieve either of these approaches? Or is there an alternative approach?
You could load up the page with the iframes in the correct positions you need them, and set a blank page in the src attribute.
Then when they scroll into view, load the correct src attribute.
This can be achieved by using some javascript like this (using jQuery for ease, but not needed).
This is a rough example, and would need some refactoring:
https://jsfiddle.net/pLwL0843/2/

On a high-level, how would I build a carousel for images?

Can you explain to me, at a very high level, what I would need to build an image carousel for the web, please. You can use data structures and general computer science terminology - but nothing language specific.
E.g:
Store all the images in an array or linked list
When the carousel is loaded, resize the displayed images as X% window size
When the next button is pressed, imageA moves to a hidden html element.
Et cetera.
I hope that makes sense.
Thanks.
You don't want anything language specific but you want to know about carousels on the web and you've tagged this with 'html' and 'css' so I'm going to assume that I can talk about HTML and CSS but I'll try to keep it high level.
If we ignore Flash, then you're left with HTML + CSS + Javascript. The common way to do this is to arrange the images or their thumbnails (don't resize via HTML - its doesn't look good and can increase your page load time) in HTML elements that are themselves contained in one or more layers of wrapping elements. So the whole set of images strung together might be wider than the viewing window. CSS is used to manage their exact layout and to keep them from overflowing the viewing window. When I say window, I just mean the portion of the page in which you want the carousel to appear. Then Javascript is used to change the CSS properties of one of the HTML elements that is wrapping the images, causing it to scroll or shift position.
With HTML5, you have more options, but the above is the way things have usually been done until now.
Finally, if you are going to actually implement this, there are a number of scripts available that will probably meet your needs, but if not I highly recommend using a Javascript framework like JQuery - it will make things much, much easier.
If you want to build it by yourself, one straightforward way would be to have a master div and all the images in it, lined up horizontally. Have the overflow set to hidden on the master div. Then use javascript and set scrollLeft as the user clicks the next, previous buttons.

Is it possible to use CSS to update parts of an HTML page in a way similar to frames?

Is it possible to use CSS to work like frames?
What I mean is, when we use frames (left, right for example), clicking on left will refresh only the right section using the 'target' attribute.
Is it possible to create this effect with CSS?
Thanks.
Using frames is usually a bad idea
To answer your question, no, CSS cannot be used to work like frames. CSS is used to changing the style of HTML and as such, cannot actually change the content of a page. It can be used to hide content, but I don't think that is what you require.
However, I feel in this case you may be asking the wrong question. As frames are usually the wrong approach.
When starting out in web design, frames seem like a great idea. You can seperate your navigation from your content, your site will load quicker because the navigation is not loaded every time and the menu is always visible, even when the page is loading.
But, actually, frames are incredibly bad for your usability.
Your users cannot bookmark individual pages
Printing is broken
Standard features in a browser like open in new tab often breaks
Users cannot copy/paste the web address for a specific page for sending to a friend
Frames do have their uses (e.g. Google image search), but for standard navigation menus they are not recommended. Try creating a page in a dynamic server language such as PHP or ASP.NET.
These languages have ways of creating standard elements such as your navigation menu without the use of frames.
No, this has nothing to do with CSS. CSS is for styling elements only. What you are looking for is an IFRAME. And IFRAME can be given a name
<iframe name="my_iframe" src="xyz.htm"></ifram>
and then be targeted in a link.
I've got a design that relies on framed content using CSS. You can do this by using overflow:auto, however it won't do what you want, i.e. loading certain portions of a page. To do this you'd need to use some AJAX library such as jQuery to load the content area dynamically. This is quite dangerous though as your URL may not relate to the current content of the page.
You could probably do something with the overflow part of CSS.
If you set up a div with overflow:auto with a fixed width and height with alot of content you will get scrollbars. Potentially you could use anchors to get content to move to be viewed within the div.
This means that all your content is in one page and it is just moved around with the anchors. You could do a similar thing using a jquery tabs plugin too.
I have never tried this and it might need javascript to get it to work fully.