1

昨晚‘今日头条’笔试题中遇到这道题,今天专门查了一下。

从 IE 8、Firefox 3.5、Safari 4 和 Chrome 2 开始都允许并行下载 JavaScript 文件。

<script>标签在下载外部资源时不会阻塞其他<script>标签。遗憾的是,JavaScript 下载过程仍然会阻塞其他资源的下载,比如样式文件和图片。尽管脚本的下载过程不会互相影响,但页面仍然必须等待所有 JavaScript 代码下载并执行完成才能继续。

实现延迟加载的方式有:

方式一:标签放在底部

<script>节点放置在</body>之前,这样js脚本会在页面显示出来之后再加载。

方式二:Defer和Async属性

使用script标签的deferasync属性

Defer属性

defer是在html4.0中定义的

html5规范要求脚本按照出现的顺序执行,对应的js文件在页面解析到<script>标签时开始下载,但不会执行,直到DOM加载完成,即onload事件触发前才会执行

当一个带有 defer 属性的 JavaScript 文件下载时,它不会阻塞浏览器的其他进程,因此这类文件可以与其他资源文件一起并行下载。

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

缺点:并不是所有浏览器支持该属性

async属性

async是html5新增的属性,IE10和其他浏览器都支持该属性

同defer一样,不会阻塞其余资源的加载,也不会影响页面的加载,但js一旦加载好了就会执行,所以很有可能不是按照原本的顺序来执行

方式三:动态脚本元素

DOM动态创建<script>

var script = document.createElement('script');
script.type = "text/javascript";
script.src = "script.js";
document.getElementByTagName('head')[0].appendChild(script);

可以监听脚本是否加载成功

script.onload = function(){
    alert('script loaded!');
};
/*IE中的监听方式不一样*/
script.onreadystatechange = function(){
    if(script.readyState == 'load' || script.readyState == 'complete'){
        script.onreadystatechange = null;
        alert('script loaded');
    }
};

方法四:使用XMLHttpRequest(XHR)

var xhr = new XMLHttpRequest();
xhr.open('get', 'script.js', true);
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
            var script = document.createElement('script');
            script.type = "text/javascript";
            script.text = xhr.responseText;
            document.body.appendChild(script);
         }
     }
};
xhr.send(null);

优点:
可以下载不立即执行的javascript代码;
同样的代码在所有现代浏览器中都可以正常运行。

缺点:
javasript文件必须和页面放置在同一个域中,不能从CDN下载,所以大型网页通常都不采取XHR脚本注入技术。

总结

减少 JavaScript 对性能的影响有以下几种方法:

将所有的<script>标签放到页面底部,也就是</body>闭合标签之前,这能确保在脚本执行前页面已经完成了渲染。

尽可能地合并脚本。页面中的<script>标签越少,加载也就越快,响应也越迅速。无论是外链脚本还是内嵌脚本都是如此。

采用无阻塞下载 JavaScript 脚本的方法:
使用<script>标签的 defer 属性(仅适用于 IE 和 Firefox 3.5 以上版本);
使用动态创建的<script>元素来下载并执行代码;
使用 XHR 对象下载 JavaScript 代码并注入页面中。


bottle_
259 声望22 粉丝

好好学习,好好生活,好好工作


« 上一篇
css3整理