我在這嘗試兩個方面:-->DOM與jscss
-->DOM與瀏覽器html
(最近在秒味視頻上學到很多,哈哈哈)chrome
1、DOM與js瀏覽器
1.js與dom的交互問題緩存
頻繁的與dom交互,是一件浪費時間與金錢的事情,這就須要咱們儘可能改進本身的代碼,讓咱們想作的事情儘可能在js中作的差很少了在去跟dom打交道。 app
下面的小例子就說明了問題:dom
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset=utf-8> 5 <title>dom優化相關</title> 6 </head> 7 <style> 8 9 </style> 10 11 <body> 12 <div id="div1"></div> 13 <script> 14 window.onload = function(){ 15 var nDiv = document.getElementById('div1'); 16 var str = ''; 17 18 /*console.time("innerHTML10000個a所用的時間"); 19 //每次循環dom都與js交互,太浪費時間啦 20 for(var i=0;i<10000;i++){ 21 nDiv.innerHTML += 'a'; 22 } 23 console.timeEnd("innerHTML10000個a所用的時間");*/ 24 25 console.time("得到10000個a以後innerHTML所用的時間"); 26 //這種就減小了js與dom的交互,大量的循環只在js中實現 27 for(var i=0;i<10000;i++){ 28 str += 'a'; 29 } 30 nDiv.innerHTML = str; 31 console.timeEnd("得到10000個a以後innerHTML所用的時間"); 32 33 } 34 </script> 35 </body> 36 </html>
(在chrome下)函數
這個時間的對比仍是比較明顯的喔。 對了,這console.time()和console.timeEnd()還挺好用的吧,其實console 還有好多亮瞎人眼的方法,能夠自行google或百度腦補。佈局
<------STOP START------->:測試
寫到上面代碼時,用到了window.onload,而後這裏暫時說點別的,看下面的代碼:
1 function t(){ 2 alert("1") 3 } 4 function b(){ 5 alert("2") 6 } 7 window.onload =t ; 8 window.onload =b ;
對吧,這隻會alert('2')嘛,也就是說window.onload不能同時加載多個函數,後面的會覆蓋掉前面的。
那怎麼辦呢? 這有一個簡單易用的方法:
1 function t(){ 2 alert("1") 3 } 4 function b(){ 5 alert("2") 6 } 7 window.onload = function(){ 8 t(); 9 b(); 10 }
這樣就能夠1和2都彈窗了。
不過更加慶幸的是,咱們還有更好的方法來爲 一個事件指派多個處理程序了那就是addEventListener和attachEvent:
1 if(window.attachEvent){ 2 window.attachEvent('onload',function(){ 3 alert('ie1'); 4 }); 5 window.attachEvent('onload',function(){ 6 alert('ie2'); 7 }); 8 }else{ 9 window.addEventListener('load',function(){ 10 alert('1'); 11 }); 12 window.addEventListener('load',function(){ 13 alert('2'); 14 }); 15 }
就是ie中可能執行順序會有點不同而已啦。
<------STOP END------->
2.在於dom交互時innerHTML與dom方法(像appendChild()這樣的方法)之間的效率比較:
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset=utf-8> 5 <title>dom優化相關</title> 6 </head> 7 <style> 8 9 </style> 10 11 <body> 12 <div id="div1"></div> 13 <ul id="oul"></ul> 14 <script> 15 16 window.onload = function(){ 17 var UL = document.getElementById('oul'); 18 var str=''; 19 20 21 console.time('dom操做所用時間'); 22 for(var i=0;i<10000;i++){ 23 var LI = document.createElement('li'); 24 UL.appendChild(LI); 25 } 26 console.timeEnd('dom操做所用時間'); 27 28 console.time('innerHTML操做所用時間'); 29 for(var i=0;i<10000;i++){ 30 str += '<li></li>'; 31 } 32 UL.innerHTML = str; 33 console.timeEnd('innerHTML操做所用時間'); 34 } 35 36 37 38 </script> 39 </body> 40 </html>
下面是時間對比:
chrome:
FF:
奇異的事實證實兩個瀏覽器下都是dom方法運行速度比較快。在我之前的認知裏面兩個瀏覽器的表現不該該是一致的,感受ff下innerHTML應該會比dom快的。
此處也求高人指點。
3.咱們知道與dom相關的行爲都會牽扯到時間問題,那麼怎麼減小dom操做呢?
---->使用節點克隆
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset=utf-8> 5 <title>dom優化相關</title> 6 </head> 7 <style> 8 9 </style> 10 11 <body> 12 <div id="div1"></div> 13 <ul id="oul"></ul> 14 <script> 15 window.onload = function(){ 16 var UL = document.getElementById('oul'); 17 var str=''; 18 19 20 /*console.time('dom操做所用時間'); 21 for(var i=0;i<10000;i++){ 22 var LI = document.createElement('li'); 23 LI.innerHTML = 'li'; 24 UL.appendChild(LI); 25 } 26 console.timeEnd('dom操做所用時間');*/ 27 28 29 console.time('克隆節點所用時間'); 30 var LI = document.createElement('li'); 31 LI.innerHTML = 'li'; 32 for(var i=0;i<10000;i++){ 33 var newLi = LI.cloneNode(true); 34 UL.appendChild(LI); 35 } 36 console.timeEnd('克隆節點所用時間'); 37 38 39 } 40 41 42 43 </script> 44 </body> 45 </html>
雖然相差不大,可是仍是不同的:
chrome:
--->儘可能使用局部變量
下面兩種寫法也是會影響效率的,由於每次都要獲取aLi.length集合也是要代價的,保存成局部變量會好些那。
for(var i=0;i<aLi.length;i++){ aLi[i].innerHTML = 'li'; }
var len = aLi.length; for(var i=0;i<len;i++){ aLi[i].innerHTML = 'li'; }
在上面添加10000個節點例子中嘗試:
一樣的下面兩種寫法也是有區別的:
var Div = document.getElementById();
var LI = document.getElementById();
var Input = document.getElementById();
//改爲下面這樣會比較好
var doc = document;
var Div = doc.getElementById();
var LI = doc.getElementById();
var Input = doc.getElementById();
---->還有就是儘可能只是用獲取元素節點的方法:
childNodes -->元素節點、文本節點
children--> 元素節點
(利用querySelectorAll)
var oul = document.getElementById('uli');
var ali = oul.getElementById('li');
-->
var aLi = document.querySelectorAll('#uli li');
2、dom與瀏覽器
1.添加操做(儘可能在appendChild前添加操做)
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset=utf-8> 5 <title>dom優化相關</title> 6 </head> 7 <style> 8 #div1 { 9 width: 100px; 10 height: 100px; 11 background: red; 12 position: absolute; 13 } 14 </style> 15 16 <body> 17 <div id="div1"></div> 18 <ul id="oul"></ul> 19 <script> 20 window.onload = function(){ 21 var oul = document.getElementById('oul'); 22 23 console.time('dom操做時間'); 24 for(var i=0;i<10000;i++){ 25 var oli = document.createElement('li'); 26 //注意下面兩句的位置 27 //oul.appendChild(oli); 28 //oli.innerHTML = 'li'; 29 oli.innerHTML = 'li'; 30 oul.appendChild(oli); 31 32 } 33 } 34 console.timeEnd('dom操做時間'); 35 } 36 37 </script> 38 </body> 39 </html>
仍是有必定的差異喔,能夠本身動手試一下。
2.合併dom操做(利用cssText)
window.onload = function(){ var oul = document.getElementById('oul'); console.time('dom操做時間'); for(var i=0;i<10000;i++){ var oli = document.createElement('li'); //事實上咱們總覺得下面第二種方法會更好些,時間會更短,可是,分別在FF和chrome中測試的話,仍是有點奇妙的。(chrome中神奇的第二種更快些) oli.style.width = '100px'; oli.style.height = '100px'; oli.style.background = 'red'; //oli.style.cssText = 'width:100px;height:100px;background:red'; } console.timeEnd('dom操做時間'); }
3.緩存佈局信息:
window.onload = function(){
var oDiv = document.getElementById('div1');
var l = oDiv.offsetLeft;
var t = oDiv.offsetTop;
//setInterval(function(){
// oDiv.style.left = oDiv.offsetLeft + 1 + 'px';
// oDiv.style.top = oDiv.offsetTop + 1 + 'px';
//},30);
//把老是會用到的佈局信息緩存起來,這樣就不用老是頻繁的去訪問dom了
setInterval(function(){
l++;
t++;
oDiv.style.left = l + 1 + 'px';
oDiv.style.top = t + 1 + 'px';
},30);
}
我這裏通常測試時間都是在chrome下,有的ff或別的瀏覽器不必定會同樣喔,歡迎留言一塊兒鑽研。