DOM 优化

xiaoxiao2021-02-27  477

前端性能优化之 DOM 与 JS

什么是 DOM? DOM 就是用于操作 xml 和 html 文档的应用程序,浏览器会把 DOM 和 JS 独立实现。

JS 操作 DOM 就像是从一个岛到了另一个岛,岛与岛之间的桥,每次通过都是要收取过桥费的,所以我们要尽量减少过桥的次数,意思就是说能在独立的岛上去完成的,就在独立的岛上去做,避免跨“岛”操作。减少 DOM 与 JS 的交互,可以大大提高浏览器的性能。

使用缓存

<script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementById('div1'); var str = ''; //未使用缓存 console.time('hello'); for(var i=0; i<5000; i++){ oDiv.innerHTML += 'A'; } console.timeEnd('hello'); //使用缓存 console.time('hello'); for(var i=0; i<5000; i++){ str += 'A'; } oDiv.innerHTML = str; console.timeEnd('hello'); } </script>

通过测试可以发现:使用缓存可以大大提高浏览器的性能。


innerHTML 和 DOM 方法对比

<body> <ul id="ul1"></ul> <script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementById('ul1'); var str = ''; //DOM 方法 console.time('hello'); for(var i=0; i<5000; i++){ var oLi = document.createElement('li'); oDiv.appendChild(oLi); } console.timeEnd('hello'); //innerHTML 方法 console.time('hello'); for(var i=0; i<5000; i++){ str += '<li></li>'; } oDiv.innerHTML = str; console.timeEnd('hello'); /** * chrome : ( */ } </script> </body>

通过测试可以发现:webkit 内核的浏览器 DOM 方法要比 innerHTML 方法的性能要好,其他的浏览器则相反,所以这个时候你就要根据你的用户量有针对性的去做选择。


节点克隆

<body> <ul id="ul1"></ul> <script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementById('ul1'); var str = ''; //未使用节点克隆 console.time('hello'); for(var i=0; i<5000; i++){ var oLi = document.createElement('li'); oLi.innerHTML = 'li'; oDiv.appendChild(oLi); } console.timeEnd('hello'); //使用节点克隆 console.time('hello'); var oLi = document.createElement('li'); oLi.innerHTML = 'li'; for(var i=0; i<5000; i++){ var newLi = oLi.cloneNode(true); oDiv.appendChild(newLi); } console.timeEnd('hello'); } </script> </body>

通过测试可以发先:使用节点克隆可以大大提高浏览器的性能


访问元素集合尽量用局部变量

