`

js并行加载,顺序执行

阅读更多

js并行加载,顺序执行

<script>运行脚本或加载外部文件时,会阻塞页面渲染,阻塞其他资源的加载。如果页面中需要加载多个js文件,在古老浏览器中性能会比较糟糕。 因此有了最原始的优化原则:把脚本放在底部

如何实现js非阻塞、并行加载,甚至能保持执行顺序呢?各浏览器表现如何?站在巨人的肩膀上,Kyle SimpsonNicholas C. ZakasSteve 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;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www')
          + '.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加载方案必须解决以下问题

  1. 支持特性检测
  2. 不会重复加载
  3. 支持并行加载

开发者的美好愿望

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

分享到:
评论
1 楼 GreatExpectations 2016-09-06  
666可以可以哦

相关推荐

    headjs实现网站并行加载但顺序执行JS

    本文主要介绍如何使用head.js实现网站并行加载但顺序执行JS,提高网站加载速度。需要的朋友可以看下

    详解关于html,css,js三者的加载顺序问题

    DOM文档的加载顺序是由上而下的顺序加载; 1、DOM加载到link标签 css文件的加载是与DOM的加载并行的,也就是说,css在加载时Dom还在继续加载构建,而过程中遇到的css样式或者img,则会向服务器发送一个请求,待资源...

    planck-loader:提供并行和顺序的数据加载和进度观察

    入门正在安装npm install @takram/planck-loader例子下面的示例将并行加载data1.json , data2.json和lib.js (在JavaScript方面),而main.js将在加载lib.js之后加载。 import { Loader } from '@takram/planck-...

    JavaScript无阻塞加载和defer、async详解

    但是少部分新的浏览器已经开始允许并行加载js了,也就是说可以同时下载js文件,但是还是按先后顺序执行文件的。 下载是异步的没问题,但是每个javascript执行的时候还是同步的,就是先出现的script标签一定是先执行...

    lab.js-2.0.3

    lab.js它能够动态并行加载脚本文件 以及 管理加载脚本文件的执行顺序

    imageLoader:简单的 JavaScript 图像加载器

    加载可以并行或顺序进行。 #ImageLoader 选项物业名称默认描述图片字符串数组或对象数组。 指定字符串数组时,数组中的每个字符串都是图像文件的路径。 例如["/path/to/image", ...]当指定对象数组时,每个对象必须...

    详谈LABJS按需动态加载js文件

    JavaScript 工具,用来根据需要加载 JavaScript 文件,通过使用该工具可以提升页面的性能,避免加载不需用到的 JavaScript 文件,可以实现动态并行加载脚本文件,以及管理加载脚本文件的执行顺序。 简单示例 $LAB...

    bag.js:JS CSS 文件加载器 + 键值存储

    主要特点是: JS/CSS 和其他类型文件的并行加载和顺序执行使用 IndexedDB / WebSQL / localStorage - 大资产没有大小限制。 对象的 KV 存储,界面简单。 您可以使用具有不同存储选项的多个实例。 例如用于资产的 ...

    harmonyos2-loader:使用iframe的资源加载器

    使用非阻塞行为并行加载资源 避免延迟load和DOMContentLoaded事件 如果需要,即使在load事件之后也保留脚本执行顺序 基于可重用源代码(工厂字符串)构建持久模块化系统 目前,一个小的loadJSON.js独立助手显示了大...

    loadcomponent:用于 Salesforce Aura 的灵活 JS 和 CSS 静态资源文件加载器

    一个简单快速的 Salesforce Aura 组件,可用于以串行、并行或任何其他方式加载 JS 和 CSS 静态资源。 非托管包: https://login.salesforce.com/packaging/installPackage.apexp?p0=04tB000000017Gl ##Getting ...

    scriptLoader:一个在网页上加载javascript文件的小库

    并行加载脚本。 如果脚本无法加载,请提供回退。 加载所有脚本后运行回调。 如何使用 该库是具有两个参数的单个函数。 scriptLoader ( scriptsToLoad , onLoaded ) scriptsToLoad 是要加载的脚本数组。 ...

    ImagePreloader:依赖于Promises的图像预加载器的轻量级JavaScript实现

    它可以按顺序(一个接一个)加载它们,或并行加载(每个集合的第一个图像,然后每个集合的第二个图像...)。 这个想法很简单:使用.queue(array)方法将甲板(图像集合)添加到预加载器队列中。 此方法返回一个...

    HTML页面加载和解析流程详细介绍

    浏览器加载和渲染html的顺序 1. IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。 2. 在渲染到页面的某一部分时,其上面的所有...JS的加载 1. 不能并行下载和解析(阻塞下载)。 2. 当引

    sqs-bulk-loader:一组有助于按顺序或与AWS SQS并行发送批量消息的功能

    AWS SQS批量加载器一组功能,可帮助按顺序或与AWS SQS并行发送批量消息。如何安装npm install sqs-bulk-loader运行测试npm test 入门基本语法是: const { sendBatchedMessages , sendBatchedMessagesInParallel } =...

    charto-polymer-shim

    异步导入因此,如果用于导入Polymer,则两者都是并行加载的。 然后,当WebComponentsReady事件被触发时,Polymer可能已经捕获,也可能尚未捕获。 该填充程序首先加载webcomponents.js并捕获事件。 然后,它依次并...

    SugarCubesJS:响应式编程SugarCubes v5框架的Javascript实现

    它使用了FrédéricBOUSSINOT [Bo1]在90年代初提出的Frederic Boussinot的同步/React范例,并允许人们在顺序Javascript之上编写React并行/并发程序。 快速开始: 通过添加以下内容来加载SugarCubes.js库: &lt; ...

    routing:构建 SPA 应用程序的基础架构框架

    当捕获到url变化时,在保持执行顺序的情况下并行加载与新url模块相关CSS、JS和AJAX。 所有路由信息都存储在一个静态路由表中,包括CSS、JS文件和用于初始化模块的AJAX动作信息,大部分路由信息是可选的。 通常,...

    parallel-require:在Web APP中使用的需求异步模型的扩展

    奇葩场景我要并行加载一个main.js和一个jsonp数据data,但是运行顺序是:main.init()main.render(data)很显然,通常的require解决不了这个问题,所以就有了parallel-require。async-parallel并发地运行多个异步task...

    前端统计框架ALog.zip

    另外值得一提的是,ALog的模块文件不依赖加载顺序、兼容同步和异步加载。 2-2. 并行多个统计模块 3. ALog适合什么应用场景? 3-1. 简单统计 直接这页面中调用 3-2. 复杂统计 通过define定义统计模块 3-3. 代理统计 ...

Global site tag (gtag.js) - Google Analytics