信息谷 - ICITU
标题:
高性能JavcaScript(一)
[打印本页]
作者:
sxadmin
时间:
2021-10-25 10:25
标题:
高性能JavcaScript(一)
本系列是《高性能javascript》读书笔记和一些自己的思考整理,一共两篇,一来可以作为自己的总结;二来可以加深对知识的理解;三可以方便后期知识的整理。
第一章、加载和执行
1、将所有的</script>标签都放在<body>中,并放在末尾;
2、尽量减少</script>脚本的数量,相应速度将会更快;
3、无阻塞得秘诀在于,在页面娇在完成后才加载javascript代码。意味着在window对象的load事件触发后再下载脚本。
有多种无阻塞下载Javascript的方法:
使用标签的defer和async属性;
使用动态创建的</script>元素来下载并执行代码;
使用XHR对象加载Javascript代码并注入页面中。
推荐的无阻塞模式:
1、先添加动态加载所需的代码;
2、然后加载初始化页面所需的剩下的代码。
function loadScript(url, callback){
var script = document.createElement("script");
script.type = "text/javascript";
if(script.readyState){ // IE
script.onreadystatechange = function(){
if(script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
}else{ // FF, Chrome, Opera, ...
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
1、将下面的代码放在</body>闭合标签前面
<script type="text/javascript" src="load.js">
<script type="text/javascript">
loadScript("the-rest.js",function(){
Application.init();
});
</script>
上面的代码有两个优势:
a、确保不会阻塞脚本
b、当第二个js文件下载时需要的所有dom已经构建完毕,并做好了交互准备,避免需要另一个时间来检测页面是否准备好。
2、把loadScript()函数直接嵌入页面,从而避免多产生一次http请求。
<script type="text/javascript">
function loadScript(url, callback){
var script = document.createElement("script");
script.type = "text/javascript";
if(script.readyState){ // IE
script.onreadystatechange = function(){
if(script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
}else{ // FF, Chrome, Opera, ...
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
loadScript("the-rest.js",function(){
Application.init();
});
</script>
采用第二种方式,可以用YUI压缩代码。
第二章、数据存取
1、数据共有四种存储方式:字面量、变量、数组项和对象;
2、访问字面量和变量速度最快,因为全局变量总是存在于执行上下文作用域链的最末端,所以尽量用局部变量;
3、避免使用with语句和try-catch子句,因为会改变对象的作用域链,会使查找的层级变深,会对性能有影响;
闭包对性能的影响:
a、当外部函数创建时,闭包没变化;
b、当外部函数执行时,闭包被创建,并初始化为外部函数的活动对象;
c、当闭包执行时,创建执行上下文,闭包自身又创建一个活动对象。
若频繁访问闭包外部变量,可设置一个局部变量存储外部变量,减轻闭包对性能的损失。
4、避免嵌套,包括对象的嵌套和if-else的嵌套;
5、属性和方法在原型链中的位置越深,访问他的速度就越慢;
6、可以将常用的对象成员、数组、跨域变量保存在局部变量中来改善性能。
第三章、DOM编程
1、最小化DOM访问次数,尽量在JS端处理;
修改页面区域的最佳方案,即innerHTML对性能影响:webkit中DOM>innerHTML;非webkit中DOM<innerHTML.
2、如需访问某个DOM节点,使用局部变量保存其引用,获取DOM元素时,在IE中nextSibling比childNode表现优异,其他浏览器二者运行时间几乎相等,在所有浏览器中,children比childNodes要快,大约为1.5-3倍;
3、HTML集合类似数组,但只能用length方法和下标索引,无其他方法,小心使用;
4、使用速度最快的API,如querySelectororAll()和firstElementChild();
5、留意重绘和重排,离线操作DOM树,使用缓存,并减少访问儿女局部信息的次数;
重绘与重排过程
a、下载所有组件html、css、js、图片;
b、解析并生成DOM树和渲染树(隐藏的dom元素在渲染树中没有对应的节点);
c、绘制页面元素;
d、DOM变化影响了元素几何属性,导致重排
e、只要DOM发生变化,一定会重绘。
最小化重绘和重排方法:
a、cssText复制/追加,一次完成多次css赋值操作;
b、css的classname。
批量修改DOM:
(1)使元素脱离文档流
(2)对其应用多重改变
(3)把元素带回文档中
有三种方式可以使dom脱离文档:
a、隐藏元素,应用修改,重新显示;
b、使用文档片断在当前的DOM之外构建一个子树,再把它拷贝回文档;
c、将原始元素拷贝到一个脱离文档的节点,修改副本,完成后再替换原始元素。
6、动画中尽量使用绝对定位,使用拖放代理;
7、使用时间代理减少事件处理器的数量。
第四章、算法和流程控制
1、for-in性能较差于其余三种循环,只适合用于一个属性未知的集合;
2、尽量较少迭代的运算量和减少循环迭代次数;
3、通常switch比ifelse快,当判断条件较多时,使用查找表;
4、注意浏览器中的调用栈大小;
5、遇到栈溢出错误,讲方法改为迭代,或者使用Memoization来避免重复计算。
欢迎光临 信息谷 - ICITU (https://icitu.com/)
Powered by Discuz! X3.4