JavaScript非阻塞加载脚本
As more and more sites evolve into “Web 2.0″ apps, the amount of JavaScript increases. This is a performance concern because scripts have a negative impact on page performance. Mainstream browsers (i.e., IE 6 and 7) block in two ways:
- Resources in the page are blocked from downloading if they are below the script.
- Elements are blocked from rendering if they are below the script.
随着越来越多的网站涉及“Web 2.0”应用,JavaScript脚本的数量也急剧增加。这是令人忧虑的,因为脚本对页面性能有负面影响。主流的浏览器(例如IE 6 、7)会以下面2种方式发生阻塞:
- 如果资源位于脚本的下方,那么他们会被阻塞下载。
- 如果元素位于脚本的下方,那么他们会被阻塞渲染展示。
The Scripts Block Downloads example demonstrates this. It contains two external scripts followed by an image, a stylesheet, and an iframe. The HTTP waterfall chart from loading this example in IE7 shows that the first script blocks all downloads, then the second script blocks all downloads, and finally the image, stylesheet, and iframe all download in parallel. Watching the page render, you’ll notice that the paragraph of text above the script renders immediately. However, the rest of the text in the HTML document is blocked from rendering until all the scripts are done loading.
这个脚本阻塞下载的例子(Scripts Block Downloads example) 展示了上面的情况。它包括2个外部脚本,后面是1个图片、1个样式表和1个iframe。使用IE7加载这个例子的HTTP瀑布图显示了第一个脚本阻塞了所有的下载,随后第2个脚本阻塞了所有的下载,最后图片样式表和iframe并行加载。观察页面的渲染情况,你会发现脚本上方的那段文字会马上渲染。然而,HTML 文档其它部分的文字会被阻塞,直到所有的脚本被下载完毕。
在 IE6 7, Firefox 2 3.0, Safari 3, Chrome 1, Opera 脚本均会阻塞下载
Browsers are single threaded, so it’s understandable that while a script is executing the browser is unable to start other downloads. But there’s no reason that while the script is downloading the browser can’t start downloading other resources. And that’s exactly what newer browsers, including Internet Explorer 8, Safari 4, and Chrome 2, have done. The HTTP waterfall chart for the Scripts Block Downloads example in IE8 shows the scripts do indeed download in parallel, and the stylesheet is included in that parallel download. But the image and iframe are still blocked. Safari 4 and Chrome 2 behave in a similar way. Parallel downloading improves, but is still not as much as it could be.
如果浏览器是单线程的,那么当一个脚本在执行时,浏览器不能下载其它资源是可以理解的。但是没有理由解释当脚本下载时浏览器不能下载其它资源。下载脚本的同时并行下载其它资源是所有最新浏览器的已经实现了的功能,包括Internet Explorer 8, Safari 4, Chrome 2。在IE8中打开脚本阻塞下载的例子(Scripts Block Downloads example)的HTTP瀑布图展示了脚本确实是并行下载的,样式表也是并行下载的,然而图片和iframe仍旧被阻塞了。Safari 4 和 Chrome 2 的行为也很类似。并行下载改善了一部分,但还没有达到它能达到的最好的效果。
IE8, Safari 4, Chrome 2下,脚本仍旧是阻塞的
Fortunately, there are ways to get scripts to download without blocking any other resources in the page, even in older browsers. Unfortunately, it’s up to the web developer to do the heavy lifting.
幸运的是,即使在更老的浏览器中,也有使脚本不阻塞其它页面资源的办法。不幸的是,这取决于web开发人员是否愿意承担这些繁重的工作。
There are six main techniques for downloading scripts without blocking:
- XHR Eval – Download the script via XHR and eval() the responseText.
- XHR Injection – Download the script via XHR and inject it into the page by creating a script element and setting its text property to the responseText.
- Script in Iframe – Wrap your script in an HTML page and download it as an iframe.
- Script DOM Element – Create a script element and set its src property to the script’s URL.
- Script Defer – Add the script tag’s defer attribute. This used to only work in IE, but is now in Firefox 3.1.
- document.write Script Tag – Write the <script src=""> HTML into the page using document.write. This only loads script without blocking in IE.
下面有6种非阻塞式加载脚本的技术:
- XHR Eval - 通过XHR下载脚本,通过eval()执行。
- XHR Injection - 通过XHR下载脚本,通过创建一个script的DOM元素注入页面,并且设置text属性。
- Script in Iframe - 在一个HTML页面内包含脚本并通过iframe加载。
- Script DOM Element - 创建一个script的DOM元素,并且设置src属性为脚本的url。
- Script Defer - 增加脚本的defer属性。曾经仅在IE中可用,现在Firefox 3.1. 中也可以了。
- document.write Script Tag - 在HTML页面内使用document.write <script src="">。仅在IE有效。
You can see an example of each technique using Cuzillion. It turns out that these techniques have several important differences, as shown in the following table. Most of them provide parallel downloads, although Script Defer and document.write Script Tag are mixed. Some of the techniques can’t be used on cross-site scripts, and some require slight modifications to your existing scripts to get them to work. An area of differentiation that’s not widely discussed is whether the technique triggers the browser’s busy indicators (status bar, progress bar, tab icon, and cursor). If you’re loading multiple scripts that depend on each other, you’ll need a technique that preserves execution order.
在Cuzillion你可以看到每个技术的样例。事实证明这些技术有重要的区别,见下面表格。它们大部分提供并行下载,有些技术不能被使用在跨域名的脚本上,有些必须在你已有的脚本基础上简单的修改,还有一个未被广泛讨论的是否触发浏览器的繁忙指示标记区别(状态栏,进度条,标签图标和光标)。如果你需要加载多个相互依存的脚本,你还需要一个维护执行顺序的技术。
技术名称 | 支持并行下载 | 支持跨域名 | 不需修改脚本 | 是否有繁忙指示 | 保障执行顺序 | 大小(字节) |
---|---|---|---|---|---|---|
XHR Eval | IE, FF, Saf, Chr, Op | no | no | Saf, Chr | - | ~500 |
XHR Injection | IE, FF, Saf, Chr, Op | no | yes | Saf, Chr | - | ~500 |
Script in Iframe | IE, FF, Saf, Chr, Op | no | no | IE, FF, Saf, Chr | - | ~50 |
Script DOM Element | IE, FF, Saf, Chr, Op | yes | yes | FF, Saf, Chr | FF, Op | ~200 |
Script Defer | IE, Saf4, Chr2, FF3.1 | yes | yes | IE, FF, Saf, Chr, Op | IE, FF, Saf, Chr, Op | ~50 |
document.write Script Tag | IE, Saf4, Chr2, Op | yes | yes | IE, FF, Saf, Chr, Op | IE, FF, Saf, Chr, Op | ~100 |
The question is: Which is the best technique? The optimal technique depends on your situation. This decision tree should be used as a guide. It’s not as complex as it looks. Only three variables determine the outcome: is the script on the same domain as the main page, is it necessary to preserve execution order, and should the busy indicators be triggered.
问题是:哪个是最好的技术?最佳的技术取决于您的具体情况。下面这个决策树可以作为一个指导。它看起来复杂,其实并不是。只有3个参数就决定了输出结果:脚本是否在主页面的同一个域名之下,是否需要保障执行顺序,是否需要触发繁忙指示标记。
Ideally, the logic in this decision tree would be encapsulated in popular HTML templating languages (PHP, Python, Perl, etc.) so that the web developer could just call a function and be assured that their script gets loaded using the optimal technique.
最理想的是,这个决策树的逻辑将体现在流行的HTML模板语言中(PHP, Python, Perl, 等),因此WEB开发人员可以简单的调用一个函数,就能保证他们的脚本使用最佳的技术来加载脚本。
In many situations, the Script DOM Element is a good choice. It works in all browsers, doesn’t have any cross-site scripting restrictions, is fairly simple to implement, and is well understood. The one catch is that it doesn’t preserve execution order across all browsers. If you have multiple scripts that depend on each other, you’ll need to concatenate them or use a different technique. If you have an inline script that depends on the external script, you’ll need to synchronize them. I call this “coupling” and present several ways to do this in Coupling Asynchronous Scripts.
很多情况下,使用 Script DOM Element是一个不错的选择。它可以在所有浏览器下工作,没有任何跨域限制,代码上很容易实现,很容易被理解,唯一不足的是并不是在所有浏览器下均能保持正确的执行顺序。如果你有多个脚本并且相互依赖,你需要合并他们或使用其它技术。如果你在页面内有依赖于外部脚本的内联脚本,你必须对他们实现同步化,我将这个方法称为“coupling” 并在耦合异步脚本中提出一些可以做到这一点的方法。
JavaScript非阻塞加载脚本的更多相关文章
- 第一百一十八节,JavaScript,动态加载脚本和样式
JavaScript,动态加载脚本和样式 一动态脚本 当网站需求变大,脚本的需求也逐步变大.我们就不得不引入太多的JS脚本而降低了整站的性能,所以就出现了动态脚本的概念,在适时的时候加载相应的脚本. ...
- 让浏览器非阻塞加载javascript的几种方式
通常大多数浏览器是并行下载资源的,但由于外部脚本的特殊性例如通过脚本改变文档的DOM结构.脚本之间的存在依赖关系.使用document.write 向页面输出HTML等.浏览器为了确保正确执行脚本和呈 ...
- 高性能 js -- 无阻塞加载脚本
参考: <<高性能JavaScript>> Nicbolas C. Zakas 著 javascript代码的下载和执行过程会阻塞浏览器的其他进程, 比如页面的绘制, 遇到&l ...
- JavaScript无阻塞加载具体方式
将脚本放在底部.\还是放在head中,用以保证在js加载前,能加载出正常显示的页面.\<script>标签放在\前 成组脚本:由于每个\<script>标签下载时阻塞页面解析过 ...
- 探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密
下面的图片是我使用firefox和chrome浏览百度首页时候记录的http请求 下面是firefox: 下面是chrome: 在浏览百度首页前我都将浏览器的缓存全部清理掉,让这个场景最接近第一次访问 ...
- 无阻塞加载和defer、async
无阻塞加载 把js放在head里,浏览器是怎么去执行它的呢,是按顺序加载还是并行加载呢?在旧的浏览器下,都是按照先后顺序来加载的,这就保证了加载的js依赖不会发生问题.但是少部分新的浏览器已经开始允许 ...
- JavaScript的DOM_动态加载脚本和样式
一.动态加载脚本 当网站需求变大,脚本的需求也逐步变大.我们就不得不引入太多的 JS 脚本而降低了整站的性能,所以就出现了动态脚本的概念,在适时的时候加载相应的脚本. 1.动态加载js文件 比如:我们 ...
- 高性能Javascript--脚本的无阻塞加载策略
Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中,其中一条是将JS放在底部 .原因是,事实上,大多数浏览器使用单进程处理U ...
- 【转】高性能Javascript--脚本的无阻塞加载策略
原文转自:http://blog.jobbole.com/78191/ Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中, ...
随机推荐
- div布局方案整理
实际项目开发过程中遇到页面 DIV 左右布局的需求:左侧 DIV 固定宽度,右侧 DIV 自适应宽度,填充满剩余页面,由此引申出本文的几种解决方案 1 左侧 DIV 设置 float 属性为 left ...
- es6笔记4^_^function
一.function默认参数 现在可以在定义函数的时候指定参数的默认值了,而不用像以前那样通过逻辑或操作符来达到目的了. es5 function sayHello(name){ //传统的指定默认参 ...
- ubuntu 执行Python脚本出现: /usr/bin/env: ‘python\r’: No such file or directory
原因: #!/usr/bin/env python 在ubuntu会变成 #!/usr/bin/env python\r 而\r 会被shell 当成参数 所以出现: /usr/bin/env: ‘ ...
- 机器学习-线性回归LinearRegression
概述 今天要说一下机器学习中大多数书籍第一个讲的(有的可能是KNN)模型-线性回归.说起线性回归,首先要介绍一下机器学习中的两个常见的问题:回归任务和分类任务.那什么是回归任务和分类任务呢?简单的来说 ...
- httpd 2.2.15 添加流媒体模块
项目中使用的一直都是 httpd 2.2.15 用于播放视频资源,近期有个新产品上线发现快进视频会出现卡顿情况,因此添加了流媒体模块.(怀疑是新产品中的播放器进行了更改) 原文:http://li ...
- Check the string
A has a string consisting of some number of lowercase English letters 'a'. He gives it to his friend ...
- Thunder团队第六周 - Scrum会议2
Scrum会议2 小组名称:Thunder 项目名称:i阅app Scrum Master:宋雨 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...
- 如何:调试 .NET Framework 源代码
文章标题:如何:调试 .NET Framework 源代码 文章地址:https://technet.microsoft.com/zh-cn/cc667410.aspx
- MONyog-数据库性能监控工具
一.安装步骤 较为简单,网上可以搜索到,此处不做详细说明. 二.使用图解 此处介绍监控数据库连接量.并发量.吞吐量.响应时间等功能 1.设置连接需要监控的数据库 打开:http://127.0.0.1 ...
- python2 对URL编码进行编译
在请求页面时有时会返回类似: %E8%AF%A5985%E5%A4%A7%E5%AD%A6%E5%B8%B8%E5%B9%B4%E4%BD%8D%E5%B1%85%E5%9B%BD%E5%86%85% ...