WebスクロヌルABCブック

投皿者Nolan Lawson、Microsoft Edge Project Manager



スクロヌルは、Web䞊で最も叀い盞互䜜甚の1぀です。 プルトゥリフレッシュメ゜ッドず無限のダりンロヌドリストが登堎するずっず前に、控えめなスクロヌルバヌがWeb䞊のスケヌリングの元の問題を解決したした。利甚可胜な衚瀺領域を超えるコンテンツず察話する方法ですか。



今日、スクロヌルは䟝然ずしおWeb䞊で最も基本的な盞互䜜甚であり、おそらく最も誀解されおいたす。 たずえば、次のシナリオの違いを知っおいたすか





平均的なむンタヌネットナヌザヌたたは平均的なWeb開発者もに尋ねるず、これらのアクションは同等であるこずがわかりたす。 真実ははるかに興味深いです。



結局のずころ、これら5぀の入力メ゜ッドは、特にパフォヌマンスずブラりザヌ間の互換性の点で非垞に異なる特性を持っおいたす。 それらの䞀郚タッチスクリヌンのスクロヌルなどは、重いJavaScriptを䜿甚しおいるペヌゞでもおそらくスムヌズですが、他のキヌボヌドキヌボヌドからのスクロヌルなどからは同じペヌゞが遅れお応答しなくなりたす。 さらに、ある皮のスクロヌルはDOMむベントハンドラヌによっお遅くするこずができたすが、他の皮類はできたせん。 ここで䜕が起こっおいたすか



この質問に答え、サむトに最もスムヌズなスクロヌルを実装する方法を理解するために、ブラりザがマルチスレッドず入力をどのように凊理するかを理解し理解するために戻っおみたしょう。



マルチスレッドWeb



抂念的には、Webはシングルスレッド環境です。 JavaScriptはDOMをブロックし、DOMはJavaScriptをブロックしたす。これは、䞡方が同じスレッド倚くの堎合「メむンスレッド」たたは「UIスレッド」ず呌ばれるを争うためです。



たずえば、このひどいJavaScriptスニペットをペヌゞに远加するず、パフォヌマンスの䜎䞋がすぐにわかりたす。



setInterval(() => { var start = Date.now(); while (Date.now() - start < 500) {/* wheeeee! */} }, 1000);
      
      





このJavaScriptが無限ルヌプで回転しおいる間、ボタンは機胜せず、フォヌム芁玠は応答せず、アニメヌションGIFでさえ遅くなりたす。あらゆる意味で、ペヌゞがフリヌズしたす。 シンプルなデモで実際の効果を調べるこずができたす。







さらに、キヌボヌドの䞊䞋キヌを䜿甚しおペヌゞをスクロヌルしようずするず、JavaScriptの実行が停止するたでペヌゞが予枬どおりにスタックしたす。 これはすべお、Webをシングルスレッド環境ず芋なしおいるずいう明確な蚌拠です。



面癜い倉則がありたすタッチスクリヌンをスクロヌルしようずするず、JavaScriptはペヌゞ䞊の他のすべおをブロックしたすが、ペヌゞは完党に䞊䞋にスクロヌルしたす。 同じこずは、タッチパッド、マりスホむヌルからのスクロヌル、およびクリックアンドドラッグカヌ゜ルでペヌゞをキャプチャした埌のスクロヌルブラりザヌによっお異なりたすにも圓おはたりたす。



どういうわけか、䞀郚のスクロヌルアクションはペヌゞの状態を倉曎できたすが、他のすべおボタン、デヌタ入力フィヌルド、GIFは完党にフリヌズしたす。 これをシングルスレッドWeb理論ずどのように組み合わせるこずができたすか







2぀のスレッドの履歎



結局のずころ、䞀般に、「ブラりザヌはシングルスレッド」ずいう論文は正しいのですが、重芁な䟋倖がありたす。 スクロヌルは、その倚様性すべおにおいお、そのような䟋倖の1぀です。



長幎にわたり、ブラりザ開発者は、補助的な䜜業をバックグラりンドスレッドにアンロヌドするず、スムヌズな操䜜ず感床に倧きなメリットがもたらされるこずに気付きたした。 スクロヌルは䞻芁なブラりザ゚クスペリ゚ンスにずっお非垞に重芁であるため、このタスクはそのような最適化のためにすぐに遞択されたした。 珟圚、すべおの䞻芁なブラりザヌ゚ンゞンBlink、EdgeHTML、Gecko、WebKitは、実行のメむンスレッドの倖偎でのスクロヌルをある皋床サポヌトしおいたすFirefoxは、 Firefoxバヌゞョン46からクラブに参加した最埌の人です。



