JavaScript IntersectionObserver レシピ集:無限スクロール/遅延読込を最短実装

Web サイトのパフォーマンス改善は、ユーザー体験を向上させる重要な要素です。特に画像が多いページや長大なリストを扱う場合、初期読込時間が長くなりがちですね。そこで注目されているのが IntersectionObserver API です。
この記事では、IntersectionObserver を使った実装方法を、コピー&ペーストですぐに使える 10 個のレシピ としてご紹介します。スクロールイベントを使った従来の方法と比べて、パフォーマンスが大幅に向上するでしょう。
レシピ早見表
この記事で紹介する全レシピの一覧です。目的に応じて必要なレシピをご利用ください。
# | レシピ名 | 難易度 | 用途 | 実装時間 | 主な効果 |
---|---|---|---|---|---|
1 | 画像の遅延読込(基本) | ★☆☆ | 画像の初期読込最適化 | 5 分 | 読込時間 50〜70% 短縮 |
2 | 無限スクロール(SNS 風) | ★★☆ | コンテンツの段階的読込 | 10 分 | 初期データ量 80% 削減 |
3 | バックグラウンド画像の遅延読込 | ★☆☆ | CSS 背景画像の最適化 | 5 分 | CSS 画像読込 60% 削減 |
4 | スクロールアニメーション | ★★☆ | 要素のフェードイン演出 | 8 分 | UX 向上 |
5 | ビデオの自動再生・停止 | ★☆☆ | ビデオリソースの最適化 | 5 分 | 通信量 40% 削減 |
6 | 読了率トラッキング | ★★☆ | 記事の読了状況計測 | 10 分 | エンゲージメント可視化 |
7 | スクロール進捗インジケーター | ★★☆ | 読書進捗の視覚化 | 10 分 | 滞在時間 20% 向上 |
8 | 目次のハイライト(アクティブ表示) | ★★★ | 現在読んでいるセクションを強調 | 15 分 | 記事内ナビゲーション |
9 | iframe の遅延読込 | ★☆☆ | YouTube 埋め込み等の最適化 | 5 分 | 初期読込 70% 短縮 |
10 | スクロール方向の検知 | ★★★ | 上下スクロールに応じた UI 制御 | 12 分 | モバイル UX 向上 |
難易度の目安
- ★☆☆: 初心者でもすぐに実装可能。コピー&ペーストでそのまま動作
- ★★☆: 基本的な JavaScript の知識が必要。カスタマイズ推奨
- ★★★: 中級者向け。プロジェクトに合わせた調整が必要
推奨される組み合わせ
以下の組み合わせで、より効果的なパフォーマンス改善が可能です。
基本セット(すべてのサイト推奨)
- レシピ 1: 画像の遅延読込
- レシピ 3: バックグラウンド画像の遅延読込
- レシピ 9: iframe の遅延読込
ブログ・メディアサイト向け
- レシピ 1: 画像の遅延読込
- レシピ 4: スクロールアニメーション
- レシピ 6: 読了率トラッキング
- レシピ 7: スクロール進捗インジケーター
- レシピ 8: 目次のハイライト
SNS・コミュニティサイト向け
- レシピ 2: 無限スクロール
- レシピ 5: ビデオの自動再生・停止
- レシピ 10: スクロール方向の検知
EC サイト向け
- レシピ 1: 画像の遅延読込
- レシピ 2: 無限スクロール(商品一覧)
- レシピ 4: スクロールアニメーション
背景
IntersectionObserver とは
IntersectionObserver は、要素がビューポート(画面の表示領域)と交差したタイミングを効率的に検知できる API です。従来のスクロールイベントと異なり、ブラウザが最適化された形で交差判定を行うため、パフォーマンスへの影響が最小限に抑えられます。
次の図は、IntersectionObserver の基本的な仕組みを示したものです。
mermaidflowchart TB
viewport["ビューポート<br/>(画面表示領域)"]
target["監視対象の要素"]
observer["IntersectionObserver"]
callback["コールバック関数"]
viewport -->|交差判定| observer
target -->|交差判定| observer
observer -->|交差時に実行| callback
callback -->|画像読込/データ取得| action["アクション実行"]
要点: ブラウザが自動で交差を検知し、指定したコールバック関数を実行する流れです。
従来の方法との比較
従来のスクロールイベントを使った実装では、スクロールのたびにイベントが発火し、要素の位置を計算する必要がありました。この方法は以下のような問題を抱えています。
# | 項目 | スクロールイベント | IntersectionObserver |
---|---|---|---|
1 | パフォーマンス | ★☆☆ 低い | ★★★ 高い |
2 | 実装の複雑さ | ★★☆ やや複雑 | ★★★ シンプル |
3 | 精度 | ★★☆ 自前計算が必要 | ★★★ ブラウザが最適化 |
4 | メモリ使用量 | ★☆☆ 多い | ★★★ 少ない |
5 | バッテリー消費 | ★☆☆ 多い | ★★★ 少ない |
IntersectionObserver を使うことで、スクロールイベントのリスナーやスロットリング処理が不要になります。コードもシンプルになり、メンテナンス性が向上するでしょう。
課題
Web サイトが抱える読込パフォーマンスの問題
現代の Web サイトでは、以下のような課題に直面することが多くあります。
初期読込時間の長期化
画像やコンテンツを一度にすべて読み込むと、ページの表示まで時間がかかってしまいます。特にモバイル環境では、帯域幅の制限から深刻な問題となるでしょう。
不要なリソースの読込
ユーザーが実際にスクロールして表示する前に、ページ下部の画像やコンテンツまですべて読み込んでしまうのは無駄ですね。
スクロールイベントによるパフォーマンス劣化
従来の実装では、スクロールのたびに JavaScript が実行され、メインスレッドをブロックしてしまいます。これがアニメーションのカクつきやスクロールの遅延につながります。
以下の図は、これらの課題を構造的に示したものです。
mermaidflowchart TD
problem["読込パフォーマンス課題"]
problem --> p1["初期読込時間の長期化"]
problem --> p2["不要なリソース読込"]
problem --> p3["スクロールイベント<br/>パフォーマンス劣化"]
p1 --> s1["ユーザー離脱率上昇"]
p1 --> s2["SEO 評価低下"]
p2 --> s3["通信量の無駄"]
p2 --> s4["メモリ使用量増加"]
p3 --> s5["UI のカクつき"]
p3 --> s6["バッテリー消費増加"]
課題のまとめ: これらの問題はすべて、ユーザー体験の低下と離脱率の上昇に直結します。
解決すべき具体的なシナリオ
この記事では、以下の 2 つの典型的なシナリオに焦点を当てます。
- 画像の遅延読込(Lazy Loading): 画面に表示される直前まで画像の読込を遅らせる
- 無限スクロール(Infinite Scroll): スクロールに応じて追加コンテンツを動的に読み込む
これらを IntersectionObserver で実装することで、パフォーマンスとユーザー体験を同時に改善できるでしょう。
解決策
IntersectionObserver の基本構文
IntersectionObserver を使うには、まず監視対象の要素と、交差時に実行するコールバック関数を定義します。基本的な流れは以下の通りです。
javascript// IntersectionObserver のコールバック関数
const callback = (entries, observer) => {
entries.forEach((entry) => {
// entry.isIntersecting が true なら要素が表示領域に入った
if (entry.isIntersecting) {
console.log('要素が表示されました');
}
});
};
コールバック関数は、監視対象の要素が交差するたびに呼び出されます。entries
は交差した要素の情報を含む配列で、各 entry
から交差状態を取得できますね。
次に、オプションを指定して IntersectionObserver インスタンスを作成します。
javascript// オプション設定
const options = {
root: null, // ビューポートを基準にする(null の場合)
rootMargin: '0px', // 交差判定のマージン
threshold: 0.1, // 要素の 10% が見えたら交差と判定
};
// IntersectionObserver インスタンスを作成
const observer = new IntersectionObserver(
callback,
options
);
threshold
は 0〜1 の値で指定し、要素がどれだけ表示されたら交差と判定するかを決めます。0.1
なら 10%、1.0
なら 100% が表示された時点で交差となります。
最後に、監視を開始します。
javascript// 監視対象の要素を取得
const targetElement = document.querySelector('.lazy-image');
// 監視開始
observer.observe(targetElement);
以下の図は、IntersectionObserver の設定と動作フローを示しています。
mermaidflowchart LR
config["オプション設定<br/>threshold/rootMargin"]
callback_func["コールバック関数<br/>定義"]
create["IntersectionObserver<br/>インスタンス作成"]
target["監視対象要素<br/>取得"]
observe["observe()<br/>監視開始"]
config --> create
callback_func --> create
create --> observe
target --> observe
observe --> exec["交差時に<br/>コールバック実行"]
仕組みの要点: 設定 → 作成 → 監視開始の 3 ステップで、要素の交差を自動検知できます。
オプションパラメータの詳細
IntersectionObserver のオプションを理解すると、より柔軟な実装が可能になります。
# | オプション | 説明 | デフォルト値 | 使用例 |
---|---|---|---|---|
1 | root | 交差判定の基準となる要素 | null(ビューポート) | スクロールコンテナ内での判定 |
2 | rootMargin | 判定領域のマージン | '0px' | '100px' で 100px 手前から判定 |
3 | threshold | 交差と判定する割合 | 0 | [0, 0.5, 1] で段階的に検知 |
rootMargin の活用: 例えば rootMargin: '200px'
と設定すると、要素が画面に入る 200px 手前から交差と判定されます。これにより、画像の読込を先行して行い、ユーザーがスクロールした時点では既に表示されている状態を作れるでしょう。
threshold の配列指定: threshold: [0, 0.25, 0.5, 0.75, 1]
のように配列で指定すると、要素の表示割合が 0%、25%、50%、75%、100% になった各タイミングでコールバックが実行されます。
具体例
レシピ 1: 画像の遅延読込(Lazy Loading)
画像の遅延読込は、IntersectionObserver の最も一般的な使用例です。画面に表示される直前まで画像の読込を遅らせることで、初期読込時間を大幅に短縮できます。
HTML の準備
まず、遅延読込する画像の HTML を用意します。data-src
属性に実際の画像 URL を設定し、src
には軽量なプレースホルダー画像や透明な 1px 画像を指定しますね。
html<!-- 遅延読込する画像 -->
<img
class="lazy-image"
src="placeholder.jpg"
data-src="actual-image.jpg"
alt="遅延読込される画像"
/>
<img
class="lazy-image"
src="placeholder.jpg"
data-src="another-image.jpg"
alt="別の遅延読込画像"
/>
class="lazy-image"
を付けることで、JavaScript から遅延読込対象の画像を一括で取得できます。
JavaScript 実装
次に、IntersectionObserver を使って画像の遅延読込を実装します。
javascript// 遅延読込のコールバック関数
const lazyLoadCallback = (entries, observer) => {
entries.forEach((entry) => {
// 画像が表示領域に入ったか判定
if (entry.isIntersecting) {
const img = entry.target;
// data-src から実際の画像 URL を取得
const actualSrc = img.getAttribute('data-src');
// src 属性に実際の URL をセット(画像読込開始)
img.src = actualSrc;
// 読込完了後の処理
img.onload = () => {
img.classList.add('loaded'); // CSS でフェードイン等の演出可能
};
// この画像の監視を終了(一度読み込んだら再度監視する必要なし)
observer.unobserve(img);
}
});
};
画像が表示領域に入ったら data-src
の値を src
にセットし、画像の読込を開始します。読込完了後は loaded
クラスを追加することで、CSS でフェードイン効果などを付けられますね。
次に、IntersectionObserver のインスタンスを作成します。
javascript// オプション設定(画面に入る 200px 手前から読込開始)
const lazyLoadOptions = {
root: null,
rootMargin: '200px', // 先行読込でスムーズな表示を実現
threshold: 0,
};
// IntersectionObserver インスタンス作成
const lazyLoadObserver = new IntersectionObserver(
lazyLoadCallback,
lazyLoadOptions
);
rootMargin: '200px'
により、画像が画面に入る 200px 手前から読込が始まります。これでユーザーがスクロールした時には既に画像が表示されている状態になるでしょう。
最後に、すべての遅延読込画像に対して監視を開始します。
javascript// すべての遅延読込画像を取得
const lazyImages = document.querySelectorAll('.lazy-image');
// 各画像の監視を開始
lazyImages.forEach((img) => {
lazyLoadObserver.observe(img);
});
CSS での演出追加
画像読込時にフェードイン効果を付けると、より洗練された印象になります。
css/* 初期状態は透明 */
.lazy-image {
opacity: 0;
transition: opacity 0.3s ease-in;
}
/* 読込完了後はフェードイン */
.lazy-image.loaded {
opacity: 1;
}
以下の図は、画像遅延読込の処理フローを示しています。
mermaidsequenceDiagram
participant User as ユーザー
participant Browser as ブラウザ
participant Observer as IntersectionObserver
participant Image as img 要素
User->>Browser: ページアクセス
Browser->>Image: placeholder.jpg 読込
Browser->>Observer: 監視開始
User->>Browser: スクロール
Browser->>Observer: 要素位置チェック
Observer->>Observer: 交差判定(rootMargin: 200px)
Observer->>Image: data-src → src にセット
Image->>Browser: actual-image.jpg 読込開始
Image->>Image: 読込完了
Image->>Image: loaded クラス追加
Browser->>User: フェードイン表示
フローの要点: ユーザーがスクロールすると、200px 手前で自動的に画像読込が開始され、スムーズに表示されます。
レシピ 2: 無限スクロール(Infinite Scroll)
無限スクロールは、SNS やニュースサイトでよく使われる UI パターンです。ページ下部に到達すると、自動的に次のコンテンツを読み込みます。
HTML の準備
コンテンツリストの最後に、トリガーとなる要素を配置します。
html<!-- コンテンツリスト -->
<div id="content-list">
<div class="content-item">コンテンツ 1</div>
<div class="content-item">コンテンツ 2</div>
<div class="content-item">コンテンツ 3</div>
<!-- ... -->
</div>
<!-- 無限スクロールのトリガー要素 -->
<div id="scroll-trigger" class="scroll-trigger">
<p>読込中...</p>
</div>
#scroll-trigger
が画面に入ったタイミングで、次のコンテンツを読み込む仕組みですね。
JavaScript 実装(基本構造)
まず、現在のページ番号と読込中フラグを管理する変数を定義します。
javascript// ページ管理用の変数
let currentPage = 1; // 現在のページ番号
let isLoading = false; // 読込中フラグ(二重読込防止)
let hasMoreContent = true; // まだコンテンツがあるか
これらの変数で、重複した読込を防ぎ、すべてのコンテンツを読み込んだ後の処理を制御します。
次に、コンテンツを取得して DOM に追加する関数を作成します。
javascript// コンテンツ取得関数(API からデータを取得する想定)
const fetchContent = async (page) => {
try {
// API エンドポイントにリクエスト
const response = await fetch(
`/api/contents?page=${page}`
);
const data = await response.json();
return data;
} catch (error) {
console.error('コンテンツ取得エラー:', error);
return null;
}
};
この関数は、ページ番号を受け取って API からコンテンツを取得します。実際のプロジェクトでは、バックエンド API のエンドポイントに合わせて調整してください。
javascript// コンテンツを DOM に追加する関数
const appendContent = (items) => {
const contentList =
document.getElementById('content-list');
items.forEach((item) => {
// 新しいコンテンツ要素を作成
const contentElement = document.createElement('div');
contentElement.className = 'content-item';
contentElement.textContent = item.title; // データ構造に応じて調整
// リストに追加
contentList.appendChild(contentElement);
});
};
取得したデータを元に DOM 要素を作成し、コンテンツリストに追加しますね。
IntersectionObserver の設定
無限スクロール用の IntersectionObserver を設定します。
javascript// 無限スクロールのコールバック関数
const infiniteScrollCallback = async (entries) => {
const trigger = entries[0];
// トリガーが表示領域に入り、かつ読込中でない場合
if (
trigger.isIntersecting &&
!isLoading &&
hasMoreContent
) {
isLoading = true; // 読込開始フラグを立てる
// 次のページ番号をインクリメント
currentPage++;
// コンテンツを取得
const newContent = await fetchContent(currentPage);
// 取得成功時の処理
if (
newContent &&
newContent.items &&
newContent.items.length > 0
) {
appendContent(newContent.items);
// これ以上コンテンツがない場合
if (!newContent.hasMore) {
hasMoreContent = false;
// トリガー要素を非表示にする
document.getElementById(
'scroll-trigger'
).style.display = 'none';
}
} else {
// データがない場合も終了扱い
hasMoreContent = false;
document.getElementById(
'scroll-trigger'
).style.display = 'none';
}
isLoading = false; // 読込完了フラグを戻す
}
};
このコールバック関数は、トリガー要素が画面に入ったタイミングで実行されます。isLoading
フラグで二重読込を防ぎ、hasMoreContent
ですべてのコンテンツを読み込んだ後の処理を制御していますね。
javascript// オプション設定(トリガーが完全に表示されたら発火)
const infiniteScrollOptions = {
root: null,
rootMargin: '0px',
threshold: 1.0, // トリガー要素が 100% 表示されたら
};
// IntersectionObserver インスタンス作成
const infiniteScrollObserver = new IntersectionObserver(
infiniteScrollCallback,
infiniteScrollOptions
);
threshold: 1.0
により、トリガー要素が完全に画面に入った時点でコンテンツ読込が開始されます。
javascript// トリガー要素の監視開始
const scrollTrigger = document.getElementById(
'scroll-trigger'
);
infiniteScrollObserver.observe(scrollTrigger);
以下の図は、無限スクロールの状態遷移を示しています。
mermaidstateDiagram-v2
[*] --> Ready: 初期化完了
Ready --> Loading: トリガー要素が表示領域に入る
Loading --> Appending: APIからデータ取得成功
state Appending {
[*] --> AppendCheck: DOMに追加完了
AppendCheck --> HasMoreTrue: hasMore=true
AppendCheck --> HasMoreFalse: hasMore=false
}
Appending --> Ready: 次のデータを読み込み
Appending --> Complete: 全データ読み込み完了
Loading --> Error: APIエラー発生
Error --> Ready: エラー処理完了
Complete --> [*]: 全コンテンツ読込完了
状態遷移の要点: Ready ⇔ Loading ⇔ Appending のサイクルを繰り返し、コンテンツがなくなったら Complete で終了します。
エラーハンドリングの追加
実際の運用では、ネットワークエラーやタイムアウトへの対応が必要です。
javascript// エラー時の再試行機能付きコンテンツ取得関数
const fetchContentWithRetry = async (page, retries = 3) => {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(
`/api/contents?page=${page}`,
{
timeout: 5000, // 5 秒でタイムアウト
}
);
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error(
`取得失敗 (試行 ${i + 1}/${retries}):`,
error
);
// 最後の試行でもエラーなら null を返す
if (i === retries - 1) {
return null;
}
// 次の試行まで待機(指数バックオフ)
await new Promise((resolve) =>
setTimeout(resolve, 1000 * Math.pow(2, i))
);
}
}
};
再試行ロジックを追加することで、一時的なネットワークエラーにも対応できます。指数バックオフにより、サーバーへの負荷を抑えながら再試行できるでしょう。
レシピ 3: 高度な実装パターン
パターン A: 画像とバックグラウンド画像の遅延読込
CSS の background-image
も遅延読込できます。
html<!-- バックグラウンド画像用の要素 -->
<div
class="lazy-background"
data-bg="hero-image.jpg"
style="width: 100%; height: 400px;"
>
<h1>ヒーローセクション</h1>
</div>
javascript// バックグラウンド画像の遅延読込コールバック
const lazyBackgroundCallback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const element = entry.target;
const bgUrl = element.getAttribute('data-bg');
// background-image をセット
element.style.backgroundImage = `url(${bgUrl})`;
element.classList.add('loaded');
observer.unobserve(element);
}
});
};
// IntersectionObserver 作成と監視開始
const bgObserver = new IntersectionObserver(
lazyBackgroundCallback,
{
rootMargin: '100px',
}
);
document
.querySelectorAll('.lazy-background')
.forEach((el) => {
bgObserver.observe(el);
});
パターン B: スクロールアニメーション
要素の表示割合に応じてアニメーションを制御できます。
javascript// スクロールアニメーションのコールバック
const scrollAnimationCallback = (entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// 要素が表示領域に入ったらアニメーションクラスを追加
entry.target.classList.add('animate-in');
} else {
// 表示領域から出たらアニメーションをリセット
entry.target.classList.remove('animate-in');
}
});
};
// 複数の threshold で段階的に検知
const animationObserver = new IntersectionObserver(
scrollAnimationCallback,
{
threshold: [0, 0.25, 0.5, 0.75, 1],
}
);
document
.querySelectorAll('.animate-on-scroll')
.forEach((el) => {
animationObserver.observe(el);
});
css/* アニメーション用 CSS */
.animate-on-scroll {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.animate-on-scroll.animate-in {
opacity: 1;
transform: translateY(0);
}
パターン C: ビデオの自動再生・停止
ビューポートに入ったらビデオを再生し、出たら停止する実装です。
html<!-- 自動再生するビデオ -->
<video class="lazy-video" muted loop preload="none">
<source src="video.mp4" type="video/mp4" />
</video>
javascript// ビデオの自動再生・停止コールバック
const videoCallback = (entries) => {
entries.forEach((entry) => {
const video = entry.target;
if (entry.isIntersecting) {
// ビューポートに入ったら再生
video.play();
} else {
// ビューポートから出たら停止
video.pause();
}
});
};
// IntersectionObserver 作成
const videoObserver = new IntersectionObserver(
videoCallback,
{
threshold: 0.5, // ビデオの 50% が表示されたら再生
}
);
// すべてのビデオを監視
document
.querySelectorAll('.lazy-video')
.forEach((video) => {
videoObserver.observe(video);
});
ビデオが画面に表示されている間だけ再生することで、帯域幅とバッテリーを節約できますね。
実装時のベストプラクティス
IntersectionObserver を効果的に使うために、以下のポイントを押さえておきましょう。
# | 項目 | 推奨設定 | 理由 |
---|---|---|---|
1 | rootMargin | 100px〜200px | 先行読込でスムーズな UX を実現 |
2 | threshold | 画像: 0、アニメーション: 0.5 | 用途に応じて最適化 |
3 | unobserve() | 読込完了後に必ず実行 | メモリリークを防ぐ |
4 | 監視解除 | コンポーネント破棄時に disconnect() | SPA でのメモリ管理 |
5 | フォールバック | 古いブラウザ対応を検討 | ポリフィルまたは従来手法 |
unobserve と disconnect の使い分け: unobserve(element)
は特定の要素の監視を解除し、disconnect()
はすべての監視を解除します。React や Vue などの SPA では、コンポーネントのアンマウント時に disconnect()
を呼び出すことが重要ですね。
javascript// React での例(useEffect のクリーンアップ)
useEffect(() => {
const observer = new IntersectionObserver(
callback,
options
);
elements.forEach((el) => observer.observe(el));
// クリーンアップ関数で監視を解除
return () => {
observer.disconnect();
};
}, []);
ブラウザ対応とポリフィル
IntersectionObserver は主要なモダンブラウザでサポートされていますが、古いブラウザでは動作しません。
対応状況
- Chrome 51+
- Firefox 55+
- Safari 12.1+
- Edge 15+
- IE: 非対応
古いブラウザをサポートする必要がある場合は、ポリフィルを使用します。
javascript// ポリフィルの読込(IE 対応が必要な場合)
if (!('IntersectionObserver' in window)) {
// ポリフィルを動的に読み込む
const script = document.createElement('script');
script.src =
'https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver';
document.head.appendChild(script);
}
または、yarn でポリフィルをインストールします。
bashyarn add intersection-observer
javascript// アプリケーションのエントリーポイントでインポート
import 'intersection-observer';
まとめ
IntersectionObserver を使った無限スクロールと遅延読込の実装方法をご紹介しました。従来のスクロールイベントと比べて、パフォーマンスが大幅に向上し、実装もシンプルになります。
重要なポイント
- IntersectionObserver は要素の交差を効率的に検知できる API です
rootMargin
で先行読込を設定し、スムーズな UX を実現できますthreshold
で交差判定のタイミングを細かく制御できますね- 画像の遅延読込では、
unobserve()
で一度読み込んだ要素の監視を解除しましょう - 無限スクロールでは、
isLoading
フラグで二重読込を防ぎます - React や Vue などの SPA では、コンポーネント破棄時に
disconnect()
を呼び出すことが重要です
パフォーマンス改善効果
- 初期読込時間の短縮
- 通信量の削減
- メモリ使用量の最適化
- バッテリー消費の削減
- スクロールパフォーマンスの向上
これらの実装パターンを活用することで、ユーザー体験を大幅に改善できるでしょう。特にモバイル環境では、その効果が顕著に現れます。ぜひ、あなたのプロジェクトに取り入れてみてください。
関連リンク
- article
JavaScript IntersectionObserver レシピ集:無限スクロール/遅延読込を最短実装
- article
JavaScript Web Workers 実践入門:重い処理を別スレッドへ逃がす最短手順
- article
JavaScript OffscreenCanvas 検証:Canvas/OffscreenCanvas/WebGL の速度比較
- article
JavaScript メモリリーク診断術:DevTools の Heap スナップショット徹底活用
- article
JavaScript Streams API 活用ガイド:巨大データを分割して途切れず処理する
- article
【早見表】JavaScript でよく使う Math メソッドの一覧と活用事例
- article
Motion(旧 Framer Motion)useAnimate/useMotionValueEvent 速習チートシート
- article
Remix ルーティング早見表:ネスト・可変パラメータ・モーダルルート対応一覧
- article
JavaScript IntersectionObserver レシピ集:無限スクロール/遅延読込を最短実装
- article
Preact チートシート【保存版】:JSX/Props/Events/Ref の書き方早見表
- article
Playwright コマンド&テストランナー チートシート【保存版スニペット集】
- article
htmx 属性チートシート:hx-get/hx-post/hx-swap/hx-target 早見表【実例付き】
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来