JavaScript的性能优化:加载和执行

一、页面加入脚本的缺点

HTML中无论JavaScript是内嵌还是外链在文件中,都有以下特性:

  1. 页面的下载和渲染都必须停下来等待脚本执行完成(浏览器必须先花时间下载外链文件中的代码,然后解析并执行它);
  2. 执行时间耗时越久,浏览器等待响应用户输入的时间就越长(页面渲染和用户交互完全被阻塞了);
  3. 脚本可能会改变页面或JavaScript的命名空间,对后面页面内容造成影响。
二、脚本位置的影响

脚本位置可以放在<head><body>中, 并允许出现多次。

  1. 放在<head>
  • 浏览器先下载脚本并执行,因此CSS样式文件和<body>中的内容均无法被加载,造成页面空白现象
  • 第一个 JavaScript 文件下载,阻塞了页面其他文件的下载,且每个文件必须等到前一个文件下载并执行完成才会开始下载。在这些文件逐个下载过程中,用户看到的是一片空白的页面。
  • 对于有DOM操作的脚本,由于<body>中的内容还没有加载,因此执行脚本时会报错
    从 IE 8、Firefox 3.5、Safari 4 和 Chrome 2 开始都允许并行下载 JavaScript 文件。<script>标签在下载外部资源时不会阻塞其他<script>标签。遗憾的是,JavaScript 下载过程仍然会阻塞其他资源的下载,比如样式文件和图片。尽管脚本的下载过程不会互相影响,但页面仍然必须等待所有 JavaScript 代码下载并执行完成才能继续。因此,尽管最新的浏览器通过允许并行下载提高了性能,但问题尚未完全解决,脚本阻塞仍然是一个问题。
  1. 放在<body>中(推荐使用)
    尽管脚本下载会阻塞另一个脚本,但是页面的大部分内容都已经下载完成并显示给了用户,因此页面下载不会显得太慢。
三、减少JavaScript对性能的影响:
  1. 首要规则:将脚本放在底部。
  2. 合并脚本,减少<script>数量;
  3. 无阻塞下载JavaScript脚本:
    (1)在 window 对象的 onload事件触发后再下载脚本,即页面加载完成后才加载脚本;
    (2)定义defer属性延迟加载脚本,带有 defer 属性的<script>标签可以放置在文档的任何位置。对应的 JavaScript 文件将在页面解析到<script>标签时开始下载,但不会执行,直到 DOM 加载完成,即onload事件触发前才会被执行。
    (3)HTML5新属性async,它的作用和 defer 一样,能够异步地加载和执行脚本,不因为加载脚本而阻塞页面的加载。但是有一点需要注意,在有 async 的情况下,JavaScript 脚本一旦下载好了就会执行,所以很有可能不是按照原本的顺序来执行的。如果 JavaScript 脚本前后有依赖性,使用 async 就很有可能出现错误。
    (4)使用 XMLHttpRequest(XHR)对象
    先创建一个 XHR 对象,然后下载 JavaScript 文件,接着用一个动态 <script> 元素将 JavaScript 代码注入页面:
var xhr = new XMLHttpRequest();
xhr.open("get", "script1.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);
  • HTTP 状态码:2XX 表示有效的回应,304 表示一个缓存响应
  • 可以下载不立即执行的 JavaScript 代码;由于代码返回在<script>标签之外,它下载后不会自动执行,直到一切都准备好了。
  • 同样的代码在所有现代浏览器中都不会引发异常
  • 此方法最主要的限制是:JavaScript 文件必须与页面放置在同一个域内,不能从 CDN 下载(CDN 指"内容投递网络(Content Delivery Network)",所以大型网页通常不采用 XHR 脚本注入技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值