美文网首页
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加载同步还是异步? JSONP原理?

    1、浏览器端的js加载默认是同步还是异步?同步,可以人为设置异步;async让js异步加载,需要每个script标...

  • java_Ajax

    Ajax:(asynchronous js and xml) 异步的js和xml 指的是一种交互方式 异步加载,客...

  • js面试题-3(ajax)

    1. 阐述一下异步加载 JS 异步加载的方案: 动态插入script标签 通过ajax去获取js代码,然后通过e...

  • 系统源码简析

    同步加载 异步加载 页面的懒加载,只针对vue文件,js文件被放到app.js中了, 比如 share.js。 a...

  • 网页优化

    1. 资源代码压缩合并,减少HTTP请求 2. 非核心代码的异步加载 异步加载方式:动态脚本加载(js创建SCRI...

  • JS异步加载

    最近做一个H5项目,一套代码跑在多个app webview,这个地方涉及到很多js文件的引入和加载,做了一个js加...

  • JS异步加载

    1. defer 属性 在 元素中设置 defer 属性,等于告诉浏览器立即下载,但延迟执行。defer属性只适...

  • Review JavaScript

    红宝书 综合 script加载js会阻塞渲染,标签中 fefer 指异步加载js,在文档load之后按顺序执行。a...

  • JavaScript补充

    01-延迟和异步加载JS 如何延迟加载JS:defer defer:js脚本可以延迟到文档完全被解析后执行 如何异...

  • webpack打包代码实现

    webpack模块加载 异步模块加载 通过 import()实现指定模块的懒加载操作 懒加载的核心原理就是创建js...

网友评论

      本文标题:JS的异步加载

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