美文网首页
JS的异步加载

JS的异步加载

作者: zooeydotmango | 来源:发表于2019-08-19 03:02 被阅读0次

    为什么要异步加载

    浏览器下载除JS外的资源时,会并行下载,以提高性能。但下载JS脚本时,会禁止并行下载(称为脚本阻塞Scripts Block Downloads)。浏览器遇到JS时,必须等JS下载,解析,执行完后,才能继续并行下载下一个资源。原因是JS可能会改变页面或改变JS间的依赖关系,例如A.js中用document.write改变页面,B.js依赖于A.js。因此要严格保证顺序,不能并行下载。

    因此不推荐将JS放到<head>标签里,浏览器遇到<script>标签会下载,解析,执行完脚本后,才继续处理剩余的页面部分。

    为了避免白屏,通常的建议是将JS放到<body>标签底下,可以有最佳的用户体验,你可以点击例子页面试一下。如果你放到了<body>标签的上部,因为脚本阻塞,可能会影响用户体验。例子中位于<body>上部的JS耗时2s,因此位于JS下面的两张img图片,会等2s后才开始加载。

    将JS放在<body>底下的建议没有错,几乎成了前端的普世规则。但对于追求极致用户体验的站点,或大型网站来说,这还不够。

    异步加载的方法

    Dynamic Script Element动态脚本元素

    该技术不但简单,而且通用,且可以跨域,应该成为你的首选

    var script = document.createElement('script');  //创建script标签
    script.type = "text/javascript";
    script.src = "A.js";
    document.getElementsByTagName('head')[0].appendChild(script);   //塞进页面
    

    当JS下载完毕后,就会立即执行。如果多个JS间有依赖关系,一下载完马上执行可能会出现error。因此通常来说你应该将有依赖关系的JS合并成一个文件,虽然合并后JS文件会变大,但由于是异步下载,你几乎不会有什么损失。
    如果实在不方便将有依赖关系的文件合并。你需要自己指定先后顺序,通过监听load事件(IE是onreadystatechange)来确保依次加载脚本:

    function loadScript(url, callback){
        var script = document.createElement ("script")
        script.type = "text/javascript";
    
        if (script.readyState){ //IE
            script.onreadystatechange = function(){
                if (script.readyState == "loaded" || script.readyState == "complete"){
                    script.onreadystatechange = null;
                    callback();
                }
            };
        } else { //Others
            script.onload = function(){
                callback();
            };
        }
        script.src = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    }
    
    //严格确保A->B->C,依次下载脚本文件
    loadScript("A-delay.js", function(){
        loadScript("B-delay.js", function(){
            loadScript("C-delay.js", function(){
                console.log("All files are loaded!");
            });
        });
    });
    

    Script async

    HTML5里为script标签里新增了async属性,用于异步加载脚本

    <script type="text/javascript" src="alert.js" async="async"></script>
    

    1.async属性是HTML5新增属性,需要Chrome、FireFox、IE9+浏览器支持
    2.async属性规定一旦脚本可用,则会异步执行
    3.async属性仅适用于外部脚本
    4.此方法不能保证脚本按顺序执行

    Script defer

    script标签里可以设置defer,表示延迟加载脚本:

    <script type="text/javascript" src="alert.js" defer="defer"></script>
    

    1.defer属性规定是否对脚本执行进行延迟,直到页面加载为止
    2.如果脚本不会改变文档的内容,可将defer属性加入到<script>标签中,以便加快处理文档的速度
    3.兼容所有浏览器
    4.此方法可以确保所有设置了defer属性的脚本按顺序执行

    更多

    更多方法见
    异步加载JS脚本

    相关文章

      网友评论

          本文标题:JS的异步加载

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