スクロールした際のパフォーマンスが悪い場合(スクロールがカクつく場合)にはpassive:true
の使用を検討しましょう。この記事ではイベントリスナーにpassive:trueというヒントを使うことで、スクロールをスムーズにする方法についてご説明します。
passive:trueの役割
passive:true
はevent.preventDefault();
という関数をイベント内で読んでいないことをブラウザに教えてあげるために使用します。
具体的には次のように使用します。
passive:trueの使用例
1 2 3 | document.addEventListener('wheel', event => { // 処理を記載 }, {passive: true}); |
event.preventDefault()
とはブラウザにデフォルトで登録されている処理を無効にする関数です。例えば、wheel
のイベントでpreventDefault
を呼ぶと、スクロールを無効化することができます。なぜスクロールにカクつきが発生するのか?
Javascriptはインタプリタ型のプログラミング言語なので、あらかじめ関数の中身に何が書いてあるのかを解析せず(コンパイルせず)、実際にその処理を実行した際に初めてその処理内容を理解します。そのため、event.preventDefault()の記載がリスナー内に存在するかを判定するには、その処理をすべて実行する必要があります。
ここで問題なのはリスナーに登録されている関数を実行している間、他の処理に待ちが発生してしまうことです。
リスナーの関数の中身が1行くらいなら特に処理時間もかからないため問題にはなりませんが、仮に1000行分の処理があった場合、スクロール中に長い待ちが発生し、結果としてスクロールがガタついたり、スクロール時の画面下の色飛びなどが発生します。
passive: trueのメリット
passive: trueを使ってevent.preventDefault()を関数内で使用していないことをブラウザに教えてあげます。するとブラウザは画面描写とリスナー内の関数の実行を切り離し、それぞれ非同期で処理するようになります。そのため、スクロール処理がスムーズになります。
1 2 3 | document.addEventListener('wheel', event => { // この関数内でevent.preventDefault()を呼んでいないことをブラウザに通知 }, {passive: true}); |
passive:trueが特に有効なイベント
wheelイベントの他にも次のイベントリスナーに使用すると大きな効果が見られます。
Chromeでpassive: trueを使うタイミングを確認
Chromeではリスナーにpassiveが推奨されているため、使用していないと次のワーニングがコンソール上に表示されます。
1 | [Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952 |
このワーニングが表示されたリスナー内で、event.preventDefault()
を使用していない場合はpassive: true
を導入しましょう。