⛸️

Observerを活用しScroll Eventから移行する。Vanilla Vue React別の実装コード

2024/11/15に公開

Observerの活用法:スクロールイベントとの比較と実装例

ウェブ開発において、ユーザーのスクロール操作に応じてヘッダーや他の要素を表示・非表示にすることは一般的なインタラクションの一つです。 しかし、スクロールイベントを直接使用すると、高頻度でイベントが発火し、パフォーマンスに悪影響を及ぼす可能性があります。

本記事では、スクロールイベントの課題と、Intersection Observer APIを活用したパフォーマンス最適化の手法について解説します。 また、バニラJavaScriptVue3Reactを使用した実装例を紹介し、それぞれのコードを詳しく説明します。

目次

スクロールイベントの課題

高頻度のイベント発火

良く使われる手法ながらも、スクロールイベントの潜在的な課題はどこにあるのでしょうか?

  • スクロールイベントは、ユーザーがスクロールするたびに何度も発火します
  • 1秒間に数十回から数百回のイベントが発生することもあり、メインスレッドに大きな負荷をかけます

パフォーマンスへの影響

  • イベントハンドラが頻繁に呼び出されると、CPU使用率が高くなり、ページのパフォーマンスが低下します
  • スクロールの滑らかさが失われ、ユーザーエクスペリエンスが悪化します

以下のサンプルでは、スクロールダウン時にヘッダーが非表示になり、スクロールアップ時にヘッダーが再表示される挙動を想定しています。

動作確認のため、CodePenを埋め込んで右下にログを出すようにしているので、スクロールしてみて実際に試してみてください。
従来型のスクロールイベント

※JavaScriptは「Babel」をクリックでコード詳細が見れます。「Result」でUI表示のToggleが可能です。

Intersection Observer APIの利点

効率的なイベント発火

  • Intersection Observerは、要素の可視状態が変化したときのみコールバックを発火します
  • 不要な計算を削減し、メインスレッドの負荷を軽減します

ブラウザによる最適化

  • ブラウザが内部的に最適化を行うため、パフォーマンスが向上します
  • 非同期処理により、メインスレッドをブロックしません

ユーザーエクスペリエンスの向上

  • スクロールが滑らかになり、快適な操作性を提供できます

スクロールイベントとの比較

特性 IntersectionObserver スクロールイベント
イベント発火頻度 必要なタイミングのみ スクロール時に常時発火(フレームごと)
負荷 監視対象の数に比例(ブラウザ最適化あり) イベント回数に比例(最適化なし)
柔軟性 特定の要素の可視状態を監視するのに適している スクロール全般の動作には便利
最適化の必要性 少ない(ただし対象要素が多い場合は注意) スロットリングやデバウンスが必須

実装例

バニラJavaScriptによる実装

「Babel」や「Result」をポチポチクリックしてUIとJavaScript内容を確認ください

Vue3による実装

Reactによる実装

Reactを使用した実装例はこちらを参照してください。


まとめ

  • スクロールイベントの課題: 高頻度のイベント発火によるパフォーマンス低下を防ぐ必要があります。
  • Intersection Observerの利点: 必要なタイミングで効率的に処理を行うことが可能です。

残課題

  • Observerはスクロール値自体は取得出来ないため、デザインの都合でなにか細かなインタラクションスクロール設計が必要になれば、ObserverとScroll Eventの組み合わせなど、さらに設計を発展させる必要があります。気をつけるべきはScroll Eventを安易に取り続けない事が重要です。

参考資料

Discussion