バックグラりンドスクロヌルでは、すべおのスクロヌルが個別のスレッドで実行されるため、ペヌゞが乱雑になっおもスムヌズにスクロヌルしたす。 スクロヌルに関係のない倖郚メカニズムを介しおペヌゞず察話しようずする堎合のみ-キヌを抌し、入力フィヌルドにデヌタを入力し、リンクをクリックしたす-ファサヌドがリセットされ、サロントリックの本質が完党に明らかになりたす。 うたくいくずすれば、これは玠晎らしいトリックです



確かに、非同期スクロヌルには、チェッカヌボヌド効果ず呌ばれる䞀般的な副䜜甚がありたす。 iOS甚のSafariで最初に登堎したのは、チェス盀のように灰色ず癜色のセルの圢でした。 最新のブラりザのほずんどでは、ブラりザがペヌゞをレンダリングできる速床よりも速くスクロヌルするず、画面䞊の空癜スペヌスずしお効果が珟れたす。 これは理想的ではありたせんが、ブロックされた、けいれんする、たたは応答しないスクロヌルず比范しお蚱容できる劥協です。







残念ながら、スクロヌルを実行のバックグラりンドスレッドに転送するこずは必ずしも容易ではありたせん。 ブラりザは、オペレヌティングシステムが同時入力を蚱可しおいる堎合にのみこれを行うこずができ、これはデバむスごずに異なる堎合がありたす。 特に、キヌボヌド入力はマりスやタッチデバむスの入力ほど最適化されおいないため、すべおのブラりザでキヌボヌドから入力する堎合、最終的には倧幅な遅延が発生したす。



ここでは、少し話が有益です。 WindowsやmacOSなどのオペレヌティングシステムが最初に登堎したずき、実行スレッドは1぀しか蚱可されおおらず、同時入力を提䟛する必芁性をほずんど予芋しおいたせんでした。 マルチコアマシンが登堎しお初めお、オペレヌティングシステムがアヌキテクチャに䞊列性を組み蟌み始めたした。



動物の初歩的な噚官が進化の歎史を理解できるように、りェブ䞊でスクロヌルする方法を芋るず、オペレヌティングシステムの単䞀スレッドの起源が珟れたす。 オペレヌティングシステムが、マりス、キヌボヌド、たたは他のデバむスからの䞊列入力を蚱可しおいる堎合にのみ、ブラりザは、実行のメむンスレッドを混乱させるJavaScriptの長時間の実行に圱響されないようにスクロヌルを効果的に最適化できたす。



ただし、Microsoft Edge開発チヌムでは、その方法に関係なく、スムヌズで応答性の高いスクロヌルを保蚌するために前進しおいたす。 EdgeHTML 14Windows 10 Anniversary Updateに含たれおいたでは、次のメ゜ッドのバックグラりンドスクロヌルをサポヌトしおいたす。





Edgeを他のデスクトップブラりザヌず比范するず、スクロヌルバヌを䜿甚した非同期スクロヌル、぀たり、マりスでスクロヌルバヌを抌したたた移動し、スクロヌルバヌたたは矢印をクリックするだけがサポヌトされおいるこずがわかりたす。 実際、発衚なしで、この機胜をAnniversary Updateで導入したした



Windows 1014393、Surface BookおよびmacOS Sierra10.12、MacBook Airのテスト結果によるず、次の結果が埗られたした。



2本指タッチパッド タッチ マりスホむヌル スクロヌルバヌ キヌボヌド
゚ッゞ14Windows ありたす ありたす ありたす ありたす いや
Chrome 56Windows ありたす ありたす ありたす いや いや
Firefox 51Windows いや いや いや いや いや
Chrome 56MacOS ありたす N / a ありたす いや いや
Firefox 51macOS ありたす N / a ありたす いや いや
Safari 10.1MacOS ありたす N / a ありたす いや いや


この衚が*を瀺しおいるように、スクロヌルの動䜜はブラりザヌごずに、さらにはOSごずに劇的に倉化したす。 1぀のブラりザのみで1぀のスクロヌル方法をテストするず、ナヌザヌが実際に操䜜する方法ず比范しお、サむトのパフォヌマンスの結果が非垞に䞍完党になりたす。



䞀般に、スクロヌルはWeb䞊で特別な堎所にあり、ブラりザが非垞に䞀生懞呜に動䜜しお、高速で受け入れやすいこずは明らかです。 ただし、Web開発者がブラりザベヌスの最適化を誀っお無効にできる埮劙な方法がありたす。 Web開発者がブラりザのスクロヌルに良い方法ず悪い方法で圱響を䞎える方法を芋おみたしょう。







リスニングプロセスがスクロヌルを劚げる方法



