首页 > 代码库 > javascript performence
javascript performence
1.将脚本放在底部
javascript是阻塞式的加载,如果先加载脚本,后面的dom都没有办法进行渲染,页面会是一片空白;
采用无阻塞下载javascript
a.使用<script>标签的defer属相
b.使用动态创建的<script>元素下载并执行元素
2.打包脚本,减少页面<script>标签
考虑到http请求会带来额外的性能开销,下载单个的100K的文件比下载5个20k的文件更快。所以尽量减少外链脚本的数量
3.定义局部变量
引擎首先从this开始查找局部变量,然后是函数参数,然后是本地定义的变量,最后遍历所有的全局变量
4.尽量少访问DOM操作
a.对于多次访问同一属性,建议存储到一个局部变量替代
//不好 var blah = document.getElementById(‘myID‘), blah2 = document.getElementById(‘myID2‘); //更好的做法 var doc = document, blah = doc.getElementById(‘myID‘), blah2 = doc.getElementById(‘myID2‘);
b.通过模板clone,替代createElement;(前提是创建一个模板元素)
var frag = document.createDocumentFragment(); for (var i = 0; i < 1000; i++) { var el = document.createElement(‘p‘); el.innerHTML = i; frag.appendChild(el); } document.body.appendChild(frag); //替换为: var frag = document.createDocumentFragment(); var pEl = document.getElementsByTagName(‘p‘)[0]; for (var i = 0; i < 1000; i++) { var el = pEl.cloneNode(false); el.innerHTML = i; frag.appendChild(el); } document.body.appendChild(frag);
c.通过firstChild和nextSibling替代childNodes遍历的元素
var nodes = element.childNodes; for (var i = 0, l = nodes.length; i < l; i++) { var node = nodes[i]; //…… } //更好的做法 var node = element.firstChild; while (node) { //…… node = node.nextSibling;
d.删除dom节点之前,一定要删除该节点上的注册事件,否则将会产生无法回收的内存
5.减少因DOM操作,引起的reflow和repaint
DOM操作会导致一些列的repaint和reflow操作。在一般浏览器中,repaint的速度远快于reflow的速度,所以要尽量避免reflow操作
应对方案:
a.使用容器存放临时变更,最后一次性更新到DOM
//不好的做法 for(var i=0;i<items.length;i++){ var item = document.createElement("li"); item.appendChild(document.createTextNode("Option"+i)); list.appendChild(item); } //好的做法 //使用容器存放临时变更,最后一次性更新到DOM var fragment =document.createDpcumentFragment(); for(var i=0;i<items.length;i++){ var item = document.createElement("li"); item.appendChild(document.createTextNode("Options"+i)); fragment.appendChild(item); } list.appendChild(fragment);
b.先将DOM节点删除或者隐藏,因为隐藏的节点不会触发reflow
list.style.display = "none"; for (var i=0; i < items.length; i++){ var item = document.createElement("li"); item.appendChild(document.createTextNode("Option " + i); list.appendChild(item); } list.style.display = "";
c.一次性修改样式属性
// 不好的做法 // 这种做法会触发多次重排 element.style.backgroundColor = "blue"; element.style.color = "red"; element.style.fontSize = "12em"; // 更好的做法是,把样式都放在一个class下 .newStyle { background-color: blue; color: red; font-size: 12em; } element.className = "newStyle";
6.DOM相同事件操作尽量采用事件托管
如果对ul下的所有li添加一个onclick,如果用for循环来实现这个操作的话,会多次操作DOM树,如果用事件托管,将onclick事件托管给父元素,只需要操作父元素即可。
7.尽量不要使用闭包,闭包不能释放被引用的变量,也会影响web性能
javascript performence