Vue 3でのバーチャルスクロールを実装して大量のデータを効率的に表示

Vue 3でのバーチャルスクロールを実装して大量のデータを効率的に表示

バーチャルスクロールは大量のデータをスムーズに表示するためのテクニックです。Vue 3では、この仕組みを簡単に取り入れることができ、表示される範囲だけを効率的にレンダリングすることで、ブラウザへの負荷を軽減します。

バーチャルスクロールとは何か

通常、大量のデータをリストで表示するとパフォーマンスが低下します。しかし、バーチャルスクロールでは、実際に見えている範囲のデータのみを描画し、それ以外の部分は非表示にすることでパフォーマンスを大幅に向上させます。

プロジェクトのセットアップ

まずは新しいVue 3プロジェクトをセットアップし、必要なライブラリをインストールします。

npm init vue@latest
npm install

必要なデータの準備

仮想リストで表示するためのデータセットを用意します。

const items = Array.from({ length: 10000 }, (_, index) => `Item ${index}`);

バーチャルスクロール用コンポーネントの作成

スクロールイベントを活用して、可視範囲内のアイテムだけを表示するコンポーネントを作成します。

<template>
  <div class="scroll-container" @scroll="onScroll">
    <div class="spacer" :style="{ height: spacerHeight + 'px' }"></div>
    <div
      v-for="item in visibleItems"
      :key="item.index"
      class="item">
      {{ item.value }}
    </div>
  </div>
</template>

スタイルの設定

スクロール領域のサイズや見た目を調整して、スムーズなスクロール体験を提供します。

.scroll-container {
  height: 400px;
  overflow-y: auto;
  position: relative;
}
.spacer {
  position: absolute;
  width: 100%;
}
.item {
  height: 50px;
}

可視範囲の計算

スクロール位置に基づいて表示するデータを動的に切り替えます。

setup() {
  const visibleItems = ref([]);
  const spacerHeight = ref(0);

  const onScroll = (event) => {
    const scrollTop = event.target.scrollTop;
    const startIndex = Math.floor(scrollTop / 50);
    visibleItems.value = items.slice(startIndex, startIndex + 10);
    spacerHeight.value = items.length * 50;
  };

  return { visibleItems, spacerHeight, onScroll };
}

仮想リストの調整

表示範囲の前後に少し余裕(バッファ領域)を持たせることで、スクロール時の描画遅延を防ぎます。これにより、スクロール中に次の要素が事前に読み込まれ、カクつきのないスムーズな表示が実現されます。

パフォーマンスの最適化

スクロールイベントは頻繁に発生するため、requestAnimationFrameを使って描画タイミングを最適化します。また、v-memokeyを活用し、再レンダリングを必要最低限に抑えることが大切です。

エラーハンドリング

不正なデータやスクロールエラーが発生した場合、アプリがクラッシュしないようにtry-catchブロックでエラーハンドリングを行います。エラー発生時は安全な状態にリセットし、ユーザーに分かりやすいエラーメッセージを表示することが重要です。

Vue Routerとの統合

ページ遷移後もスクロール位置や表示状態を保持するには、keep-aliveを使ってコンポーネントの状態を維持します。また、beforeRouteLeaveフックを使ってスクロール位置を保存し、戻ったときに再適用することで、シームレスな体験を提供できます。

SSRとの互換性

サーバーサイドレンダリングでは、初期データを事前に取得し、ブラウザ側での再描画を減らすことがポイントです。onServerPrefetchを使ってデータを取得し、クライアントハイドレーションで齟齬が発生しないように状態を同期します。

まとめ

Vue 3のバーチャルスクロールは、大量のデータを効率的に扱うための強力なツールです。しっかりと設計すれば、ユーザーに快適な体験を提供できます。