【性能优化】懒加载和预加载小汇总与简单使用

浏览器【加载资源】机制:

1.前提摘要:从输入URL到看到页面的时间(单单指前端部分,不考虑后端相应时间等问题)

2.前端部分主要花费的时间在这【3】部分
①HTML页面请求时间(就是发送URL请求到拿到HTML字符串的时间)→②页面资源请求时间(就是CSS,JS,一些用到的插件库以及图片等【时间占比最多】)→③页面绘制时间(就是浏览器把我们请求回来的HTML字符串以及资源绘制成我们看到的网页)

3.页面加载的流程图
【性能优化】懒加载和预加载小汇总与简单使用_第1张图片
4.细说【资源加载】的知识点
从上面的流程图可以看出,这个顺序就是我们2中说的顺序一样,这里再细说一下:先将html下载回来,浏览器对head头部的资源进行下载完毕后再对DOM树进行渲染和对应所需的资源下载,这里是同步进行的,边渲染边下载资源;
那么我们看看资源内部又是怎么下载的→图【性能优化】懒加载和预加载小汇总与简单使用_第2张图片
加载资源时是浏览器内部进行排列来加载的,我们应该要注意这几点:

  • 不同浏览器对资源文件的排列加载可能会有所不同,但是一般差异不大;
  • 按照排列好的资源文件进行资源的下载,成功下载是发送请求成功并返回相应资源;
  • 注意发送请求是并发的,浏览器不需要等到请求返回数据成功后再发送其他请求(IE6除外);
  • 浏览器都有自己的并发限制,不是一股脑的把请求全部发送;
  • 虽然浏览器都是有自己加载资源的排列规则,但这不代表,写在body层中的资源会优于head头部的资源进行加载,所以这就是我们写代码的规范所在;
  • 资源加载中一般是css和js资源是优于图片资源进行加载的;
  • 如果script的执行阻塞(没有对这些会出现阻塞的代码进行处理),会导致后面的资源和渲染无法进行;

问题:那么什么资源文件应该写在head头部?怎样避免页面加载不出来(避免js阻塞)? 后续详细总结…

正题:懒加载

**概念原理:**对非必要的资源进行延后加载,等到需要加载时使用JS再去加载DOM元素,图片等;
代码展示:


<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>lazyLoadertitle>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .pic{
                width: 600px;
                height: auto;
                margin-top: 20px;
                margin-left: 50%;
                -webkit-transform: translate(-50%,-50%);
                -moz-transform: translate(-50%,-50%);
                -ms-transform: translate(-50%,-50%);
                transform: translate(-50%,0);
                border: 2px solid #000;
                text-align: center;
                padding: 20px 0;
            }
        style>
    head>
    <body>
        <button id="btn">测试button>
        <div class="pic">div>
        <script type="text/javascript">
        /* 懒加载 */
        // ① 将需要进行懒加载的资源整合到一起
            var imgArr = ["https://img.alicdn.com/tfs/TB175W5agFY.1VjSZFnXXcFHXXa-520-280.jpg_q90_.webp",
        "https://img.alicdn.com/simba/img/TB1Pi00dq1s3KVjSZFASut_ZXXa.jpg",
        "https://aecpm.alicdn.com/tps/i2/TB10vPXKpXXXXacXXXXvKyzTVXX-520-280.jpg",
        "https://img.alicdn.com/tfs/TB16jSHaMFY.1VjSZFnXXcFHXXa-520-280.jpg_q90_.webp"
        ]
            var jsArr = ["https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js",
        "https://cdn.bootcss.com/vue/2.0.0/vue.min.js",
        "https://cdn.bootcss.com/twitter-bootstrap/3.0.0/js/bootstrap.min.js"
        ]
            var cssArr = "https://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap-theme.min.css";
        // ② 封装一个懒加载函数
        function lazyLoader(url,type,target = document.body){
            // 1.先写报错处理
            if(!url) throw new Error("Parameter missing: Pass in the first parameter --URL!");
            if(!type) throw new Error("Parameter missing: Pass in the second  parameter --TYPE!");

            // 2.声明一个对象将三种用到的类型整理起来
            var judge = {
                img: function(){
                    var img = new Image();
                    return img;
                },
                js: function(){
                    var script = document.createElement("script");
                    script.setAttribute("type","text/javascript");
                    return script;
                },
                css: function(){
                    var link = document.createElement("link");
                    link.setAttribute("type","text/css");
                    link.setAttribute("ref","stylesheet");
                    return link;
                }
            }

            // 3.判断传入的是String字符串还是Array数组
            if(typeof url == 'string'){              
                var $dom = judge[type]();
                $dom.src = url;
                $dom.href = url;
                target.appendChild($dom);
            }else if(url instanceof Array){
                url.forEach(function(item,index){ 
                    var $dom = judge[type]();
                    $dom.src = item;
                    $dom.href = item;
                    target.appendChild($dom);
                })
            }else{
                throw new Error("URL type error: please pass in the correct URL type!");
            }
        }

        // 4.调用封装好的懒加载函数
        document.getElementById("btn").onclick = function(){
            var $pic = document.getElementsByClassName("pic")[0];
            var $head = document.getElementsByTagName("head")[0];
            lazyLoader(imgArr,"img",$pic);
            lazyLoader(cssArr,"css",$head);
            lazyLoader(jsArr,"js");
        }
        script>
    body>
