美文网首页
懒加载和预加载

懒加载和预加载

作者: 临安linan | 来源:发表于2019-11-08 20:06 被阅读0次

    更多个人博客:(https://github.com/zenglinan/blog)

    如果对你有帮助,欢迎star。

    懒加载

    懒加载在一些图片繁多的网站很常见, 举个简单的例子, 淘宝的首页里有很多商品图片, 用户可以一直往下拉, 但是很多用户往往都下拉不了多少就跳转到别的地方了, 假如一次性把首页的所有图片都请求加载下来, 这会导致几个严重的问题:

    1. 影响网页加载速度
    2. 浪费用户带宽
    3. 影响浏览器并行加载同域名下的其他资源 (浏览器并行加载同域资源有数量限制)

    懒加载的实现原理

    将页面的图片的 src 设为 loading 图片的路径, 将真实路径存储起来, 同时给未加载的图片添加标记属性。

    监听页面的滚动事件(这里最好做一下节流), 滚动时遍历未加载的图片, 获取图片距离可视区顶部的高度, 假如小于页面高度, 就将 src 替换真实的 url

    代码实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Lazyload 1</title>
    </head>
    <body>
      <img src="images/loading.gif" data-src="images/1.png">
      <img src="images/loading.gif" data-src="images/2.png">
      <img src="images/loading.gif" data-src="images/3.png">
      <img src="images/loading.gif" data-src="images/4.png">
      <img src="images/loading.gif" data-src="images/5.png">
      <img src="images/loading.gif" data-src="images/6.png">
      <img src="images/loading.gif" data-src="images/7.png">
      <img src="images/loading.gif" data-src="images/8.png">
      <img src="images/loading.gif" data-src="images/9.png">
      <img src="images/loading.gif" data-src="images/10.png">
      <img src="images/loading.gif" data-src="images/11.png">
      <img src="images/loading.gif" data-src="images/12.png">
      <script>
        class LazyLoad {
          constructor(){
            this.clientHeight = window.innerHeight  // 可视区高度
            this.initLoad()  // 初始加载
            this.bindScrollEvent()
          }
          initLoad(){
            this.lazyLoad()
          }
          bindScrollEvent(){
           let fn = this.throttle(() => {
              this.lazyLoad()
            }, 300)  // 300ms可执行一次 
           document.addEventListener('scroll', fn)
          }
          lazyLoad(){
            let images = document.querySelectorAll("img[data-src]")
            Array.from(images).forEach((img) => {
              let offsetTop = this.getPosition(img)
              if(offsetTop < this.clientHeight){
                img.src = img.getAttribute("data-src")
                img.removeAttribute('data-src', '')  // 每次删除已加载图片的 data-src 属性, 避免下次再遍历到, 提升性能
              }
            })
          }
          getPosition(el){
            return el.getBoundingClientRect().top
          }
          throttle(fn, timeout){  // 节流
            let perious = 0
            return function(){
            let now = +new Date()
              let args = arguments
              if(now - perious >= timeout){
                perious = now
                fn.apply(this, args)
              }
            }
          }
        }
        let lazyLoadObj = new LazyLoad()
      </script>
    </body>
    </html>
    

    预加载

    预加载与懒加载相反, 懒加载是延迟加载, 在需要展示或用到的时候才加载

    预加载是预先加载好后面需要用到的资源, 后面使用的时候直接去缓存里取。举个栗子, 比如一个网站的开场动画, 这些动画是由很多图片组成的, 假如不预先加载好, 那就会造成动画不流畅产生闪动白屏。

    预加载实现

    HTML 实现预加载

    在 link 标签上设置 rel="prefetch" 可以实现预加载, 该方法兼容性还不太好。

    CSS 实现图片预加载

    将图片放在 CSS 中加载, 但不显示

    #preload { background: url(http://domain.tld/image-01.png) no-repeat -9999px -9999px; }
    

    JS 实现预加载

    JS 实现预加载 js 文件和 css 文件时, 标签必须嵌入页面才会生效。

    // CSS
    var css = document.createElement('link');
    css.type = "text/css";
    css.rel  = "stylesheet";
    css.href = "http://domain.tld/preload.css";
    document.body.appendChild(css)
    
    // JS
    var js  = document.createElement("script");
    js.type = "text/javascript";
    js.src  = "http://domain.tld/preload.js";
    document.body.appendChild(js)
    
    // img
    new Image().src = "http://xxxx.com"
    

    Ajax 实现预加载

    Ajax 实现预加载比较好的一个点是, 不需要创建标签影响到页面, 但是可能会有跨域问题

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://xxxx.js');
    xhr.send('');
    

    相关文章

      网友评论

          本文标题:懒加载和预加载

          本文链接:https://www.haomeiwen.com/subject/ceiwbctx.html