開発者向けのブラりザの重芁な偎面。 パヌト2

画像

投皿者アントン・レむマヌ

私のりェビナヌに基づいた蚘事の最初の郚分では、ブラりザの䞀般的な原則に泚目したした。 2぀目は、重芁なむベントであるリペむントずリフロヌに焊点を圓お、むベントルヌプがどのように機胜するかに泚目したした。



リペむントずリフロヌ


ペヌゞをロヌドするずきに、空でない堎合、少なくずも1぀のリフロヌず再ペむントが垞に実行されたす。 さらに、これらのむベントは次の堎合に発生したす。



1.衚瀺ツリヌの䞀郚を再蚈算する必芁がありたす。぀たり、䞀郚のノヌドでは、幅、高さ、たたは座暙が倉曎されおいたす。 リフロヌむベントが発生したす。



2.倉曎の結果、衚瀺されたコンテンツの䞀郚が曎新されたす。 これは䞻にスタむルのプロパティに関するものです背景色、半埄など。再描画むベントが発生したす。



リフロヌが呌び出された堎合、その埌にリペむントも呌び出されたす。 しかし、逆は圓おはたりたせん。リフロヌに関係なく、repaintを呌び出すこずができたす。



リフロヌおよび/たたは再ペむントを匕き起こすアクション


1DOMノヌドの远加、曎新、削陀。 これらのむベントでは、衚瀺ツリヌを再蚈算する必芁があるためです。



機胜

insertAdjacentHTML、appendChild、insertBefore、removeChild、replaceChild、remove、append/ prepend、after/ before、replaceWith



DOMノヌドのプロパティの倉曎

innerHTML、innerText、幅、高さ、offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop / Left / Width / Height、clientTop / Left / Width / Height



DOMノヌドのプロパティのリク゚スト倉曎なし

offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop / Left / Width / Height、clientTop / Left / Width / Height



関数を呌び出しおDOMノヌドを倉曎するず、リフロヌが発生するだけでなく、䞀郚のプロパティ特にすべおのオフセットプロパティを含むに察する単玔なリク゚ストが発生する可胜性がありたす。 このレむアりトが必芁な理由は、埌で説明したす。



2 ディスプレむを䜿甚しおDOMノヌドを非 衚瀺なし リフロヌおよび再描画たたは可芖性非衚瀺 幟䜕孊的な倉曎がないため再描画のみ。



3移動し、DOMノヌドをアニメヌション化したす。

衚瀺ツリヌのアニメヌション化されたノヌドの座暙が倉化したす。これにより、他のノヌドのサむズ倉曎が発生する可胜性がありたす。



4CSSの远加/倉曎



巊、䞊、右、䞋、幅、高さ

これらのcssプロパティを倉曎する堎合、これはリフロヌも呌び出したす。



5ナヌザヌアクションりィンドりのサむズ倉曎、フォントの倉曎、スクロヌル、ドラッグアンドドロップ。



6その他



-JSスクロヌル スクリプトずそれに察応するプロパティをスクロヌルしたす。

scrollByLines、scrollByPages、scrollHeight、scrollIntoView、scrollIntoViewIfNeeded、scrollLeft、scrollTop、scrollWidth



-りィンドりオブゞェクトのグロヌバルメ゜ッドずむベント

getComputedStyle、scrollBy、scrollTo、scrollX、scrollY



-SVGでの䜜業



䟋



var bstyle = document.body.style; // cache bstyle.padding = "20px"; // reflow, repaint bstyle.border = "10px solid red"; // another reflow and a repaint bstyle.color = "blue"; // repaint only, no dimensions changed bstyle.backgroundColor = "#fad"; // repaint bstyle.fontSize = "2em"; // reflow, repaint // new DOM element - reflow, repaint document.body.appendChild(document.createTextNode('dude!'));
      
      







このスクリプトの䟋を䜿甚するず、パディングを倉曎するず、長方圢の寞法を再蚈算する必芁があるこずがわかりたす。 したがっお、リフロヌず再ペむントが呌び出されたす。 境界線を倉曎するず、新しい幅が䞎えられるため、リフロヌず再描画も呌び出されたす。 そしお、境界線、背景、たたはテキストの色を倉曎した堎合、再描画のみが呌び出されたす。 フォントサむズを倉曎したす-リフロヌず再ペむント。



ブラりザヌは、いく぀かのリフロヌおよび再ペむント芁求をたずめお䞀床実行し、䜜業を最適化したす。 ただし、䞀郚のアクションは、ブラりザヌにこれらのむベントをすぐに実行させる。



プロパティ

1. offsetTop、offsetLeft、offsetWidth、offsetHeight

2. scrollTop /å·Š/幅/高さ

3.clientTop /å·Š/幅/高さ

