フロントエンドのみで完結するアクセス解析:js-cookieを活用したユーザー行動記録の実装

計測対象の定義と技術的基礎

訪問者の滞在時間やページビュー数を把握したいが、大型の分析ツール導入には時間をかけられない場合がある。クライアントサイドのストレージを活用すれば、サーバー側の負荷を増やすことなく重要な行動ログを収集できる。本稿では、軽量ライブラリjs-cookieを組み合わせて、最小限のコードで独自アクセス解析を構築する手法を解説する。

単一ページアプリケーションや静的サイトにおける行動記録は、ブラウザに保存される状態情報によって実現される。本実装では以下の4つの指標をターゲットとする。

  • 初回アクセス時刻(新規ユーザー判定)
  • 前回のセッション終了時刻(アクティブ度算出)
  • ページロード回数(リピート率分析)
  • 累計滞在秒数(コンテンツエンゲージメント評価)

js-cookieはブラウザのCookie APIをラップしたユーティリティであり、setgetremoveの3つのメソッドでデータの読み書きを制御できる。状態の永続化にはJSON形式のシリアライズが最適である。

ステップ1:ライブラリの読み込み

外部CDNまたはローカルビルド产物どちらでも利用可能だ。配信速度を考慮し、信頼できるCDNを指定する。

<script src="https://cdn.jsdelivr.net/npm/js-cookie@3/dist/js.cookie.min.js"></script>

ステップ2:状態管理ロジックの構築

記録用のスクリプトを分離し、ページ遷移のライフサイクルに合わせてデータを更新する。ここでは変数名を最適化し、エラーハンドリングを強化した実例を示す。

function initializeSessionMetrics() {
  const storageKey = 'userActivityLog';
  const defaultState = {
    initialAccessTime: new Date().toISOString(),
    pageLoads: 0,
    previousSessionEnd: null,
    cumulativeTimeSec: 0
  };

  try {
    const raw = Cookies.get(storageKey);
    const metrics = raw ? JSON.parse(raw) : { ...defaultState };

    const currentTimestamp = Date.now();
    if (metrics.previousSessionEnd) {
      const lastVisitTimestamp = new Date(metrics.previousSessionEnd).getTime();
      const sessionDelta = Math.max(0, Math.floor((currentTimestamp - lastVisitTimestamp) / 1000));
      metrics.cumulativeTimeSec += sessionDelta;
    }

    metrics.pageLoads += 1;
    metrics.previousSessionEnd = new Date().toISOString();

    Cookies.set(storageKey, JSON.stringify(metrics), {
      expires: 30,
      path: '/'
    });
  } catch (error) {
    console.warn('アクティビティログの初期化に失敗しました:', error);
  }
}

document.addEventListener('DOMContentLoaded', initializeSessionMetrics);

window.addEventListener('pagehide', () => {
  try {
    const raw = Cookies.get('userActivityLog');
    if (!raw) return;

    const metrics = JSON.parse(raw);
    if (metrics.previousSessionEnd) {
      metrics.previousSessionEnd = new Date().toISOString();
      Cookies.set('userActivityLog', JSON.stringify(metrics), { path: '/' });
    }
  } catch (error) {
    console.warn('セッション更新中にエラーが発生しました:', error);
  }
});

beforeunload の代わりに pagehide を使用することで、バックグラウンド化やブラウザ閉じ時の信頼性を向上させている。

ステップ3:計測結果の可視化

管理画面上で保存されたログを読み込み、DOMに反映させる関数を定義する。

function renderActivityDashboard() {
  const container = document.querySelector('#dashboard-panel');
  if (!container) return;

  const raw = Cookies.get('userActivityLog');
  if (!raw) {
    container.textContent = '記録データが見つかりません。';
    return;
  }

  try {
    const data = JSON.parse(raw);
    const formattedDate = (isoStr) => new Date(isoStr).toLocaleString('ja-JP');
    const minutesSpent = Math.round(data.cumulativeTimeSec / 60);

    container.innerHTML = `
      <section class="metrics-viewer">
        <h3>ユーザー行動サマリー</h3>
        <dl>
          <dt>初回訪問</dt><dd>${formattedDate(data.initialAccessTime)}</dd>
          <dt>ページビュー</dt><dd>${data.pageLoads} 回</dd>
          <dt>最終アクセス</dt><dd>${formattedDate(data.previousSessionEnd)}</dd>
          <dt>合計滞在時間</dt><dd>${minutesSpent} 分</dd>
        </dl>
      </section>
    `;
  } catch (e) {
    container.textContent = 'データの解析中にエラーが発生しました。';
  }
}

高度なカスタマイズオプション

Cookie属性の明示的指定

大規模サイトではサブドメイン横断やセキュリティポリシーの適用が必須となる。withAttributes メソッドを利用することで、デフォルト設定を上書きしたインスタンスを生成できる。

const secureStorage = Cookies.withAttributes({
  path: '/',
  domain: '.example.com',
  secure: true,
  sameSite: 'lax'
});

secureStorage.set('crossDomainMetrics', JSON.stringify({ value: 100 }));

グラフ描画との連携

蓄積された数値系列をチャートライブラリに渡すことで、視覚的なトレンド分析が可能になる。Chart.jsを例とする。

function drawVisitTrend() {
  const raw = Cookies.get('userActivityLog');
  const ctx = document.getElementById('trendCanvas')?.getContext('2d');
  if (!raw || !ctx) return;

  const data = JSON.parse(raw);
  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['初期値', '現在'],
      datasets: [{
        label: '訪問回数推移',
        data: [1, data.pageLoads],
        backgroundColor: '#4e79a7'
      }]
    },
    options: { responsive: true }
  });
}

運用上の留意点

プライバシー規制への対応

GDPRや国内のプライバシーポリシーに従い、ユーザーへの明示的な同意取得が不可欠である。バナーやチェックボックスを実装し、同意がある状態でのみ計測関数を呼び出す設計とすること。

<div id="privacy-notice" role="alert" aria-live="polite">
  <p>行動記録のためにブラウザストレージを利用します。</p>
  <button type="button" id="accept-tracking">同意する</button>
</div>

パフォーマンスとストレージ最適化

  1. 非同期読み込み属性 defer または async を付与し、パースブロックを防止する。
  2. キープレフィックスを標準化し、他サービスとの競合を回避する。例:app_analytics_ プフィックス。
  3. 大容量データの記録には localStorageIndexedDB の併用を検討し、Cookieのサイズ制限を回避する。

ディレクトリ構成例

root/
├── public/
│   ├── index.html
│   ├── lib/
│   │   └── js.cookie.min.js
│   └── js/
│       └── tracker.js
└── src/
    └── core/
        └── api.mjs

クライアント環境に依存する実装は、サーバー連携なしで迅速にプロトタイプを構築できる利点がある。必要に応じてWebhookやfetch APIを用いてバックエンドへ定期送信し、スケーラブルな分析基盤へ移行可能だ。詳細なAPI仕様やテストケースは公式リポジトリのドキュメントを参照のこと。

タグ: js-cookie ブラウザCookie クライアントサイド解析 javascript Webトラッキング

6月29日 16:16 投稿