《高性能javascript》读书笔记--js脚本的加载与执行
来源:互联网 发布:男士搭配服装软件 编辑:程序博客网 时间:2024/06/05 19:24
第一章 加载与执行
JS在浏览器中的性能,可以认为是开放者面临的最重要可用性问题。
JS的阻塞性————多数浏览器使用单一进程处理UI和脚本,意味着<script>标签的出现会让页面等待脚本的执行(内嵌和外链),脚本执行时间越长,浏览器响应越慢。
1. 脚本位置
html规范指出<script>标签可以放在<head>或者<body>中,并允许出现多次。理论上讲,在<head>中加载JS和CSS,有助于确保页面和交互的正确性。
目前的浏览器基本都允许并行下载,外部资源同时下载,但是依然会阻塞其他资源的下载,比如图片,如图1所示,图片资源在js下载完成后才开始下载。
图1 资源的加载
尽管脚本下载过程不会相互影响,但仍需要等待所有js下载完才可以继续,尽管允许并行下载,但脚本阻塞仍然是一个问题。
因此,书中提到雅虎特别性能小组提出优化js的首要规则:将脚本放在底部。
然而,将script放在尾部的缺点,是浏览器只能先解析完整个HTML页面,再下载JS。而对于一些高度依赖于JS的网页,就会显得慢了,所以将script放在尾部也不是最优解,第3部分的无阻塞脚本会提到。
*浏览器的并行下载机制:
1)图片、js、css都属于静态资源,可以并行下载
2)浏览器并不是严格地按照顺序下载静态资源,它会根据优先级来安排下载顺序。
http1.1协议下的并行数量限制:
IE6:2个;
IE7:4个;
IE8+:6个
FireFox,Chrome:6个。
补充:同一时间针对同一域名下的请求有一定数量限制,超过限制数目的请求会被阻塞。大多数浏览器的并发数量都控制在6以内。有些资源的请求时间很长,因而会阻塞其他资源的请求。因此,对于一些静态资源,如果放到不同的域名下面就能实现与其他资源的并发请求。
2. 组织脚本
由于每个script标签初始下载时会阻塞页面渲染,所有要减少页面<script>标签数量。这不仅针对外链脚本,内嵌脚本数量也要限制。因此,常用的方法是将多个文件合并成一个,减少请求次数。
3. 无阻塞脚本
减少js文件大小并限制http请求次数仅仅是创建响应迅速的web应用第一步。当功能丰富,代码庞大的时候,精简代码,减少个数可能并不适合,因为庞大的单个js文件虽然只产生一次请求,但却会锁死浏览器相当大的时间。一些处理方法:
1)延迟脚本defer
先下载,不立即执行,直到DOM加载完(onload事件触发前)。
其中,a.js输出“defer”,b.js输出“normal”,结果是”normal”, “defer”, “load”。带有defer属性的<script>元素不是跟在第二后面执行的,而是在onload事件处理器执行前被调用。
另外,在支持H5的实现会忽略defer属性,因此把延迟脚本放在页底还是最佳的选择。
2)异步脚本async
H5点async属性与defer类似,区别在于执行的时机。async的执行比较混乱,不会在意<script>的顺序,加载完后就执行。如果项目中存在依赖关系,不推荐使用。
3)动态脚本
动态创建<script>元素加载js文件,文件在该元素被添加到页面时开始下载,返回的代码会立即执行。重点在于:无论何时启动下载,文件的下载和执行过程不会阻塞页面的其他进程。通常创建的新标签放在head里比较保险。
另外,为了确保没有问题,要跟踪脚本下载完成且准备就绪。
第一种,使用script.onload
第二种,readyState属性,五种状态:uninitialized初始状态,loading开始下载,loaded下载完成,interactive完成下载但不可用,complete准备就绪。常用loaded和complete。
var script = document.createElement("script"); script.type = "text/javacript"; script.src = "./b.js"; document.body.appendChild(script); function loadScript(url, callback){var script = document.createElement ("script");script.type = "text/javascript";if (script.readyState){ //IEscript.onreadystatechange = function(){if (script.readyState == "loaded" || script.readyState == "complete"){script.onreadystatechange = null;callback();}};} else { //Othersscript.onload = function(){callback();};}script.src = url;document.getElementsByTagName_r("head")[0].appendChild(script);}
可以尽可能多地动态加载,但是要考虑清楚顺序问题。所有可以使用串联调用的方法确保顺序,也可以合并后加载。
4)XMLHttpRequest脚本注入
该方法是先创建XHR对象,然后下载js文件,最后动态注入。和动态注入多区别在于,下载后不会立即执行,可以推迟到你准备就绪的时候,另外,兼容性较好。
局限在于,不能跨域请求,意味着js文件不能从cdn获取,因此大型应用一般不采用。
4. 小结
管理浏览器中的JS代码并不是一个简单的事情,因为阻塞问题会影响浏览器的进程。有几种方法可以减少JS对性能的影响:
1)将 <script>标签放于页底,确保脚本执行前页面已完成渲染
2)合并脚本。<script>标签越少,加载越快,响应越迅速
3)多种无阻塞下载JS的方法:
*使用<script>的defer和async属性
*使用动态创建<script>元素的方法
*使用XHR对象下载JS代码,并注入页面
- 《高性能javascript》读书笔记--js脚本的加载与执行
- 并行加载与顺序执行–《高性能javascript》读书笔记(jquery加载顺序)
- 《高性能 JavaScript》笔记(一):脚本加载和执行
- 【高性能 JavaScript --笔记】JavaScript 加载与执行
- 高性能javascript(一)加载与执行
- 高性能Javascript--脚本的无阻塞加载策略
- 高性能Javascript:脚本的无阻塞加载策略
- 高性能Javascript--脚本的无阻塞加载策略
- 高性能Javascript:脚本的无阻塞加载策略
- 高性能Javascript--脚本的无阻塞加载策略
- 高性能Javascript--脚本的无阻塞加载策略
- 高性能Javascript:脚本的无阻塞加载策略
- 高性能JavaScript:脚本的无阻塞加载策略
- 高性能Javascript:脚本的无阻塞加载策略
- 高性能Javascript--脚本的无阻塞加载策略
- 高性能JS--载入脚本并执行
- 高性能Javascript【一】加载和执行
- 高性能JavaScript---加载和执行
- 第一阶段-入门详细图文讲解tensorflow1.4 -安装(二)Windows CPU or GPU
- java的4种安全沙箱之ClassLoader双亲委派机制
- 在Linux中利用Service命令添加系统服务及开机自启动
- Error:Cannot locate factory for objects of type DefaultGradleConnector, as ConnectorServiceRegistry
- ffmpeg avfilter描述对应代码
- 《高性能javascript》读书笔记--js脚本的加载与执行
- ThinkPHP(字母函数)
- 【mysql 主从复制】掌握MySQL主从复制
- 网络名词解析
- 一种查询表详细属性的方法
- 用PHPStorm实现在本地实时编辑服务器端的代码
- JS实现效果-点击按钮返回到页面顶部
- 数据结构实验之查找三:树的种类统计
- PHP session 单双引号引发的重定向循环