html>

运用场景:
① 首屏内容过大,一次加载完需要很多时间,此时可以合理利用懒加载让用户尽快看到页面;
② 用户自主使用的功能中包含大量资源的,如地图定位系统,聊天系统,支付绑卡系统等,只有当用户点击使用该功能时才进行加载对应资源;
③ 多图片展示的页面,像花瓣,图展汇。可以通过用户滚动距离来进行展示图片;

正题:预加载

**概念原理:**只有将所有资源加载完毕后才让用户看到,一般在JS进行加载资源的时候,使用遮罩遮住页面,当对应的资源加载完成时将遮罩去掉;
代码展示:


<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            #mask{
                display: block;
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                z-index: 99;
                color: #fff;
                text-align: center;
                background-color: rgba(0, 0, 0, .7);
            }
            .loadNum{
                margin-top: 10%;
            }
            #btn{
                width: auto;
                line-height: 24px;
                padding: 0 5px;
                border-radius: 6px;
                background-color: coral;
                text-align: center;
                border: 1px solid transparent;
                outline: none;
                cursor: pointer;
            }
            #btn:hover{
                background-color: lightblue;
            }
        style>
    head>
    <body>
        <div id="mask">
            <div class="loadNum">0%div>
        div>
        <div class="pic">div>
        <button id="btn">测试button>
        <script type="text/javascript">
            /* 预加载 */
            // ① 将需要预加载的资源进行整合
            var imgArr = ["https://img.alicdn.com/tfs/TB175W5agFY.1VjSZFnXXcFHXXa-520-280.jpg_q90_.webp",
        "https://img.alicdn.com/simba/img/TB1Pi00dq1s3KVjSZFASut_ZXXa.jpg",
        "https://aecpm.alicdn.com/tps/i2/TB10vPXKpXXXXacXXXXvKyzTVXX-520-280.jpg",
        "https://img.alicdn.com/tfs/TB16jSHaMFY.1VjSZFnXXcFHXXa-520-280.jpg_q90_.webp"
        ]
            var jsArr = ["https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js",
        "https://cdn.bootcss.com/vue/2.0.0/vue.min.js",
        "https://cdn.bootcss.com/twitter-bootstrap/3.0.0/js/bootstrap.min.js"
        ]
            var cssArr = "https://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap-theme.min.css";
            // ② 封住一个预加载函数
            function preLoader(url,type,$mask,target= document.body){
                // 1.处理报错信息
                if(!url) throw new Error("Parameter missing: Pass in the first parameter --URL!");
                if(!type) throw new Error("Parameter missing: Pass in the second  parameter --TYPE!");

                // 2.声明一个对象整合不同资源类型
                var judge = {
                    img: function(){
                        var img = new Image();
                        return img;
                    },
                    js: function(){
                        var script = document.createElement("script");
                        script.setAttribute("type","text/javascript");
                        return script;
                    },
                    css: function(){
                        var link = document.createElement("link");
                        link.setAttribute("type","text/css");
                        link.setAttribute("ref","stylesheet");
                        return link;
                    }
                }

                // 3.对参数传入的类型做不同的处理
                var lenTem = 0;
                if(url instanceof String){
                    var $dom = judge[type]();
                    $dom.src = item;
                    $dom.href = item;
                    target.appendChild($dom);
                    lenAll++;

                }else if(url instanceof Array){
                    // 3.1记录加载资源的总长度
                    var lenAll = url.length;
                    
                    url.forEach(function(item,index){
                        var $dom = judge[type]();
                        $dom.src = item;
                        $dom.href = item;
                        // 3.2使用onload进行记录每次插入的标签时长度+1,知道加载长度等于总资源长度是去掉遮罩层
                        $dom.onload = function(){
                            lenTem++;
                            target.appendChild($dom);
                            console.log("lenAll",lenTem);
                            $mask.innerHTML = (lenTem/lenAll) * 100 + "%";
                            if(lenAll == lenTem){
                              $mask.style.display = "none";
                            }
                        } 
                    })
                }else{
                    throw new Error("URL type error: please pass in the correct URL type!");
                }    
            }
                 // 4.调用预加载函数
                 window.onload = function(){
                    var $pic = document.getElementsByClassName("pic")[0];
                    var $mask = document.getElementById("mask");
                    preLoader(imgArr,"img",$mask,$pic);
                 }     
        script>
    body>
html>

运用场景:
① 需要完全资源加载完毕达到流畅体验的应用;
② 常见的就是游戏应用,如H5游戏,微信小程序等;

你可能感兴趣的:(【性能优化】)