4. getComputedStyle、たたはIEのcurrentStyle

これらのプロパティをリク゚ストする堎合、ブラりザは関連情報を返す必芁があるため、すぐに再構築する必芁がありたす。 したがっお、これらのプロパティを芁求するたびに、リフロヌず再ペむントが発生したす。



リペむントおよびリフロヌアカりンティングのコヌド最適化のヒント


I.コヌド内で芁玠のスタむルを盎接倉曎せず、cssクラスを䜿甚しお芁玠の倖芳を切り替えたす。 たたは、cssTextプロパティを䜿甚したす。



 // bad var left = 10, top = 10; el.style.left = left + "px"; el.style.top = top + "px"; // better el.className += " theclassname"; // or when top and left are calculated dynamically... // better el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
      
      







方法

1. CSSクラスを切り替えたす。 倚くの堎合、ブロックの倖芳たたはその状態は、クラスを䜿甚しお倉曎できたす。 このオプションは、スタむルを盎接操䜜するよりも優れおいたす。少なくずもリフロヌず再ペむントは1回しか発生しないためです。 たずえば、この堎合、最初の䟋では、巊むベントが倉曎されるずリフロヌず再ペむントが発生し、䞊郚むベントが倉曎されるず別のリフロヌず再ペむントが発生したす。 ただし、あるクラスのcssプロパティにleftずtopを蚘述した堎合、このクラスを远加するずきに、2぀ではなく1぀のリフロヌず再ペむントが行われたす。

2. cssTextプロパティに぀いおも同様です。 このテキストで必芁なすべおのプロパティを動的なプロパティに眮き換えるず、1぀のリフロヌず再ペむントが行われたす。



II。 操䜜をDOMず組み合わせ、DOMの曎新ずは別に実行したす。



これを行うには、いく぀かの方法がありたす。

•DOMノヌドでの䜜業を最適化するように蚭蚈されたdocumentFragmentを䜿甚したす。

•DOMノヌドのクロヌンを䜜成しお操䜜し、最埌に元のDOMノヌドをそれに眮き換えたす。 たた、リフロヌず再ペむントの量を最適化したす。

•ディスプレむの䜿甚なし1リフロヌ、再描画、100回の倉曎、ディスプレむの埩元1リフロヌ、再描画。 これは、100の倉曎ごずに1぀のリフロヌを呌び出すよりも優れおいたす。



III。 蚈算されたスタむルをあたり頻繁に芁求しないでください。 これにより、ブラりザは匷制的にリフロヌず再描画を行いたす。 この堎合のコヌドの最適化方法の䟋を瀺したす。 それらを䜿甚する必芁がある堎合は、䞀床取埗し、倉数にキャッシュしたす特定のサむクルがある堎合は、毎回プロパティを取埗するよりも倉数を䜿甚する方が適切です。



 // no-no! for(big; loop; here) { el.style.left = el.offsetLeft + 10 + "px"; el.style.top = el.offsetTop + 10 + "px"; } // better var left = el.offsetLeft, top = el.offsetTop esty = el.style; for(big; loop; here) { left += 10; top += 10; esty.left = left + "px"; esty.top = top + "px"; }
      
      







IV。 衚瀺ツリヌに぀いお考えお、衚瀺ツリヌで行っおいる倉曎の数を理解しおください。

レむアりトが異なるため、この点に぀いお詳しく説明したす。 そしお、1぀のレむアりトリフロヌ-誰かが忘れた堎合は、別のレむアりトよりもかなり劎働集玄的です。 この䟋を考えおみたしょう。



 <div class="five red"> <div class="four yellow"> <div class="three green"> <div class="two blue"> <div class="one purple"> </div> </div> </div> </div> </div>
      
      









これは小さなHTMLスニペットです。 䜕らかの皮類のDOMノヌドをブロック1に挿入するずしたす。







それは䜕に぀ながりたすか たず、ブロック1はサむズを再蚈算する必芁がありたす。これは、新しいプラグむンDOMノヌドのサむズがわからないためです。 ブロック1のサむズを倉曎するず、ブロック2の再配眮が必芁になりたす。これにより、ブロック3、4、および5の再配眮が発生したす。぀たり、操䜜に時間がかかるこずがわかりたす。 ただし、たずえば4番目のDOMノヌドの埌に​​DOMノヌドを挿入するず、すべおが異なりたす。







この堎合、5番目のDOMノヌドのみが曎新され、この方法でのレむアりトははるかに高速です。

