Webパフォーマンス測定とモニタリング完全ガイド:継続的な改善のための実践手法
「パフォーマンスを改善したいが、どこから始めればいいかわからない」「測定はしているが、どう活用すればいいかわからない」「継続的な改善ができていない」と感じたことはありませんか?
パフォーマンス測定とモニタリングは、Webサイトのパフォーマンスを継続的に改善するための基盤です。適切な測定とモニタリングにより、ボトルネックを特定し、効果的な改善を実施できます。
この記事では、パフォーマンス測定とモニタリングの基礎から実践まで、測定ツールの選び方、モニタリングの設定方法、データ分析と改善への活用法を、具体的なコード例とベストプラクティスを交えて網羅的に解説します。
この記事を読む前に
この記事では、Webサイト制作とパフォーマンスの基礎知識があることを前提としています。以下の記事を事前に読んでおくと、より深く理解できます:
- Webパフォーマンス完全ガイド:Webパフォーマンスの全体像と測定・モニタリングの位置づけ
- Core Web Vitals完全ガイド:測定すべき指標の詳細
- GA4入門:Webサイトのパフォーマンスを測定する方法
この記事でわかること
- パフォーマンス測定とモニタリングとは何か、なぜ重要なのか
- 測定ツールの種類と選び方
- ラボ環境での測定方法
- リアルユーザーモニタリング(RUM)の実装方法
- モニタリングの設定とアラート
- データ分析と改善への活用法
- 継続的な改善のプロセス
1. パフォーマンス測定とモニタリングとは何か?
1.1 基本的な定義
パフォーマンス測定とは、Webサイトのパフォーマンス指標を測定し、現状を把握するプロセスです。
パフォーマンスモニタリングとは、パフォーマンス指標を継続的に監視し、問題を早期に発見するプロセスです。
測定とモニタリングが重要な理由
測定とモニタリングにより、パフォーマンスの現状を正確に把握できます。例えば、LCPが3秒であることを測定することで、改善の必要性を判断できます。問題の原因を特定できます。例えば、特定のJavaScriptファイルが読み込みを遅延させていることを発見できます。改善の効果を定量的に確認できます。例えば、画像最適化により、LCPが3秒から1.5秒に改善したことを確認できます。パフォーマンスの劣化を早期に発見できます。例えば、モニタリングにより、新機能の追加によりパフォーマンスが劣化したことを即座に発見できます。
1.2 測定の種類
ラボ環境での測定(Synthetic Monitoring):
- 特徴:制御された環境で測定
- メリット:再現性が高い、詳細な分析が可能
- デメリット:実際のユーザー環境と異なる可能性
リアルユーザーモニタリング(RUM):
- 特徴:実際のユーザーの環境で測定
- メリット:実際のユーザー体験を反映
- デメリット:環境が多様で、詳細な分析が難しい場合がある
両方が必要な理由
ラボ環境での測定は、再現性が高く、詳細な分析が可能です。例えば、Google Lighthouseにより、制御された環境で一貫した測定が可能です。一方、RUMは、実際のユーザー体験を反映します。例えば、実際のユーザーのネットワーク環境やデバイスでのパフォーマンスを測定できます。両方を組み合わせることで、より正確なパフォーマンス評価が可能になります。例えば、ラボ環境で問題を発見し、RUMで実際の影響を確認することで、優先順位を適切に設定できます。
2. ラボ環境での測定
2.1 Google Lighthouse
Lighthouseとは?
Lighthouseは、Googleが開発した、Webページの品質を測定するオープンソースツールです。
測定方法:
Chrome DevTools:
- Chrome DevToolsを開く(F12)
- 「Lighthouse」タブを選択
- 「Performance」を選択
- 「Analyze page load」をクリック
- 結果を確認
コマンドライン:
# Lighthouseをインストール
npm install -g lighthouse
# パフォーマンスを測定
lighthouse https://example.com --only-categories=performance --view
# 結果をJSONで出力
lighthouse https://example.com --only-categories=performance --output=json --output-path=./report.json
Node.js API:
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const options = { logLevel: 'info', output: 'html', onlyCategories: ['performance'], port: chrome.port };
const runnerResult = await lighthouse(url, options);
await chrome.kill();
return {
score: runnerResult.lhr.categories.performance.score 100,
metrics: runnerResult.lhr.audits,
};
}
runLighthouse('https://example.com').then(result => {
console.log('Performance Score:', result.score);
});
Lighthouseは、パフォーマンスだけでなく、アクセシビリティ、SEO、ベストプラクティスも測定できます。また、具体的な改善提案も提供されるため、すぐに実践できる最適化方法を学べます。Lighthouseは、Chrome DevToolsに統合されているため、簡単に使用できます。また、具体的な改善提案も提供されるため、すぐに実践できる最適化方法を学べます。例えば、「画像を最適化する」「JavaScriptを遅延読み込みする」などの具体的な改善提案が提供されます。
2.2 WebPageTest
WebPageTestとは?
WebPageTestは、世界中の複数の場所から、詳細なパフォーマンス分析を提供するツールです。
測定方法:
- WebPageTestにアクセス(https://www.webpagetest.org/)
- テストするURLを入力
- テスト場所を選択
- ブラウザを選択
- 「Start Test」をクリック
- 結果を確認
APIを使用した測定:
const axios = require('axios');
async function runWebPageTest(url, location = 'Tokyo') {
// テストを開始
const testResponse = await axios.get('https://www.webpagetest.org/runtest.php', {
params: {
url: url,
location: location,
f: 'json',
k: 'YOUR_API_KEY', // APIキーが必要
},
});
const testId = testResponse.data.data.testId;
// 結果を取得(ポーリング)
let result;
do {
await new Promise(resolve => setTimeout(resolve, 5000));
const resultResponse = await axios.get('https://www.webpagetest.org/jsonResult.php', {
params: { test: testId },
});
result = resultResponse.data;
} while (result.statusCode === 100);
return {
loadTime: result.data.average.firstView.loadTime,
ttfb: result.data.average.firstView.TTFB,
lcp: result.data.average.firstView.LCP,
};
}
WebPageTestは、世界中の複数の場所から測定できるため、地域によるパフォーマンスの違いを確認できます。また、詳細な分析機能(ウォーターフォールチャート、動画キャプチャなど)により、ボトルネックを特定できます。例えば、東京、ニューヨーク、ロンドンなど、複数の場所から測定することで、地域によるパフォーマンスの違いを確認できます。また、ウォーターフォールチャートや動画キャプチャなどの詳細な分析機能により、ボトルネックを特定できます。
2.3 Google PageSpeed Insights
PageSpeed Insightsとは?
PageSpeed Insightsは、LighthouseとChrome User Experience Reportを組み合わせて、実際のユーザーデータを含む包括的な分析を提供するツールです。
測定方法:
- PageSpeed Insightsにアクセス(https://pagespeed.web.dev/)
- テストするURLを入力
- 「分析」をクリック
- 結果を確認
APIを使用した測定:
const axios = require('axios');
async function runPageSpeedInsights(url) {
const response = await axios.get('https://www.googleapis.com/pagespeedonline/v5/runPagespeed', {
params: {
url: url,
key: 'YOUR_API_KEY', // APIキーが必要
category: ['performance'],
},
});
const lighthouseResult = response.data.lighthouseResult;
return {
score: lighthouseResult.categories.performance.score 100,
metrics: {
lcp: lighthouseResult.audits['largest-contentful-paint'].numericValue,
fid: lighthouseResult.audits['max-potential-fid'].numericValue,
cls: lighthouseResult.audits['cumulative-layout-shift'].numericValue,
},
};
}
PageSpeed Insightsは、実際のユーザーデータ(Chrome User Experience Report)を含むため、ラボ環境での測定よりも、実際のユーザー体験を反映します。また、具体的な改善提案も提供されます。PageSpeed Insightsは、実際のユーザーデータを含むため、ラボ環境での測定よりも、実際のユーザー体験を反映します。例えば、実際のユーザーのデバイスやネットワーク環境でのパフォーマンスを測定できるため、より正確な評価が可能になります。また、具体的な改善提案も提供されるため、すぐに実践できる最適化方法を学べます。
3. リアルユーザーモニタリング(RUM)
3.1 Web Vitalsライブラリ
Web Vitalsライブラリとは?
Web Vitalsライブラリは、Core Web Vitals(LCP、FID、CLS)を測定するためのJavaScriptライブラリです。
実装方法:
import { getLCP, getFID, getCLS } from 'web-vitals';
function sendToAnalytics(metric) {
// 分析ツールに送信
const body = JSON.stringify(metric);
// Google Analytics 4
if (typeof gtag !== 'undefined') {
gtag('event', metric.name, {
event_category: 'Web Vitals',
value: Math.round(metric.value),
event_label: metric.id,
non_interaction: true,
});
}
// カスタムエンドポイント
if ('sendBeacon' in navigator) {
navigator.sendBeacon('/api/analytics', body);
} else {
fetch('/api/analytics', { body, method: 'POST', keepalive: true });
}
}
getLCP(sendToAnalytics);
getFID(sendToAnalytics);
getCLS(sendToAnalytics);
Next.jsでの実装:
// pages/_app.js
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import { getCLS, getFID, getLCP } from 'web-vitals';
export function reportWebVitals(metric) {
// 分析ツールに送信
console.log(metric);
// Google Analytics 4
if (typeof gtag !== 'undefined') {
gtag('event', metric.name, {
event_category: 'Web Vitals',
value: Math.round(metric.value),
event_label: metric.id,
non_interaction: true,
});
}
}
export default function App({ Component, pageProps }) {
const router = useRouter();
useEffect(() => {
// Web Vitalsを測定
getCLS(reportWebVitals);
getFID(reportWebVitals);
getLCP(reportWebVitals);
}, []);
return <Component {...pageProps} />;
}
Web Vitalsライブラリは、実際のユーザーの環境でCore Web Vitalsを測定できます。これにより、実際のユーザー体験を正確に把握し、改善の効果を検証できます。例えば、実際のユーザーのデバイスやネットワーク環境でのCore Web Vitalsを測定できるため、ラボ環境での測定よりも、実際のユーザー体験を反映します。
3.2 Performance API
Performance APIとは?
Performance APIは、ブラウザが提供する、パフォーマンス情報を取得するためのAPIです。
実装方法:
// Navigation Timing
const navigationTiming = performance.getEntriesByType('navigation')[0];
console.log('TTFB:', navigationTiming.responseStart - navigationTiming.requestStart);
console.log('DOM Content Loaded:', navigationTiming.domContentLoadedEventEnd - navigationTiming.navigationStart);
console.log('Load Complete:', navigationTiming.loadEventEnd - navigationTiming.navigationStart);
// Resource Timing
const resourceTiming = performance.getEntriesByType('resource');
resourceTiming.forEach(resource => {
console.log(`${resource.name}:`, {
duration: resource.duration,
size: resource.transferSize,
ttfb: resource.responseStart - resource.requestStart,
});
});
// Paint Timing
const paintTiming = performance.getEntriesByType('paint');
paintTiming.forEach(paint => {
console.log(`${paint.name}:`, paint.startTime);
});
Performance APIは、ブラウザが提供する標準的なAPIのため、追加のライブラリが不要です。また、詳細なパフォーマンス情報を取得できるため、カスタムな分析が可能です。例えば、performance.timingを使用することで、ページの読み込み時間を詳細に測定できます。また、performance.getEntriesByType('resource')を使用することで、リソースの読み込み時間を測定できます。
3.3 カスタムメトリクスの測定
実装例:
// カスタムメトリクスの測定
function measureCustomMetric(name, startMark, endMark) {
const startTime = performance.getEntriesByName(startMark)[0].startTime;
const endTime = performance.getEntriesByName(endMark)[0].startTime;
const duration = endTime - startTime;
// メトリクスを記録
performance.mark(`${name}-end`);
performance.measure(name, startMark, `${name}-end`);
const measure = performance.getEntriesByName(name)[0];
console.log(`${name}:`, measure.duration, 'ms');
// 分析ツールに送信
sendToAnalytics({
name: name,
value: measure.duration,
id: `${name}-${Date.now()}`,
});
}
// 使用例
performance.mark('data-fetch-start');
fetch('/api/data')
.then(res => res.json())
.then(data => {
performance.mark('data-fetch-end');
measureCustomMetric('data-fetch-time', 'data-fetch-start', 'data-fetch-end');
});
4. モニタリングの設定
4.1 ダッシュボードの構築
実装例(Next.js + Chart.js):
// components/PerformanceDashboard.js
import { useEffect, useState } from 'react';
import { Line } from 'react-chartjs-2';
export default function PerformanceDashboard() {
const [metrics, setMetrics] = useState([]);
useEffect(() => {
// メトリクスを取得
fetch('/api/metrics')
.then(res => res.json())
.then(data => setMetrics(data));
// 定期的に更新
const interval = setInterval(() => {
fetch('/api/metrics')
.then(res => res.json())
.then(data => setMetrics(data));
}, 60000); // 1分ごとに更新
return () => clearInterval(interval);
}, []);
const chartData = {
labels: metrics.map(m => new Date(m.timestamp).toLocaleTimeString()),
datasets: [
{
label: 'LCP',
data: metrics.map(m => m.lcp),
borderColor: 'rgb(75, 192, 192)',
},
{
label: 'FID',
data: metrics.map(m => m.fid),
borderColor: 'rgb(255, 99, 132)',
},
{
label: 'CLS',
data: metrics.map(m => m.cls),
borderColor: 'rgb(54, 162, 235)',
},
],
};
return (
<div>
<h2>Performance Dashboard</h2>
<Line data={chartData} />
</div>
);
}
4.2 アラートの設定
実装例:
// utils/performance-alerts.js
export function checkPerformanceMetrics(metrics) {
const alerts = [];
// LCPのアラート
if (metrics.lcp > 4000) {
alerts.push({
level: 'error',
metric: 'LCP',
message: `LCP is ${metrics.lcp}ms, which is above the threshold of 4000ms`,
});
} else if (metrics.lcp > 2500) {
alerts.push({
level: 'warning',
metric: 'LCP',
message: `LCP is ${metrics.lcp}ms, which is above the recommended threshold of 2500ms`,
});
}
// FIDのアラート
if (metrics.fid > 300) {
alerts.push({
level: 'error',
metric: 'FID',
message: `FID is ${metrics.fid}ms, which is above the threshold of 300ms`,
});
} else if (metrics.fid > 100) {
alerts.push({
level: 'warning',
metric: 'FID',
message: `FID is ${metrics.fid}ms, which is above the recommended threshold of 100ms`,
});
}
// CLSのアラート
if (metrics.cls > 0.25) {
alerts.push({
level: 'error',
metric: 'CLS',
message: `CLS is ${metrics.cls}, which is above the threshold of 0.25`,
});
} else if (metrics.cls > 0.1) {
alerts.push({
level: 'warning',
metric: 'CLS',
message: `CLS is ${metrics.cls}, which is above the recommended threshold of 0.1`,
});
}
return alerts;
}
// アラートを送信
function sendAlert(alert) {
// メール、Slack、PagerDutyなどに送信
console.log('Alert:', alert);
// 例:Slackに送信
fetch('https://hooks.slack.com/services/YOUR/WEBHOOK/URL', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `Performance Alert: ${alert.message}`,
attachments: [{
color: alert.level === 'error' ? 'danger' : 'warning',
fields: [{
title: 'Metric',
value: alert.metric,
short: true,
}],
}],
}),
});
}
5. データ分析と改善への活用
5.1 データの集計と分析
実装例:
___
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const options = { logLevel: 'info', output: 'html', onlyCategories: ['performance'], port: chrome.port };
const runnerResult = await lighthouse(url, options);
await chrome.kill();
return {
score: runnerResult.lhr.categories.performance.score 100,
metrics: runnerResult.lhr.audits,
};
}
runLighthouse('https://example.com').then(result => {
console.log('Performance Score:', result.score);
});0___
5.2 改善の優先順位付け
実装例:
___
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const options = { logLevel: 'info', output: 'html', onlyCategories: ['performance'], port: chrome.port };
const runnerResult = await lighthouse(url, options);
await chrome.kill();
return {
score: runnerResult.lhr.categories.performance.score 100,
metrics: runnerResult.lhr.audits,
};
}
runLighthouse('https://example.com').then(result => {
console.log('Performance Score:', result.score);
});1___
6. 継続的な改善のプロセス
6.1 PDCAサイクル
Plan(計画):
- 現状を把握(測定)
- 目標を設定(例:LCPを2.5秒以下に)
- 改善計画を立案
Do(実行):
- 改善を実施
- 変更を記録
Check(評価):
- 効果を測定
- データを分析
Action(改善):
- 成功した改善を標準化
- 失敗した改善から学ぶ
- 次の改善計画を立案
6.2 実践例
ステップ1:現状の把握
___
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const options = { logLevel: 'info', output: 'html', onlyCategories: ['performance'], port: chrome.port };
const runnerResult = await lighthouse(url, options);
await chrome.kill();
return {
score: runnerResult.lhr.categories.performance.score 100,
metrics: runnerResult.lhr.audits,
};
}
runLighthouse('https://example.com').then(result => {
console.log('Performance Score:', result.score);
});2___
ステップ2:目標の設定
___
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const options = { logLevel: 'info', output: 'html', onlyCategories: ['performance'], port: chrome.port };
const runnerResult = await lighthouse(url, options);
await chrome.kill();
return {
score: runnerResult.lhr.categories.performance.score 100,
metrics: runnerResult.lhr.audits,
};
}
runLighthouse('https://example.com').then(result => {
console.log('Performance Score:', result.score);
});3___
ステップ3:改善の実施
___
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const options = { logLevel: 'info', output: 'html', onlyCategories: ['performance'], port: chrome.port };
const runnerResult = await lighthouse(url, options);
await chrome.kill();
return {
score: runnerResult.lhr.categories.performance.score 100,
metrics: runnerResult.lhr.audits,
};
}
runLighthouse('https://example.com').then(result => {
console.log('Performance Score:', result.score);
});4___
ステップ4:効果の検証
___
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const options = { logLevel: 'info', output: 'html', onlyCategories: ['performance'], port: chrome.port };
const runnerResult = await lighthouse(url, options);
await chrome.kill();
return {
score: runnerResult.lhr.categories.performance.score 100,
metrics: runnerResult.lhr.audits,
};
}
runLighthouse('https://example.com').then(result => {
console.log('Performance Score:', result.score);
});5___
パフォーマンス測定・モニタリングの要点とPDCA
- パフォーマンス測定とモニタリングは、継続的な改善の基盤
- ラボ環境での測定とリアルユーザーモニタリング(RUM)を組み合わせる
- 適切なツールを選択し、継続的にモニタリング
- データを分析し、改善の優先順位を決定
- PDCAサイクルで継続的に改善
次に読むおすすめの記事
Webパフォーマンス測定とモニタリングについて理解を深めたら、以下の記事も参考にしてください:
より深く学ぶ
- Webパフォーマンス完全ガイド:Webパフォーマンスの全体像と測定・モニタリングの位置づけ
- Core Web Vitals完全ガイド:測定すべき指標の詳細
- TTFB完全ガイド:TTFBの測定と改善
実践的な活用
- 画像最適化完全ガイド:画像最適化の効果測定
- JavaScript/CSS最適化完全ガイド:JavaScript/CSS最適化の効果測定
- 成果の出るWebサイト設計完全ガイド:SEO・UX・表示速度を同時に最適化する方法
関連する基礎知識
- GA4入門:Webサイトのパフォーマンスを測定する方法
- データ分析とは?超初心者向け完全ガイド:データ分析の基礎知識
次のステップ:
- 測定ツールを選択(Lighthouse、WebPageTest、PageSpeed Insights)
- RUMを実装(Web Vitalsライブラリ、Performance API)
- モニタリングを設定(ダッシュボード、アラート)
- データを分析(集計、トレンド分析)
- 改善を実施(優先順位に従って)
参考資料・引用元
- Google Lighthouse(2025年12月時点)
- WebPageTest(2025年12月時点)
- Google PageSpeed Insights(2025年12月時点)
- Web Vitals Library(2025年12月時点)
- Performance API(2025年12月時点)
ご相談・お問い合わせはこちら