We want a simple solution to lazy-loading data, based on the visible area of the website, without using any external libraries. The most obvious use case for such a system, would be the loading of images on a website, as one scrolls down the page. If you only want the code, you can find it on GitHub.
We need an attribute or something similar which identifies the relevant elements. In this example, we will use the attribute “realsrc”, to save the URL of a image which should be lazy-loaded and displayed as a background image for the respective container. This means the HTML should look something like this:
We need event listeners, which fire upon the relevant events. If we don’t add a listener for
load, lazy-loaded elements will only be loaded, once the first scroll event fires, which is generally not what we want. Likewise, if we’re using a responsive design, we need to listen for
resize events, because users might expose more visible area, by resizing the window.
We then need a callback function for the event listeners. We will call it
refresh_handler in our example.
Getting the relevant elements
We have given all elements, which have to change in some way, an attribute called “realsrc”. This means we now simply select all elements which have this attribute. This isn’t very efficient, however we only have to query those elements once and then cache them in a variable. We should also remember which elements were already changed. Since the DOM is parsed top down, we can increment a counter, representing the position within the array of elements until which we have already modified the respective element, so that we do not attempt to modify them again
Getting the current view box
The most reliable, cross-browser way of calculating the current view-box, is by using an element or pseudo element on top of the page. On my web page I use my navigation bar for this, but you might as well just insert an empty container at the start of your HTML code and give it any unique ID.
Selecting and modifying elements
We then use a loop to iterate through the elements and modifying any contained within the view-box. We should define an offset, so that pictures are already loaded if they are almost within the visible area.
Optional: Optimizing the execution
Define minimum view-box change
We have already cached elements and guaranteed, that we do neither modify an element twice nor even check twice if it is within the current view-box. Scroll events, unfortunately, are triggered very rapidly. Rate limiting those is difficult, so an easier, but similarly efficient solution is to have as little code as possible executed per handler. We can achieve this by checking how much the view-box changed, at the very beginning of the handler, before doing anything else.
De-register Event Listener
Since we return from the handler at the first element that’s not visible within the loop, reaching the end of the loop and leaving it without a return-statement, means that there are no more elements to modify or load. This in return means that we can simply de-register the event-listeners, so they won’t be executed anymore anyway.
- Complete code example
Feel free to share your thoughts or ask a question!