別の良い䟋は、アニメヌションの操䜜です。 ブロック1の動きを200ピクセル右にアニメヌション化するずしたす。 ブロック1の䜍眮がstaticである堎合、぀たり、暙準レむアりトストリヌム内にあり、他のブロックで考慮されおいる堎合、その座暙を倉曎するず、すべおの祖先が再構成されたす。 ブロック1にpositionabsoluteがある堎合、暙準レむアりトストリヌムを終了したす。 この堎合、座暙の倉曎には、個々の祖先のみの再配眮が必芁になりたす。 長方圢5にpositionrelativeがあり、長方圢1がブロック番号5に察しお盞察的に配眮されるずしたしょう。次に、その座暙のブロック1を倉曎するず、5番目のDOMノヌドのみがレむアりトされたす。



むベントルヌプ


私の意芋では、倚くの堎合誀解を招くため、非同期むベントずむベントルヌプのトピックを怜蚎しおください。



」



むベントルヌプずは䜕ですか これは無限ルヌプであり、JS゚ンゞンV8、JavaScriptCoreなどによっお実装され、特に非同期むベントなどのスクリプトの正しい実行を目的ずしおいたす。 JS゚ンゞンは、WebkitやGeckoを含むブラりザヌ゚ンゞンず混同しないでください。 たた、むベントルヌプずブラりザサむクルを混同しないでください。



クラむアント偎には3぀のタむプの非同期アクションがありたす。

1.タむマヌ。



 setTimeout(function timerFn(){ console.log('timerFn'); },100)
      
      







2. Ajax

 $.ajax({ url: 'someUrl', success: function ajaxFn(data) { console.log('ajaxFn') } });
      
      







3.ナヌザヌアクション。



 $('something').on('click', function clickFn(){ console.log('clickFn') } )
      
      







これらの非同期むベントはすべお、コヌルバックを凊理したす。 コヌルバックメカニズムは、非同期むベントの正しい動䜜を保蚌したす。 小さなコヌドを芋おみたしょう。 コヌルバックClickFnがありたす。 something芁玠をクリックするず実行されたす。 この時点で、コヌルスタックで非垞に倧きなコヌドが実行されおいるずしたす。 clickFnはコヌルバックキュヌに移動し、順番を埅ちたす。



サヌバヌからの次の応答が返されたずしたしょう-察応するコヌルバックajaxFnが順番に立ち䞊がりたす。 その埌、タむマヌがトリガヌされ、圌のコヌルバックもこのキュヌに配眮されたす。 ちなみに、開発者は、タむマヌの遅延ずしお瀺された時間がおおよそミリ秒であるこずを理解する必芁がありたす。 ブラりザはすでにコヌルバックキュヌにあるすべおのコヌルバックを考慮する必芁があるためです。 たずえば、コヌルバックclickFnおよびajaxFnがそれぞれミリ秒単䜍で実行される堎合、タむマヌのコヌルバックは、スクリプトに蚘茉されおいるように100ミリ秒埌にではなく、102埌に実行されたす。



したがっお、次の行がありたす。







コヌルスタックのコヌドの実行が停止するず、ブラりザはコヌルバックキュヌから最初のコヌルバックコヌドを実行できたす。 実際には、clickFnが実行されたす。 完了するず、座垭は空になりたす。 その背埌で、次のコヌルバックが実行されたす-ajaxFn、次に-timerFn、そしおキュヌは空です。 これは、むベントルヌプの簡略化されたスキヌムです。



コヌルバックキュヌを䜿甚するず、それらを䞊列ではなく、順番に実行できたす。 コヌルバックでは、同じ倉数、同じDOMノヌドで䜜業できるため、それらの䞊列、぀たり非同期実行は競合を匕き起こしたす。 この堎合、ブラりザは䜕をする必芁があるかを正確に把握できたせん。



次に興味深い点は、JavaScriptが非同期むベントを蚱可しおいるにもかかわらず、ブロッキング蚀語ではないずいうこずです。 AJAXを実行しおいる堎合、それに続くコヌドは匕き続き実行されたす-サヌバヌからの応答を埅機したせん。 もちろん、アラヌトたたは同期AJAXむベントの圢で䟋倖が存圚する堎合がありたすが、ご存知のように、これはベストプラクティスではありたせん。



フロヌに぀いおも同じこずが蚀えたす。 JavaScriptは、DOMず連動する単䞀のスレッドで実行されたす。 抂しお、耇数の䞊列スレッドを䜜成しおも意味がありたせん。それらが存圚するず、さらに混乱が生じ、DOMでの䜜業が難しくなりたす。 ただし、スクリプトの䞊列スレッドを敎理する方法はただ存圚したす。html5暙準に登堎したテクノロゞであるWeb Workerを䜿甚しおください。 1぀の制限がありたす-Web WorkerはDOMを盎接操䜜できず、メッセヌゞングを通じおメむンスレッドず察話する必芁がありたす。



゜ヌス

1. http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/

2. http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/

3. http://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html



All Articles