zoukankan      html  css  js  c++  java
  • 异步加载script,提高前端性能(defer和async属性的区别)

    一、异步加载script的好处

    为了加快首屏响应速度,前端会采用代码切割、按需加载等方式优化性能。异步加载script也是一种前端优化的手段。

    就好比如果我的页面其中一个功能需要打开地图,但是地图的js插件包是非常大的,而如果用户不用地图功能的时候,我们当然不能再给它加载js地图包,白白让他多花等待时间岂不是很冤枉!于是我们可以动态插入script,当用户点击了某个按钮的时候,再新建script标签,引入地图js资源。

    下面介绍下异步加载script的几种方式。

    二、异步加载script的方式

    1. 异步加载JS
        getMap.onclick = function(){
            //获得需要插入的位置
            var oDiv = document.getElementById('div');
            //异步创建script
            var script = document.createElement('script');
            
            script.src = 'https://map.baidu.com/...'
            
            oDiv.appendChild(script);
        }
    
    2. script标签加上defer或async

    script标签存在两个属性,defer和async,加上两个属性之后,在js真正执行之前都不会阻止html的加载。因此script标签的使用分为三种情况:

    • 没有defer或async属性,浏览器会立即加载并执行相应的脚本。也就是说在渲染script标签之后的文档之前,不等待后续加载的文档元素,读到就开始加载和执行,此举会阻塞后续文档的加载;
    <script src="example.js"></script>
    
    • 有了async属性,表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行;
    <script async src="example.js"></script>
    
    • 有了defer属性,加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本的执行需要等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前。
    <script defer src="example.js"></script>
    

    下图可以直观的看出三者之间的区别:

    其中蓝色代表js脚本网络加载时间,红色代表js脚本执行时间,绿色代表html解析。

    从图中我们可以明确一下几点:

      1.defer和async在网络加载过程是一致的,都是异步执行的;

      2.两者的区别在于脚本加载完成之后何时执行,可以看出defer更符合大多数场景对应用脚本加载和执行的要求;

      3.如果存在多个有defer属性的脚本,那么它们是按照加载顺序执行脚本的;而对于async,它的加载和执行是紧紧挨着的,无论声明顺序如何,只要加载完成就立刻执行,它对于应用脚本用处不大,因为它完全不考虑依赖。

    转载于:https://www.cnblogs.com/neusc/archive/2016/08/12/5764162.html

    3. 通过 ajax 去获取 js 代码,然后通过 eval 执行
    window.onload = function(){
        //1.创建XMLHttpRequest对象并考虑兼容性
        var xhr;
        if(window.XMLHttpRequest){
            //通用浏览器
            xhr = new XMLHttpRequest();
        }
        else{
            //IE5/6
            xhr = new ActiveXObject('Miscrosoft.XMLHttp')
        }
        
        //2.设置请求方式
        let url = '';
        xhr.open('get', url, true);//异步请求
        
        //3.发送请求
        xhr.send();
        
        //4.回调函数
        xhr.onreadyStateChange = function(){
            if(xhr.readyState == 4 && xhr.status == 200){
                let script = xhr.responseText;
                eval(script);   //异步加载script
            }
        }
    }
     
    
    4. 创建并插入 iframe,让它异步执行 js
    var iframe = document.createElement('iframe'); 
     document.body.appendChild(iframe); 
     var doc = iframe.contentWindow.document; 
     doc.open().write('<body onload="insertJS()">'); 
     doc.close();
    
  • 相关阅读:
    3-2
    3-1
    2-11
    2-10
    2-7
    2-9
    springboot 使用undertow代替tomcat容器提高吞吐量
    springboot—JVM性能参数调优
    springbootDay3
    springboot_Mybaits_PageHelper
  • 原文地址:https://www.cnblogs.com/soyxiaobi/p/9519895.html
Copyright © 2011-2022 走看看