js并行加载,顺序执行
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并行加载,顺序执行的更多相关文章
- JS 动态加载脚本 执行回调
JS 动态加载脚本 执行回调 关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件 ...
- CSS样式表、JS脚本加载顺序与SpringMVC在URL路径中传参数与SpringMVC 拦截器
CSS样式表和JS脚本加载顺序 Css样式表文件要在<head>中先加载,这样网页显示时可以第一次就渲染出正确的布局和样式,网页就不会闪烁,或跳变 JS脚本尽可能放在<body> ...
- JS的加载和执行
从JS的加载和执行谈性能优化 ---高性能JS读后感(第一章) 从脚本的"霸道"说起,随着浏览器的进步,js越来越听话了,所以,我们先说说以前的浏览器是怎么加载js的,以及js如何 ...
- 性能优化-css,js的加载与执行
前端性能优化 css,js的加载与执行 javascript是单线程的 一个网站在浏览器是如何进行渲染的呢? html页面加载渲染的过程 html渲染过程的一些特点 顺序执行,并发加载 词法分析 并发 ...
- promise实现图片按照指定的加载顺序执行
promise实现图片按照指定的加载顺序执行,先加载第二张,再加载第一张,最后加载第三张 <!DOCTYPE html> <html lang="en"> ...
- JS 动态加载脚本 执行回调_转
关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件里面的函数是不会成功的.本文讲解 ...
- JS脚本加载与执行对性能的影响
高性能JavaScript-JS脚本加载与执行对性能的影响 在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 ...
- 前端性能优化 css和js的加载与执行
一个网站在浏览器端是如何进行渲染的? html本身首先会被渲染成 DOM 树,实际上 html 是最先通过网址请求过来的,请求过来之后,html 本身会由一个字节流转化成一个字符流,浏览器端拿的就是字 ...
- 【转】html、css、js文件加载顺序及执行情况
原链接:http://www.cnblogs.com/Walker-lyl/p/5262075.html 今天看书,看到html,css,js加载执行情况,发现自己并不是真正的了解,网上搜了半小时依然 ...
随机推荐
- centos 7 下面安装oracle 11g r2 过程分享
本人对LINUX等很多还不熟悉,如果有不对的地方还请各位指正.谢谢. 打算学习下ORACLE,RMAN备份与还原功能,所以安装了虚拟机,用的是centos7 X86_64-1611版本,oracle用 ...
- 文科生细谈学习Linux系统的重要性
首先大概介绍下自己,我学的是公共事业管理方面的专业,可以说是面向纯理论,社区管理社会管理的专业,但是从大二开始,对网络及服务器运维方面产生浓厚兴趣,并不断在网上找相关资料. 在这期间经历过很多,单说桌 ...
- 移动端APP页面Webview模式跳转详解
首先,来看一下关于Android home键和back键区别 back键 Android的程序无需刻意的去退出,当你一按下手机的back键的时候,系统会默认调用程序栈中最上层Activity的Dest ...
- IIS下防止mdb数据库被下载的实现方法
第一种方法:要求网站管理人员具体asp编程经验.因为现在的销售虚拟主机的系统,已经为用户建立了一个database目录,跟web目录同一个级别,用户访问的是web中的文件,而无法访问database目 ...
- 【技术干货】听阿里云CDN安防技术专家金九讲tengine+lua开发
一.介绍 二.安装 三.运行 四.开发 1.介绍 Tengine:轻量级.高性能.高并发.配置化.模块化.可扩展.可移植的Web和反向代理 服务器,Tengine是nginx超集,但做了很多优化,包含 ...
- Linux用户深度管理
linux系统是多任务.多用户的系统. 用户.用户组的概念 每个文件和进程,都需要对应一个用户和用户组. linux系统是通过UID和GID来是识别用户和组的. 其中用户名等同于人名(人类识别), ...
- seajs和requirejs对比;node初识
seajs 引包 载入主模块(seajs.use('./main')) 定义模块define(function(require,exports,module)) 模块化的好处 1.开发效率高 2.可以 ...
- Apache Kafka系列(四) 多线程Consumer方案
Apache Kafka系列(一) 起步 Apache Kafka系列(二) 命令行工具(CLI) Apache Kafka系列(三) Java API使用 Apache Kafka系列(四) 多线程 ...
- 如何快速禁用约束 (解决ORA-O2266问题)
业务场景: 某天truncate大量表时遇到错误ORA-O2266:表中的唯一/主键被启用的外键引用,不想看ER图来禁用大量复杂约束,所以研发了三种套路... 一. 最偷懒套路 如果要一次性导出很 ...
- Python下的OpenCV学习 01 —— 在Linux下安装OpenCV
一.OpenCV简要介绍 OpenCV是一个跨平台的计算机视觉库,可以运行在Windows.Linux.MacOS等操作系统上.OpenCV提供了众多语言的接口,其中就包含了Python,Python ...