Meaning lazy loading (Why use lazy load)
Impact on page loading speed is the biggest picture, a general picture can reach the size of a few M, and the code is perhaps only a few dozen KB. When the page loading speed a lot of pictures, the pages slowly, within a few clock S page is not loaded, you might lose a lot of users. So much for the picture of the page, in order to speed up page load times, so many times we need to not appear in the visible region within a page Picture not loaded first, and then wait until the scroll to the visible area to load. For this way will be greatly improved page load performance, but also improve the user experience.
Lazy loading, by definition, in the current Web page, slide the page to be able to see the picture when the picture reload
Therefore, the problem split into two:
- How to determine the picture appears in the current viewport (that is, how can we judge to see pictures)
- How to control image loading
# Option One
How to determine the picture appears in the current viewport clientTop, offsetTop, clientHeight and scrollTop various heights on the picture for comparison
These are highly representative of what does this mean?
That I used to know it is possible, then I am more simple, like Sike. I figured out now, but back then things do not turn up
So it has a problem: complex trivial difficult to understand!
Just know that it's static height is not enough, we also need to know the dynamics of
How to dynamically? Listen window.scroll event
How to control image loading
<Data-IMG the src = "shanyue.jpg"> // NOTE: To specify the width and height of image
Instead of using the src data-src attribute setting a temporary data-src, load control
# Option II
The above program to improve it
How to determine the current picture appears in the introduction of a new viewport the API, Element.getBoundingClientRect () method returns the size of the element and position relative to the viewport.
How to determine that the picture appears in the current viewport it, according to the schematic example, the following code, this is easier to understand, and on the back can easily be (you can happily go to the interview).
// clientHeight highly representative of the current viewport img.getBoundingClientRect (). Top <document.documentElement.clientHeight
Listen window.scroll event also optimize it
Add throttle, to improve performance. Work generally used lodash.throttle on it, Almighty lodash ah!
_.throttle(func, [wait=0], [options={}])
# Option III
And then improve it
How to determine the picture appears in the current viewport program two methods used are: window.scroll listening Element.getBoundingClientRect () and use the throttle _.throttle
A series of combined action too complicated, so the browser out of a triple event: IntersectionObserver API, a can monitor whether the current viewport element to the event, in one step!
Event callback parameter is IntersectionObserverEntry collection, whether on behalf of a range of values in the visible viewport
Which, entry.isIntersecting represents the target element is visible
const observer = new IntersectionObserver((changes) => { // changes: 目标元素集合 changes.forEach((change) => { // intersectionRatio if (change.isIntersecting) { const img = change.target img.src = img.dataset.src observer.unobserve(img) } }) }) observer.observe(img) <script> var num = document.getElementsByTagName('img').length; var img = document.getElementsByTagName("img"); var n = 0; //Store pictures loaded into position, avoiding every traversing from the first picture lazyload (); // page is loaded but finished loading pictures in the area window.onscroll = lazyload; function lazyload () { // listen for page scrolling event var seeHeight = document.documentElement.clientHeight; // visible area of height var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // scrollbar height from the top for ( var I = n-; I <NUM; I ++ ) { IF (IMG [I] .offsetTop <+ seeHeight scrollTop) { IF (IMG [I] .getAttribute ( "the src") == "default.jpg" ) { IMG [I] .src= img[i].getAttribute("data-src"); } n = i + 1; } } } </script>
<script> var n = 0, imgNum = $("img").length, img = $('img'); lazyload(); $(window).scroll(lazyload); function lazyload(event) { for (var i = n; i < imgNum; i++) { if (img.eq(i).offset().top < parseInt($(window).height()) + parseInt($(window).scrollTop())) { if (img.eq(i).attr("src") == "default.jpg") { var src = img.eq(i).attr("data-src"); img.eq(i).attr("src", src); n = i + 1; } } } } </script>
Use of a throttle function performance optimization
If the function is directly bound to the scroll event, when the page is scrolled, the function will be triggered high frequency, which is affecting the performance of the browser.
I want to achieve the trigger limit frequency to optimize performance.
Throttle function: a function is executed only once in N seconds. Here is a simple throttling function:
// simple function of the throttle // function fun to execute // Delay delay // time must be executed within a time period function Throttle (fun, Delay, time) { var timeout, the startTime = new new a Date (); return function () { var context = the this , args = arguments, curTime = new new a Date (); the clearTimeout (timeout); // if the trigger reaches a predetermined time interval, triggers Handler IF (curTime - the startTime> = time) { fun.apply (context, args); startTime =curTime; // did not reach the trigger interval, to reset the timer } the else { timeout = the setTimeout (Fun, Delay); } }; }; // actually want to bind on the scroll event Handler function lazyload ( Event ) { for ( var I = n-; I <imgNum; I ++ ) { IF . (img.eq (I) .offset () Top <the parseInt ($ (window) .height ()) + the parseInt ($ (window) .scrollTop () )) { IF (img.eq (I) .attr ( " the src " ) == " default.jpg") { Var the src = img.eq (I) .attr ( " Data-the src " ); img.eq (I) .attr ( " the src " , the src); n- = I + . 1 ; } } } } // employed throttling function window.addEventListener ( ' Scroll ' , throttle (lazyload, 500 , 1000 ));