バックグラりンドスクロヌルにより、効率が倧幅に向䞊したす。スクロヌルずJavaScriptは完党に分離されおいるため、互いに干枉するこずなく䞊行しお動䜜できたす。



しかし、Webペヌゞを少し蚭蚈した人は誰でも、JavaScriptずスクロヌルを接続する方法を知っおいたす。



 window.addEventListener(“wheel”, function (e) { e.preventDefault(); // oh no you don't! });
      
      





event.preventDefault()



を呌び出すホむヌルリスニングプロセスを远加するず、マりスホむヌルずタッチパッドの䞡方のスクロヌルが100ブロックされたす。 そしお明らかに、スクロヌルがブロックされるず、バックグラりンドのスクロヌルもブロックされたす。



そのような䟋の効果はそれほど明癜ではありたせん



 window.addEventListener(“wheel”, function (e) { console.log('wheel!'); // innocent listener, not calling preventDefault() });
      
      





関数がpreventDefault()



呌び出さない堎合、スクロヌルをたったくブロックできないか、最悪の堎合は関数自䜓の期間だけスクロヌルをブロックできないずpreventDefault()



考えるかもしれたせん。 ただし、実際には、空のリスニングプロセスでさえ、このペヌゞのすべおのJavaScriptプロセスが完了するたでスクロヌルを完党にブロックしたす。 これは、 このデモで確認できたす。



マりスホむヌルをリッスンするこずは、倧きなブロッキングJavaScript操䜜ず盞互䜜甚したせんが、共通のむベントルヌプがあるため、バックグラりンドスレッドは、より長いJavaScript操䜜が完了するたで埅機しおから、むベントリスナヌから応答を受け取りたす。



なぜ圌は埅぀必芁がありたすか JavaScriptは動的なプログラミング蚀語であり、ブラりザヌはpreventDefault()



が呌び出されないこずを確信できたせん。 関数が単にconsole.log()



曞き蟌んでいるこずが開発者に明らかであっおも、ブラりザ開発者はチャンスを残さないこずを奜みたす。 実際、空のfunction() {}



でも同じ結果になりたす。



これはマりスホむヌルだけでなく、タッチデバむスでは、 touchstartたたはtouchmoveリスニングプロセスによっおスクロヌルをブロックするこずもできたす。



ペヌゞにリスナヌむベントを远加するずきは、パフォヌマンスに圱響するため泚意が必芁です。



スクロヌルJavaScript APIはいく぀かありたすが、スクロヌルはブロックされたせん。 スクロヌルむベントは倚少非論理的ですが、スクロヌル埌にブロックされないため、スクロヌル埌に起動され 、キャンセルされたせん。 たた、IEずMicrosoft Edgeで導入され、最近ChromeずFirefoxで導入された新しいPointer Events APIは 、元々、スクロヌルを誀っおブロックしないように蚭蚈されたした。



wheelたたはtouchstartむベントをリッスンする必芁がある堎合でも、Web開発者がスクロヌルが最高品質で機胜するこずを保蚌する方法には、いく぀かの秘trickがありたす。 これらのトリックのいく぀かを芋おみたしょう。







グロヌバルおよびロヌカルのリスニングプロセス



前の䟋では、グロヌバルリスニングプロセスのケヌスを芋たした぀たり、 りィンドりたたはドキュメントにアタッチされおいたす 。 しかし、個々のスクロヌル芁玠のリスニングプロセスに぀いおはどうでしょうか。



蚀い換えるず、スクロヌルは機胜するが、ペヌゞには独自の独立したスクロヌルを行う個別の領域があるペヌゞを想像しおください。 この領域でのみリスニングプロセスを远加するず、ブラりザはペヌゞ党䜓のスクロヌルをブロックしたすか



 document.getElementById('scrollableDiv') .addEventListener(“wheel”, function (e) { // In theory, I can only block scrolling on the div itself! });
      
      





簡単なデモペヌゞで確認するず、スクロヌルのリスニングプロセスが独立したスクロヌルのdivにある堎合、Microsoft EdgeずSafariはドキュメント党䜓のスムヌズなスクロヌルを残すこずに気付くでしょう。



ブラりザずその動䜜の衚は次のずおりです。



2本指タッチパッド タッチ マりスホむヌル クリックアンドドラッグ キヌボヌド
デスクトップ゚ッゞ14Windows ありたす ありたす ありたす ありたす いや
デスクトップChrome 56Windows いや ありたす いや いや いや
デスクトップFirefox 51Windows いや いや いや いや いや
デスクトップChrome 56MacOS いや N / a いや いや いや
デスクトップFirefox 51MacOS ありたす N / a ありたす いや いや
Safari 10.1MacOS ありたす N / a ありたす いや いや


結果は、これらのブラりザ機胜を掻甚するためにWeb開発者が利甚できる最適化があるこずを瀺しおいたす。 ドキュメント党䜓に察しおホむヌル/タッチリスニングプロセスを䜿甚する代わりに、リスニングプロセスをドキュメントの特定のサブセクションに远加しお、ペヌゞの他のすべおの郚分でスクロヌルがスムヌズに維持されるようにするこずをお勧めしたす。 ぀たり、ホむヌル/タッチスタヌトリスニングプロセスを可胜な限り最高レベルに委任するのではなく、必芁な芁玠のためにそれらを分離するのが最善です。



残念ながら、すべおのJavaScriptフレヌムワヌクでこの方法が蚱可されおいるわけではありたせん。特に、Reactは、ペヌゞの䞀郚にのみ適甚する堎合でも、ドキュメント党䜓にグロヌバルなリスニングプロセスを远加する傟向がありたす。 ただし、この問題専甚のオヌプンチケットがあり、Reactの担圓者は、プルリク゚ストを喜んで受け入れるず述べたした。  私たちの提案に非垞に迅速に反応したReactの人たちを尊重したす 







パッシブリスニングプロセス



ホむヌル/タッチスタヌトのグロヌバルリスニングプロセスを避けるこずは良い習慣ですが、達成しようずしおいる効果によっおは、䞍可胜な堎合もありたす。 たた、いく぀かの点で、単にPreventDefault()



を呌び出す可胜性があり、それを埅っおいるために、むベントをリッスンするだけでブラりザが党䞖界を停止するのは銬鹿げおいるように芋えたす。



幞いなこずに、Web開発者がリスニングプロセスを「パッシブ」ずしお明瀺的にマヌクし、埅機を回避できるようになったずきに、ブラりザヌに新しい機胜が衚瀺されるようになりたした。



 window.addEventListener(“wheel”, function (e) { // Not calling preventDefault()! }, { passive: true } // I pinkie-swear I won't call preventDefault() );
      
      





このアプロヌチでは、ブラりザはホむヌルリスニングプロセスが完党に存圚しないかのようにスクロヌルを凊理したす。 この機胜は、Chrome、Firefox、Safariの最新バヌゞョンで既に利甚可胜であり、Microsoft Edgeの将来のリリヌスですぐに利甚可胜になるはずです 。 パッシブリスニングプロセスを認識しないブラりザヌをサポヌトするには、 機胜怜出を䜿甚する必芁があるこずに泚意しおください。



䞀郚のむベント touchstartやtouchmoveを含むでは、バヌゞョン56のChromeが介入するこずを決定し、デフォルトでパッシブにしたした 。 リスニングプロセスを远加する堎合、ブラりザ間のこのわずかな違いに留意しおください







おわりに



これたで芋おきたように、Webでのスクロヌルは非垞に耇雑なプロセスであり、すべおのブラりザヌはパフォヌマンスを改善するさたざたな段階にありたす。 しかし、党䜓ずしお、Web開発者に明確なアドバむスを提䟛できたす。



たず、 ホむヌルたたはタッチリスナヌプロセスをグロヌバルドキュメントたたはりィンドりオブゞェクトに远加するのではなく、個々のスクロヌルで小さな芁玠に远加するのが最善です。 たた、開発者は、互換性の問題を回避するために、可胜であれば機胜怜出を䜿甚しお、パッシブリスニングプロセスを䜿甚する必芁がありたす。 ポむンタヌむベントそこにpolyfillがありたす を䜿甚し、 スクロヌルむベントをリッスンするこずも、䞍泚意でロックをスクロヌルするのを防ぐ確実な方法です。



この蚘事がWeb開発者に圹立぀ヒントを提䟛し、内郚のブラりザが䜕であるかを䞀目で芋られるこずを願っおいたす。 疑いもなく、ブラりザが進化し、りェブが成長するに぀れお、スクロヌルの仕組みはさらに耇雑で掗緎されたものになりたす。



Microsoft Edgeチヌムは、この分野で革新を続け、より倚くのサむトずナヌザヌにシヌムレスなスクロヌルを提䟛したす。 控えめなスクロヌルバヌ-Webで最も叀く、物議を醞しおいる盞互䜜甚に぀いおこれを考えおみたしょう



*結果は、2017幎2月に各ブラりザの最新バヌゞョンで取埗されたした。 それ以来、Firefox 52はスクロヌルのサポヌトを曎新し、スクロヌルバヌによるスクロヌルを陀くすべおのテストでEdge 14の動䜜ず䞀臎するようになりたした。 他のブラりザでもスクロヌルの実装が改善され、りェブがより速く、より圱響を受けやすくなるこずを願っおいたす



All Articles