<body> <ul id="ul1"> </ul> <script type="text/javascript"> window.onload = function(){ var oUl = document.getElementById('ul1'); var aLi = oUl.getElementsByTagName('li'); for(var i=0; i<5000; i++){ var oLi = document.createElement('li'); oUl.appendChild(oLi); } //未使用局部变量 console.time('hello'); //这个操作里面比较影响性能的就是 aLi.length 原因就 //是 for 循环的时候你每次都要重新获取其长度,这就是 //频繁的 DOM 操作,所以说我们要把它变成一个局部变量。 //对一个变量进行循环,不会涉及到多次的 DOM 操作,性能 //就会好一些 for(var i=0; i<aLi.length; i++){ aLi[i].innerHTML = i; } console.timeEnd('hello'); //使用局部变量 console.time('hello'); var len = aLi.length; for(var i=0; i<len; i++){ aLi[i].innerHTML = i; } console.timeEnd('hello'); } </script> </body> //未使用局部变量 var oDiv = document.getElementById(''); var oInput = document.getElementById(''); var oUl = document.getElementById(''); //使用局部变量 var doc = document; var oDiv = doc.getElementById(''); var oInput = doc.getElementById(''); var oUl = doc.getElementById('');

通过测试可以发现:使用局部变量比未使用局部变量性能要高很多。


尽量用只获取元素的节点方法

childNodes;//不仅获取元素节点同时获取文本节点 children;//只会获取到元素节点 firstChild;//只会获取到元素节点 firstElementChild;//只会获取到元素节点

尽量用只获元素节点的方法可以提高浏览器的性能


使用新选择器

<body> <ul id="ul1"> <li>1111</li> <li>1111</li> <li>1111</li> <li>1111</li> </ul> <script type="text/javascript"> var oUl = document.getElementById('ul1'); var aLi = document.getElementsByTagName('li'); //上面的两句话可以用下面的一句话代替 var aLi = document.querySelectorAll('#ul1 li'); // ie 8 以下的浏览器不支持该属性 for(var i=0; i<aLi.length; i++){ aLi[i].style.color = 'red'; } </script> </body>

利用 querySelector ,querySelectorAll 这些新的选择器对性能的提升是很大的。


前端性能优化之 DOM 与 浏览器

页面渲染机制

重排:当你改变页面中元素大小的时候,浏览器在加载页面的时候就会发生重排。

重绘:当浏览器显示的内容改变的时候就会发生重绘。


添加顺序

<body> <ul id="ul1"></ul> <script type="text/javascript"> window.onload = function(){ var oUl = document.getElementById('ul1'); //添加操作在 appendChild 后,降低了性能 console.time('hello'); for(var i=0; i<5000; i++){ var aLi = document.createElement('li'); oUl.appendChild(aLi); aLi.innerHTML = 'LI'; } console.timeEnd('hello'); //添加操作在 appendChild 前,提供了性能 console.time('hello'); for(var i=0; i<5000; i++){ var aLi = document.createElement('li'); aLi.innerHTML = 'LI'; //当你在 append 之前添加的时候,减少了重排重绘 //的过程,提高了性能,我们尽量把一些操作放在添加的 //前面进行 oUl.appendChild(aLi); } console.timeEnd('hello'); } </script> </body>

cssText

利用 cssText 合并 DOM 操作,可以提高浏览器的性能。

<body> <ul id="ul1"></ul> <script type="text/javascript"> window.onload = function(){ var oUl = document.getElementById('ul1'); //没有进行合并 console.time('hello'); for(var i=0; i<5000; i++){ var aLi = document.createElement('li'); aLi.style.width = "100px"; aLi.style.height = "20px"; aLi.style.backgroundColor = 'red'; oUl.appendChild(aLi); } console.timeEnd('hello'); //进行了合并 console.time('hello'); for(var i=0; i<5000; i++){ var aLi = document.createElement('li'); aLi.style.cssText='width:100px;height:20px;background:red;'; oUl.appendChild(aLi); } console.timeEnd('hello'); } </script> </body>

缓存布局信息

<body> <div id="div1"></div> <script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementById('div1'); //这里就是缓存布局信息的方式 var L = oDiv.offsetLeft; var T = oDiv.offsetTop; //如果在函数中每次都要获取 offsetLeft 和 offsetTop //就会非常影响性能 setInterval(function(){ L++; T++; oDiv.style.left = L + 'px'; oDiv.style.top = T + 'px'; },30); } </script> </body>

使用文档碎片

<body> <ul id="ul1"></ul> <script type="text/javascript"> window.onload = function(){ console.time('hello'); var oUl = document.getElementById('ul1'); //创建一个文档碎片 var oFrag = document.createDocumentFragment(); for(var i=0; i<5000; i++){ var aLi = document.createElement('li'); //每次循环的时候都会向页面添加,就相当于 5000 次 //的重排和重绘的过程,所以我们在每次循环的时候, //把所有的东西都放到文档里面,然后一次性添加 oFrag.appendChild(aLi); } //使用文档碎片一次性添加 oUl.appendChild(oFrag); console.timeEnd('hello'); } </script> </body>

前端性能优化之 DOM 与 事件

前端性能优化之 DOM 与 前端模板

利用前端模板来对逻辑和视图进行更好的分离,页面的渲染和你的 JS 是分开进行的,这对大型的架构非常好。前端模板是 MVC 架构的基础。

转载请注明原文地址: https://www.6miu.com/read-1343.html

最新回复(0)