js并行加载,顺序执行
<script>运行脚本或加载外部文件时,会阻塞页面渲染,阻塞其他资源的加载。如果页面中需要加载多个js文件,在古老浏览器中性能会比较糟糕。 因此有了最原始的优化原则:把脚本放在底部。
如何实现js非阻塞、并行加载,甚至能保持执行顺序呢?各浏览器表现如何?站在巨人的肩膀上,Kyle Simpson、Nicholas C. Zakas和Steve Souders对此有过总结和方案。
背景
1. Script DOM Element。 动态插入<script>,不会阻塞,但无法保持执行顺序。但唯有Firefox可以保持执行顺序,但也差点在Firefox 4 nightly的版本中去掉这个特性。
2. HTML5 async 非阻塞,加载完后立即执行,不保证顺序。这个属性不管有没有值、值为true或false,都是等同的效果(由于Kyle的推进,不能保证执行顺序与其值无关了)。
Google Analytics的新版嵌入代码就结合使用了上面两个方案,如:
1
2
3
4
5
6
7
8
|
var ga = document.createElement( 'script' );
ga.type = 'text/javascript' ;
ga.async = true ;
+ '.google-analytics.com/ga.js' ;
var s = document.getElementsByTagName( 'script' )[0];
s.parentNode.insertBefore(ga, s); |
3. IE partsandspares.co.za defer属性。不阻塞,可以保证顺序,在DOM加载完成后执行(在DOMContentLoaded之前)。
4. <script>的type属性设为”script/cache” 非标准的type属性,使js文件只会被加载而不会执行。需要执行时,创建一个type属性为”text/javascript”的正常<script>元素,src设为前面已经加载的js地址即可,执行顺序开发者可控(执行时机也完全可控)。类似的方式也有通过<img>来做预加载的。
5. document.write。文档流关闭后执行会清空整个页面。
6. XHR 并行加载,执行顺序可控,但有同域限制。
基本需求
Steve Souders 和 Nicholas C. Zakas 一起总结了下,认为js加载方案必须解决以下问题:
- 支持特性检测
- 不会重复加载
- 支持并行加载
开发者的美好愿望
Nicholas C. Zakas 几经周折,有了以下的提案,分离js的加载和执行,方便开发者自由控制js的执行时间。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var script = document.createElement( "script" );
// 此属性仅可由js动态写入,在HTML标签中直接写入无效 script.preload = true ;
// src赋值后,立即触发加载(仅加载,不会执行js内容) script.src = "foo.js" ;
// onpreload是需要新支持的事件,加载完成后触发此事件 script.onpreload = function (){
// 在需要时,将加载的js插入到DOM中,即可运行生效
document.body.appendChild(script);
}; |
基于特性检测feature detection(区别于特性推测feature inference)
var isPreloadSupported = (typeof script.preload == “boolean”);
这一特性只有在Javascript中动态赋值时生效,直接写到HTML标签上时是无效的。
但这只是一个提案,开发者们的美好愿望,而非被浏览器支持的标准。目前这一提案已在LABjs中支持,Zakas本人也在积极推进此提案的标准化。
而Kyle在推进另外一种方式,即要求对含有属性async=false的<script>保持执行顺序。如果async=true,则一旦加载完则会马上执行脚本,不会严格保持顺序。默认地,页面中的<script>的async属性为false,即保持执行顺序;js创建的<script>的async属性为true,即加载完立即执行,不保证顺序。
为了支持特性检测,一个由js创建的<script>标签默认具有async=true的属性。
Kyle的这一提案已被HTML5小组接受放入草案,在Firefox 4 nightly版本中的也已实现。
Firefox 4为了更向HTML5标准看齐,一度在开发者版本中去掉了对动态创建<script>来加载js文件的执行顺序支持:
<script> elements created using document.createElement() and inserted into a document now behave according to the HTML5 specification by default. Scripts with the src attribute execute as soon as available (without maintaining ordering) and scripts without the src attribute execute synchronously.
为此,Kyle向WebKit开发团队抗议,提了一个bug,最终得到了如他所愿的支持:
To make script-inserted scripts that have the src attribute execute in the insertion order, set .async=false on them.
Zakas很欣赏Kyle的方案,Kyle在LABjs中也支持了Zakas的提议,各浏览器们也这么和谐就好了。
转自:http://www.impng.com/web-dev/parallel-download-ordered-execute.html
相关推荐
通过并行加载多个JS文件,head.js可以显著提高网站的加载速度,同时确保这些脚本按照指定的顺序执行,从而保持代码逻辑的正确性。 ### 1. 并行加载与顺序执行 传统的JavaScript加载方式通常是在HTML文档中通过`...
在标签中加入defer属性,可以让浏览器将JavaScript脚本的下载与DOM解析并行进行,但会等到DOM文档完全解析后再执行脚本。async属性告诉浏览器该脚本是异步下载和执行的,不需要等待其他脚本或CSS文件的加载完成。这...
通过优化网页的加载顺序,特别是将非关键的JavaScript广告放在最后加载,我们可以显著提高网页的首屏加载速度,从而提升用户体验。同时,对于网页性能的优化,还可以考虑使用CDN加速资源获取,压缩代码减少传输量,...
3. **延迟加载(defer)**:`defer`属性确保脚本按顺序执行,但同样不会阻塞页面解析。这对于库和框架等需要按特定顺序加载的脚本非常有用。 4. **图片预加载**:`loading.gif`可能是一个预加载指示器,用于在页面...
以一个示例来解释脚本执行顺序,我们可以考虑两个JavaScript文件(1.js和2.js)的加载。当这两个文件通过`<script>`标签按顺序引入时,无论它们是否并行下载,1.js总是在2.js之前执行。这可以通过延迟发送文件内容的...
`defer`属性则保证脚本在DOM解析完成后、DOMContentLoaded事件触发之前执行,且按照脚本在文档中的顺序执行。 2. 使用`XMLHttpRequest`或`fetch` API:通过创建HTTP请求获取JS文件内容,然后使用`document....
LAB.js通过智能管理和控制脚本加载顺序,确保了即便在异步加载的情况下,也能按照开发者的需求执行特定的脚本。 在传统的Web应用中,JavaScript文件通常按顺序写入HTML文件中,然后由浏览器逐个下载和执行。然而,...
3. **异步加载(Asynchronous Loading)**:避免阻塞主线程,使脚本并行加载,提升页面加载效率。 二、API介绍 根据描述,这个JS动态加载库提供了三个API,虽然具体名称未知,但常见的动态加载库的API可能包括: 1....
这样可以确保JS不会影响DOM的构建,但会按照`<script>`标签出现的顺序执行。 除了基本的加载方式,还可以通过以下几种策略优化JS加载: - **按需加载**(Lazy Loading):只在需要时加载JS,例如,滚动到页面底部...
在JavaScript中,处理异步操作时,经常需要按顺序执行一系列任务,特别是在处理网络请求时。传统的回调函数会导致“回调地狱”(Callback Hell),代码可读性和可维护性下降。为了解决这个问题,我们可以利用迭代器...
JavaScript 是Web开发中不可或缺的一部分,尤其...需要注意的是,虽然现代浏览器允许并行下载JavaScript文件,但仍然会阻塞样式和图片等其他资源的下载,因此,优化JavaScript加载和执行仍然是提升网页性能的关键步骤。
在网页开发中,JavaScript库和插件的加载顺序至关重要,特别是当依赖于其他库或特定功能的脚本时。在给定的标题和描述中,我们聚焦于`cookie.js`和`jquery.js`的加载顺序问题。`cookie.js`通常是一个用于处理浏览器...
尤其在支持像IE6这样的较旧浏览器时,这种策略显得尤为重要,因为这些浏览器可能对大量资源的并行加载处理能力有限。 首先,让我们深入理解JavaScript延迟加载(Lazy Loading)的概念。通常,JavaScript脚本如果...
串行加载可以保证脚本按照预期顺序执行,但缺点是每个脚本加载之间有时间间隔,可能会使得整个加载过程变慢。文章提供了一个名为`seriesLoadScripts`的函数,该函数接受一个包含多个脚本文件路径的数组,并接受一个...
总结,js文件动态加载是提升SPA性能的关键策略,通过合理的异步加载和执行机制,可以优化用户体验,同时确保程序在加载组件时的正确运行顺序。理解并掌握这些技术,对于现代Web开发来说至关重要。
入门正在安装npm install @takram/planck-loader例子下面的示例将并行加载data1.json , data2.json和lib.js (在JavaScript方面),而main.js将在加载lib.js之后加载。 import { Loader } from '@takram/planck-...
2. **配置和初始化**:设置预加载的图片列表,可以选择性地设定加载顺序、加载模式以及其他选项。 3. **调用预加载方法**:启动预加载过程,可以指定预加载的回调函数来处理加载完成后的逻辑。 4. **处理加载后的...