web-performance-optimization
Webサイトやアプリの読み込み速度・Core Web Vitals・バンドルサイズ・キャッシュ戦略・ランタイムパフォーマンスを包括的に最適化します。パフォーマンス改善が必要な場面や計測・分析を行いたい際に活用できます。
description の原文を見る
Optimize website and web application performance including loading speed, Core Web Vitals, bundle size, caching strategies, and runtime performance
SKILL.md 本文
ウェブパフォーマンス最適化
概要
開発者がウェブサイトとウェブアプリケーションのパフォーマンスを最適化し、ユーザーエクスペリエンス、SEOランキング、コンバージョン率を向上させるのに役立ちます。このスキルは、ロード速度、ランタイムパフォーマンス、Core Web Vitals メトリクスを測定、分析、改善するための体系的なアプローチを提供します。
このスキルの使用時機
- ウェブサイトやアプリの読み込みが遅い場合
- Core Web Vitals(LCP、FID、CLS)の最適化時
- JavaScript バンドルサイズの削減時
- Time to Interactive(TTI)の改善時
- 画像とアセットの最適化時
- キャッシング戦略の実装時
- パフォーマンスボトルネックのデバッグ時
- パフォーマンス監査の準備時
動作方法
ステップ 1: 現在のパフォーマンスを測定
ベースラインメトリクスの確立を支援します:
- Lighthouse 監査を実行
- Core Web Vitals(LCP、FID、CLS)を測定
- バンドルサイズをチェック
- ネットワークウォーターフォールを分析
- パフォーマンスボトルネックを特定
ステップ 2: 問題を特定
パフォーマンスの問題を分析します:
- 大きな JavaScript バンドル
- 最適化されていない画像
- レンダリングをブロックするリソース
- サーバーレスポンス時間が遅い
- キャッシュヘッダーが不足している
- レイアウトシフト
- メインスレッドをブロックしている長いタスク
ステップ 3: 最適化を優先順位付け
高い影響をもつ改善に焦点を当てます:
- クリティカルレンダリングパスの最適化
- コード分割と遅延読み込み
- 画像の最適化
- キャッシング戦略
- サードパーティスクリプトの最適化
ステップ 4: 最適化を実装
パフォーマンス改善を適用します:
- アセット(画像、フォント、CSS、JS)の最適化
- コード分割の実装
- キャッシュヘッダーの追加
- 非クリティカルリソースの遅延読み込み
- クリティカルレンダリングパスの最適化
ステップ 5: 改善を検証
変更の影響を測定します:
- Lighthouse 監査を再実行
- 改善前後のメトリクスを比較
- リアルユーザーメトリクス(RUM)を監視
- 異なるデバイスとネットワークでテスト
例
例 1: Core Web Vitals の最適化
## パフォーマンス監査結果
### 現在のメトリクス(最適化前)
- **LCP(Largest Contentful Paint):** 4.2s ❌(2.5s 以下であるべき)
- **FID(First Input Delay):** 180ms ❌(100ms 以下であるべき)
- **CLS(Cumulative Layout Shift):** 0.25 ❌(0.1 以下であるべき)
- **Lighthouse スコア:** 62/100
### 特定された問題
1. **LCP 問題:** ヒーロー画像(2.5MB)の読み込みが遅い
2. **FID 問題:** 大きな JavaScript バンドル(850KB)がメインスレッドをブロック
3. **CLS 問題:** 寸法のない画像がレイアウトシフトを引き起こす
### 最適化計画
#### LCP(Largest Contentful Paint)を修正
**問題:** ヒーロー画像が 2.5MB で読み込みが遅い
**解決策:**
\`\`\`html
<!-- 前:最適化されていない画像 -->
<img src="/hero.jpg" alt="Hero">
<!-- 後:モダンフォーマットで最適化 -->
<picture>
<source srcset="/hero.avif" type="image/avif">
<source srcset="/hero.webp" type="image/webp">
<img
src="/hero.jpg"
alt="Hero"
width="1200"
height="600"
loading="eager"
fetchpriority="high"
>
</picture>
\`\`\`
**追加最適化:**
- 画像を 200KB 以下に圧縮
- CDN を使用して高速配信
- ヒーロー画像をプリロード:\`<link rel="preload" as="image" href="/hero.avif">\`
#### FID(First Input Delay)を修正
**問題:** 850KB の JavaScript バンドルがメインスレッドをブロック
**解決策:**
1. **コード分割:**
\`\`\`javascript
// 前:すべてが 1 つのバンドルに含まれている
import { HeavyComponent } from './HeavyComponent';
import { Analytics } from './analytics';
import { ChatWidget } from './chat';
// 後:重要度の低いコードを遅延読み込み
const HeavyComponent = lazy(() => import('./HeavyComponent'));
const ChatWidget = lazy(() => import('./chat'));
// ページが対話可能になった後に分析を読み込み
if (typeof window !== 'undefined') {
window.addEventListener('load', () => {
import('./analytics').then(({ Analytics }) => {
Analytics.init();
});
});
}
\`\`\`
2. **未使用の依存関係を削除:**
\`\`\`bash
# バンドルを分析
npx webpack-bundle-analyzer
# 未使用のパッケージを削除
npm uninstall moment # 代わりに date-fns を使用(よりコンパクト)
npm install date-fns
\`\`\`
3. **重要度の低いスクリプトを遅延実行:**
\`\`\`html
<!-- 前:レンダリングをブロック -->
<script src="/analytics.js"></script>
<!-- 後:遅延実行 -->
<script src="/analytics.js" defer></script>
\`\`\`
#### CLS(Cumulative Layout Shift)を修正
**問題:** 寸法のない画像がレイアウトシフトを引き起こす
**解決策:**
\`\`\`html
<!-- 前:寸法がない -->
<img src="/product.jpg" alt="Product">
<!-- 後:寸法がある -->
<img
src="/product.jpg"
alt="Product"
width="400"
height="300"
style="aspect-ratio: 4/3;"
>
\`\`\`
**動的コンテンツ向け:**
\`\`\`css
/* 後で読み込まれるコンテンツのためにスペースを予約 */
.skeleton-loader {
min-height: 200px;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: loading 1.5s infinite;
}
@keyframes loading {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
\`\`\`
### 最適化後の結果
- **LCP:** 1.8s ✅(57% 改善)
- **FID:** 45ms ✅(75% 改善)
- **CLS:** 0.05 ✅(80% 改善)
- **Lighthouse スコア:** 94/100 ✅
例 2: JavaScript バンドルサイズの削減
## バンドルサイズの最適化
### 現在の状況
- **合計バンドル:** 850KB(gzip 圧縮:280KB)
- **メインバンドル:** 650KB
- **ベンダーバンドル:** 200KB
- **ロード時間(3G):** 8.2s
### 分析
\`\`\`bash
# バンドル構成を分析
npx webpack-bundle-analyzer dist/stats.json
\`\`\`
**発見事項:**
1. Moment.js:67KB(date-fns に置き換え可能:12KB)
2. Lodash:72KB(ライブラリ全体を使用しているが、必要なのは 5 つの関数のみ)
3. 未使用コード:~150KB のデッドコード
4. コード分割なし:すべてが 1 つのバンドルに含まれている
### 最適化ステップ
#### 1. 重いライブラリを置き換え
\`\`\`bash
# moment.js(67KB)を削除 → date-fns を使用(12KB)
npm uninstall moment
npm install date-fns
# 前
import moment from 'moment';
const formatted = moment(date).format('YYYY-MM-DD');
# 後
import { format } from 'date-fns';
const formatted = format(date, 'yyyy-MM-dd');
\`\`\`
**削減量:** 55KB
#### 2. Lodash を選択的に使用
\`\`\`javascript
// 前:ライブラリ全体をインポート(72KB)
import _ from 'lodash';
const unique = _.uniq(array);
// 後:必要な部分のみをインポート(5KB)
import uniq from 'lodash/uniq';
const unique = uniq(array);
// またはネイティブメソッドを使用
const unique = [...new Set(array)];
\`\`\`
**削減量:** 67KB
#### 3. コード分割を実装
\`\`\`javascript
// Next.js 例
import dynamic from 'next/dynamic';
// 重いコンポーネントを遅延読み込み
const Chart = dynamic(() => import('./Chart'), {
loading: () => <div>Loading chart...</div>,
ssr: false
});
const AdminPanel = dynamic(() => import('./AdminPanel'), {
loading: () => <div>Loading...</div>
});
// ルートベースのコード分割(Next.js で自動)
// pages/admin.js - /admin にアクセスした時のみ読み込み
// pages/dashboard.js - /dashboard にアクセスした時のみ読み込み
\`\`\`
#### 4. デッドコードを削除
\`\`\`javascript
// webpack.config.js でツリーシェイキングを有効化
module.exports = {
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false
}
};
// package.json 内
{
"sideEffects": false
}
\`\`\`
#### 5. サードパーティスクリプトを最適化
\`\`\`html
<!-- 前:すぐに読み込み -->
<script src="https://analytics.com/script.js"></script>
<!-- 後:ページが対話可能になった後に読み込み -->
<script>
window.addEventListener('load', () => {
const script = document.createElement('script');
script.src = 'https://analytics.com/script.js';
script.async = true;
document.body.appendChild(script);
});
</script>
\`\`\`
### 結果
- **合計バンドル:** 380KB ✅(55% 削減)
- **メインバンドル:** 180KB ✅
- **ベンダーバンドル:** 80KB ✅
- **ロード時間(3G):** 3.1s ✅(62% 改善)
例 3: 画像最適化戦略
## 画像の最適化
### 現在の問題
- 合計 12MB の 15 枚の画像
- モダンフォーマット(WebP、AVIF)がない
- レスポンシブ画像がない
- 遅延読み込みがない
### 最適化戦略
#### 1. モダンフォーマットへの変換
\`\`\`bash
# 画像最適化ツールをインストール
npm install sharp
# 変換スクリプト(optimize-images.js)
const sharp = require('sharp');
const fs = require('fs');
const path = require('path');
async function optimizeImage(inputPath, outputDir) {
const filename = path.basename(inputPath, path.extname(inputPath));
// WebP を生成
await sharp(inputPath)
.webp({ quality: 80 })
.toFile(path.join(outputDir, \`\${filename}.webp\`));
// AVIF を生成(最高圧縮率)
await sharp(inputPath)
.avif({ quality: 70 })
.toFile(path.join(outputDir, \`\${filename}.avif\`));
// 最適化された JPEG フォールバックを生成
await sharp(inputPath)
.jpeg({ quality: 80, progressive: true })
.toFile(path.join(outputDir, \`\${filename}.jpg\`));
}
// すべての画像を処理
const images = fs.readdirSync('./images');
images.forEach(img => {
optimizeImage(\`./images/\${img}\`, './images/optimized');
});
\`\`\`
#### 2. レスポンシブ画像を実装
\`\`\`html
<!-- モダンフォーマットのレスポンシブ画像 -->
<picture>
<!-- AVIF をサポートするブラウザ向け(最高圧縮率) -->
<source
srcset="
/images/hero-400.avif 400w,
/images/hero-800.avif 800w,
/images/hero-1200.avif 1200w
"
type="image/avif"
sizes="(max-width: 768px) 100vw, 50vw"
>
<!-- WebP をサポートするブラウザ向け -->
<source
srcset="
/images/hero-400.webp 400w,
/images/hero-800.webp 800w,
/images/hero-1200.webp 1200w
"
type="image/webp"
sizes="(max-width: 768px) 100vw, 50vw"
>
<!-- JPEG フォールバック -->
<img
src="/images/hero-800.jpg"
srcset="
/images/hero-400.jpg 400w,
/images/hero-800.jpg 800w,
/images/hero-1200.jpg 1200w
"
sizes="(max-width: 768px) 100vw, 50vw"
alt="Hero image"
width="1200"
height="600"
loading="lazy"
>
</picture>
\`\`\`
#### 3. 遅延読み込み
\`\`\`html
<!-- ネイティブ遅延読み込み -->
<img
src="/image.jpg"
alt="Description"
loading="lazy"
width="800"
height="600"
>
<!-- ファーストビュー画像は早期読み込み -->
<img
src="/hero.jpg"
alt="Hero"
loading="eager"
fetchpriority="high"
>
\`\`\`
#### 4. Next.js Image コンポーネント
\`\`\`javascript
import Image from 'next/image';
// 自動最適化
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // ファーストビュー画像用
quality={80}
/>
// 遅延読み込み
<Image
src="/product.jpg"
alt="Product"
width={400}
height={300}
loading="lazy"
/>
\`\`\`
### 結果
| メトリクス | 最適化前 | 最適化後 | 改善 |
|--------|--------|--------|------|
| 合計画像サイズ | 12MB | 1.8MB | 85% 削減 |
| LCP | 4.5s | 1.6s | 64% 高速化 |
| ページロード(3G) | 18s | 4.2s | 77% 高速化 |
ベストプラクティス
✅ これをしてください
- まず測定する - 最適化前に常にベースラインメトリクスを確立する
- Lighthouse を使用 - 定期的に監査を実行して進捗を追跡
- 画像を最適化 - モダンフォーマット(WebP、AVIF)とレスポンシブ画像を使用
- コード分割 - 大きなバンドルをより小さなチャンクに分割
- 遅延読み込み - 重要度の低いリソースを遅延実行
- 積極的にキャッシュ - 静的アセットに適切なキャッシュヘッダーを設定
- メインスレッドの作業を最小化 - JavaScript 実行を 50ms のチャンク以下に保つ
- クリティカルリソースをプリロード - クリティカルアセットに `<link rel="preload">` を使用
- CDN を使用 - CDN から静的アセットを提供して高速配信
- リアルユーザーを監視 - リアルユーザーから Core Web Vitals を追跡
❌ これをしないでください
- 盲目的に最適化しない - 測定してから最適化する
- モバイルを無視しない - 実際のモバイルデバイスと低速ネットワークでテスト
- レンダリングをブロックしない - レンダリングをブロックする CSS と JavaScript を避ける
- すべてをアップフロントで読み込まない - 重要度の低いリソースを遅延読み込みする
- 寸法を忘れない - 常に画像の幅と高さを指定
- 同期スクリプトを使用しない - async または defer 属性を使用
- サードパーティスクリプトを無視しない - 通常、パフォーマンス問題を引き起こす
- 圧縮をスキップしない - 常にアセットを圧縮とミニファイする
一般的な落とし穴
問題:デスクトップで最適化されているがモバイルで遅い
症状: デスクトップでは Lighthouse スコアが良好だが、モバイルでは悪い 解決策:
- 実際のモバイルデバイスでテスト
- Chrome DevTools のモバイルスロットリングを使用
- 3G/4G ネットワークに最適化
- JavaScript 実行時間を削減
# スロットリングでテスト
lighthouse https://yoursite.com --throttling.cpuSlowdownMultiplier=4
問題:大きな JavaScript バンドル
症状: Time to Interactive(TTI)が長い、FID が高い 解決策:
- webpack-bundle-analyzer でバンドルを分析
- 未使用の依存関係を削除
- コード分割を実装
- 重要度の低いコードを遅延読み込み
# バンドルを分析
npx webpack-bundle-analyzer dist/stats.json
問題:画像がレイアウトシフトを引き起こす
症状: CLS スコアが高い、コンテンツがジャンプする 解決策:
- 常に幅と高さを指定
- CSS の aspect-ratio プロパティを使用
- スケルトンローダーでスペースを予約
img {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
}
問題:サーバーレスポンス時間が遅い
症状: TTFB(Time to First Byte)が高い 解決策:
- サーバーサイドキャッシュを実装
- 静的アセット用に CDN を使用
- データベースクエリを最適化
- 静的サイト生成(SSG)を検討
// Next.js:静的生成
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 60 // 60 秒ごとに再生成
};
}
パフォーマンスチェックリスト
画像
- モダンフォーマット(WebP、AVIF)に変換
- レスポンシブ画像を実装
- 遅延読み込みを追加
- 寸法(幅/高さ)を指定
- 画像を圧縮(各 200KB 以下)
- CDN を使用して配信
JavaScript
- バンドルサイズ < 200KB(gzip 圧縮)
- コード分割を実装
- 重要度の低いコードを遅延読み込み
- 未使用の依存関係を削除
- ミニファイと圧縮
- スクリプトに async/defer を使用
CSS
- クリティカル CSS をインライン化
- 重要度の低い CSS を遅延実行
- 未使用の CSS を削除
- CSS ファイルをミニファイ
- CSS containment を使用
キャッシング
- 静的アセットのキャッシュヘッダーを設定
- Service Worker を実装
- CDN キャッシュを使用
- API レスポンスをキャッシュ
- 静的アセットをバージョン管理
Core Web Vitals
- LCP < 2.5s
- FID < 100ms
- CLS < 0.1
- TTFB < 600ms
- TTI < 3.8s
パフォーマンスツール
測定ツール
- Lighthouse - 包括的なパフォーマンス監査
- WebPageTest - 詳細なウォーターフォール分析
- Chrome DevTools - パフォーマンスプロファイリング
- PageSpeed Insights - リアルユーザーメトリクス
- Web Vitals Extension - Core Web Vitals を監視
分析ツール
- webpack-bundle-analyzer - バンドル構成を視覚化
- source-map-explorer - バンドルサイズを分析
- Bundlephobia - インストール前にパッケージサイズを確認
- ImageOptim - 画像圧縮ツール
監視ツール
- Google Analytics - Core Web Vitals を追跡
- Sentry - パフォーマンス監視
- New Relic - アプリケーションパフォーマンス監視
- Datadog - リアルユーザー監視
関連スキル
@react-best-practices- React パフォーマンスパターン@frontend-dev-guidelines- フロントエンド開発標準@systematic-debugging- パフォーマンス問題のデバッグ@senior-architect- パフォーマンスに対応したアーキテクチャ
追加リソース
プロのヒント: Core Web Vitals(LCP、FID、CLS)を最初に優先してください。ユーザーエクスペリエンスと SEO ランキングに最も大きな影響を与えます!
制限事項
- このスキルは、タスクが上記で説明されたスコープと明確に一致する場合にのみ使用してください。
- 出力を環境固有の検証、テスト、または専門家のレビューの代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界線、または成功基準が不明な場合は、停止して説明を求めてください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- sickn33
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/sickn33/antigravity-awesome-skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。