高性能JavaScript DOMプログラミング(1)

4060 ワード

DOMはXMLとHTMLドキュメントを操作するためのアプリケーションインターフェースであり、シナリオでDOM操作すると高価であることを知っています.適切な比喩があります.DOMとJavaScriptはそれぞれ一つの島を想像しています.その間は有料の橋で接続しています.ECMAScriptは毎回DOMを訪問します.この橋を経由して、そして「橋を渡る費用」を納めて、DOMを訪問する回数が多いほど、費用も高くなります.そのため、橋を渡る回数をできるだけ減らして、ECMAScript島にいるようにするのがオススメです.DOMインターフェースを使わないわけにはいかないですが、どうやってプログラムの効率を上げることができますか?
1、DOMアクセスと修正DOM元素のアクセスは有料です(「橋を渡る費用」は分かります).元素の価格を修正するのはもっと高いです.それはブラウザがページの幾何学的変化(並べ替えと描き直し)を再計算することにつながるからです.
もちろん最悪の場合はループ中に要素にアクセスしたり、修正したりします.次の二つのコードを見てください.

var times = 15000;

// code1
console.time(1);
for(var i = 0; i < times; i++) {
 document.getElementById('myDiv1').innerHTML += 'a';
}
console.timeEnd(1);

// code2
console.time(2);
var str = '';
for(var i = 0; i < times; i++) {
 str += 'a';
}
document.getElementById('myDiv2').innerHTML = str;
console.timeEnd(2);

その結果、初めて運行する時間はなんと2回目の千倍になりました.(chromeバージョン44.0.2403.130 m)

1: 2846.700ms
2: 1.046ms
第一段コードの問題は、繰り返しのたびに、この要素は二回訪問されることです.一回はinnerHTMLの値を読み取り、もう一回はそれを書き直します.つまり、毎回循環して橋を渡っています.その結果,DOMへのアクセスが多くなり,コードの動作速度が遅くなることが十分に示された.したがって、DOM訪問の回数を減らすことができるなら、できるだけECMAScriptに残して処理します.
2、HTML集合&DOM操作DOMを遍歴するもう一つのエネルギー消費点はDOMを遍歴しています.一般的にはHTML集合を収集します.例えば、getElements ByTagName()を使ったり、document.linksを使ったりして、みんなはこれに慣れていないと思います.収集の結果は、同じ配列の集合であり、「リアルタイム状態」でリアルタイムに存在しています.これは、下の文書オブジェクトが更新されると自動的に更新されることを意味します.どう言いますか?簡単に栗を挙げます.


 
  • apple
  • orange
  • bana
  • &噫13;
    var lis=document.getElements ByTagName('li')&啱13;
    var peach=document.create Element('li')&啱13;
    peach.innerHTML='peach';13;
    Dcument.getElementById('fuit').apendChild(peach);13;
    &噫13;
    consolone.log(lis.length);/4&{13;
    これはまさに非効率の源です!簡単です.配列の最適化操作と同じで、length変数をキャッシュするとokです.
    
    console.time(0);
    var lis0 = document.getElementsByTagName('li');
    var str0 = '';
    for(var i = 0; i < lis0.length; i++) {
     str0 += lis0[i].innerHTML;
    }
    console.timeEnd(0);
    
    
    console.time(1);
    var lis1 = document.getElementsByTagName('li');
    var str1 = '';
    for(var i = 0, len = lis1.length; i < len; i++) {
     str1 += lis1[i].innerHTML;
    }
    console.timeEnd(1);
    
    
    性能の向上はどれぐらいありますか?
    
    0: 0.974ms
    1: 0.664ms
    
    集合の長さが大きい場合(デモは1000)、性能の向上は明らかである.
    「高性能JavaScript」は、もう一つの最適化戦略を提示しました.「行列を遍歴するのは集合より速いので、まず集合要素を配列にコピーすると、その属性にアクセスするのがより速い」と指摘しました.(疑義がありますので、私と交流して検討してください)
    
    console.time(1);
    var lis1 = document.getElementsByTagName('li');
    var str1 = '';
    for(var i = 0, len = lis1.length; i < len; i++) {
     str1 += lis1[i].innerHTML;
    }
    console.timeEnd(1);
    
    
    console.time(2);
    var lis2 = document.getElementsByTagName('li');
    var a = [];
    for(var i = 0, len = lis2.length; i < len; i++)
     a[i] = lis2[i];
    
    var str2 = '';
    for(var i = 0, len = a.length; i < len; i++) {
     str2 += a[i].innerHTML;
    }
    console.timeEnd(2);
    
    
    今回の最後に2つの原生DOM方法を紹介します.querySelector()とquerySelectorAll()はみんながよく知らないと信じています.前者は一つの配列に戻ります.後者はマッチの最初の要素に戻ります.いいですよね.すべての場合、その性能は前者のHTML集合より優れています.
    
    console.time(1);
    var lis1 = document.getElementsByTagName('li');
    console.timeEnd(1);
    
    console.time(2);
    var lis2 = document.querySelectorAll('li');
    console.timeEnd(2);
    
    // 1: 0.038ms
    // 2: 3.957ms
    
    しかし、CSSのような選択方法なので、グループ選択をする時には効率が上がり、便利です.たとえば、次のようなグループクエリを行います.
    
    var elements = document.querySelectorAll('#menu a');
    var elements = document.querySelectorAll('div.warning, div.notice');
    
    以上、高性能JavaScript DOMプログラミングのすべての内容について、理解していただきたいと思います.