看了 js高性能 这本动物书才知道这是进大厂必备书籍😥
本系列文章 遵循 三大步 - why,what,how
why?🤔
为什么 js 加载需要优化
多数浏览器使用单一进程来处理用户界面刷新和 js 脚本执行。
同一时刻只能做一件事
故而当使用多个 script 脚本标签的时候,无论是内嵌的还是外链的,
页面的下载个渲染必须停下来等待脚本执行完成。这是页面生存周期中的必要环节。
(这是书籍第一章开头的一段话,简单而清晰)
what😏
什么是 js加载优化
网页在加载 js 的时候,页面渲染和用户交互是完全被阻塞的,当js加载过久或
js加载个数过多的时候会引起界面无法响应,卡死,空白等体验性差的结果,
因此需要对JS 加载进行优化
😀how👇👇
1、脚本位置
- js目的 让静态界面能与用户之间有交互的行为。如果js不先执行,可能部分界面功能会不正常,因此有些js会放在head 标签中。
但不是所有js都放到 head。脚本放到head 会有明显的延迟感觉。并且会阻塞图片等其他资源的下载
尽量把前期不需要的js都放置到body 底部
这也是常见的 js 加载优化
<body>
<p></p>
<div></div>
....
<script type="text/javascript" src="xxx.js">
</script>
</body>
2、脚本文件的减少
- 几乎所有的网站都会加载许多js文件,即便是 简单的博客系统,也加载好几个js文件包括 css样式表
每个js请求都会发出 网络请求到响应,接着是执行和完成加载。
在这个过程中,如果有多个js文件,需要请求多次网络,有时候服务器如果处理得慢也会造成明显的卡顿
最简单的办法就是 合并多个小体积js文件,达到一次请求,多个下载
另外该书还提及 雅虎的处理方式:
一个 请求网络URL 会同时下载两个js文件
与上边的方式不同的是,该方式下的JS文件在服务器上是 独立的,但是 该URL 会使得服务器让 两个JS文件同时被请求下载。与合并有区别
3、动态添加js
- 既然可以通过 操作 dom 树节点来 添加div,p,a 等标签,那么 script 也是可以的,并且也能达到优化目的,因为我们可以自由地控制 js文件的
请求时机
- 但是有个问题,当过多使用这个方式的时候,如果某个js文件之间是有
依赖性
,即便是请求时机
可以控制,但是加载完毕时机
不可控,可能造成某个js文件比另一个js即便是先
请求网络,但是执行完毕时机
反而慢于后者,从而后者js在运行期间(可能是某个触发函数,例如 click)
报错
-还好该死的浏览器内核提供了 一个 load事件在脚本加载完成时候会被触发,可以自定义这个函数的功能来实现 依赖js文件之间的先后请求时机的顺序
function loadScript(url , callback){
var script = document.createElement("script")
script.type = "text/javascript";
//兼容IE
if(script.readyState){
script.onreadystatechange = function(){
if(script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
}else {
script.onload = function){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
(为什么 添加到 head标签? 该书简单的说添加到 head标签比添加到 body标签更保险)
具体原因 IE会抛出一个错误: http://www.nczonline.net/blog/2008/03/17/the-dreaded-operation-aborted-error
配置 链式调用的方法来解决 js 执行时机
loadScript("xxx.js",function(){
dosomething....
loadScript("xxx.js",function(){
dosomething....
loadScript("xxx.js",function(){
dosomething....
....
})
})
})
如果想控制 请求时机的同时,还想控制 加载时机(人类欲望无休止)
🙄
- 另一个动态JS 方法就是 使用 ajax方法。这种方法和以往发送 ajax请求数据的 代码是一样,此处不讲述。区别就是,服务器返回了一段 js代码(字符串数据类型),然后可以使用存储技术,或者存放在某个变量中进行保存。优点
不会立即执行js
,兼容性好,主流浏览器都支持
,可以推迟到自定义某个执行时机去执行代码
,缺点因为是 ajax请求,有跨域限制
4、无阻塞的加载
- script 有个 defer 属性 , 指明该脚本原意上是不会修改DOM,因此代码能安全的延迟执行。也就是 该属性会使得 script 加载的脚本 异步加载,并且是并行的加载,不会产生阻塞。
与 async H5标准新出的 属性相比,区别在于执行时机,
async 是加载完成后自动执行(立即),而defer是等待 页面完成后才执行
defer 能保证执行顺序,而 async 不能
网友评论