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加载执行情况,发现自己并不是真正的了解,网上搜了半小时依然 ...
随机推荐
- python函数(6):内置函数和匿名函数
我们学了这么多关于函数的知识基本都是自己定义自己使用,那么我们之前用的一些函数并不是我们自己定义的比如说print(),len(),type()等等,它们是哪来的呢? 一.内置函数 由python内部 ...
- python列表反转
使用reverse来让列表反转特别方便, 没事自己写了几种方式 In [59]: def reverse(nums): length = len(nums) for i in range(length ...
- Samba服务部署
Samba,是种用来让UNIX系列的操作系统与微软Windows操作系统的SMB/CIFS(Server Message Block/Common Internet File System)网络协议做 ...
- 表达式求值(栈方法/C++语言描述)(一)
一个算数表达式(以下简称为表达式)由运算数.运算符.左括号和右括号组成,定义一个枚举类型TokenType表示为: typedef enum { BEGIN, NUMBER, OPERATOR, LE ...
- CSS属性定义 文本修饰 边框效果 背景修饰
一.CSS属性定义1.css颜色表示方法[重点]rgb(红绿蓝3个颜色通道 强度值为0-255)rgb(0,0,0)rgba(alpha a是透明度 值为0-1)rgba(123,123,123,0) ...
- GDB教程
GDB是一个由GNU开源组织发布的.UNIX/LINUX操作系统下的.基于命令行的.功能强大的程序调试工具. GDB中的命令固然很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调 ...
- 关于Uncaught SyntaxError: Unexpected token o in JSON at position 1,chrome持续报错的相关解析
今天跟大家分享我前两天遇见的一个BUG,说出来很难受,因为这个BUG花了我一个多小时去找原因,后来莫名其妙的故障消失了,强迫症犯了的我,居然花了2个多小时去故意再制造这个BUG,只想弄明白WHY??? ...
- python-----运算符及while循环
一.运算符 计算机可以进行的运算有很多种,不只是加减乘除,它和我们人脑一样,也可以做很多运算. 种类:算术运算,比较运算,逻辑运算,赋值运算,成员运算,身份运算,位运算,今天我们先了解前四个. 算术运 ...
- 前端应该知道的Web Components
前端组件化的痛点 在前端组件化横行的今天,确实极大的提升了开发效率.不过有一个问题不得不被重视,拟引入的这些html.css.js代码有可能对你的其他代码造成影响. 虽然我们可以通过命名空间.闭包等一 ...
- 新入门的小白,整理一下特别简单实用的div+css兼容性的问题。
最近整理了一下特别简单的div+css的不同浏览器的兼容性的问题,跟大家分享一下,只适合刚入门的新手,欢迎大牛们给提出意见. 1. 默认的内外边距不同 问题: 各个浏览器默认的内外边距不同 解决: * ...