UNPKG

perf-audit-cli

Version:

CLI tool for continuous performance monitoring and analysis

564 lines (421 loc) 17.7 kB
# Performance Audit CLI Tool フロントエンド・SSR(Server-Side Rendering)アプリケーションのパフォーマンスを継続的に監視・分析し、パフォーマンス劣化を防ぐためのCLIツール。 ## 特徴 - クライアント・サーバーサイドバンドルの自動監視(SSR対応) - 個別・統合パフォーマンスバジェットチェック - Lighthouse統合によるWebパフォーマンス測定 - SQLiteベースの履歴管理とトレンド分析 - JSON/HTML形式の詳細レポート生成 - CI/CD統合(GitHub Actions、GitLab CI対応) - Webpack, Vite, Rollup等の主要バンドラー対応 - Webダッシュボードによるビジュアライゼーション ## インストール ```bash npm install -g perf-audit-cli ``` ## 使い方 ### 1. 初期化 ```bash perf-audit init ``` 設定ファイル `perf-audit.config.js` が作成され、プロジェクトに合わせてカスタマイズできます。 ### 2. バンドル分析(SSR対応) ```bash perf-audit analyze [オプション] ``` オプション: - `--format <type>`: 出力形式 (json, html, console) [デフォルト: console] - `--details`: 詳細分析を表示 設定ファイルの `analysis.target` で解析対象を制御できます: - `'client'`: クライアントサイドバンドルのみ - `'server'`: サーバーサイドバンドルのみ - `'both'`: クライアント・サーバー両方(デフォルト) #### 出力例(SSR対応) ``` 🎯 Performance Audit Report ═══════════════════════════════════════════ 📦🖥️ Client & Server Analysis 📦 Client Bundles: ├─ main.js: 125.3KB (gzip: 42.1KB) ⚠️ +5.2KB ├─ vendor.js: 89.2KB (gzip: 28.3KB) └─ Client Total: 214.3KB (gzip: 70.4KB) 🖥️ Server Bundles: ├─ server.js: 180.4KB (gzip: 58.2KB) -2.1KB ├─ vendor.js: 145.6KB (gzip: 42.8KB) └─ Server Total: 326.0KB (gzip: 101.0KB) 📊 Overall Total: └─ Combined Total: 540.3KB (gzip: 171.4KB) 💡 Recommendations: - [Client] Consider code splitting for large bundles: main.js - [Server] Review server dependencies for optimization All checks passed! (2024-01-15 19:30:00) ``` ### 3. パフォーマンスバジェットチェック ```bash perf-audit budget [オプション] ``` オプション: - `--format <type>`: 出力形式 (json, console) [デフォルト: console] 設定された閾値と比較し、CI向けの終了コードを返します。 ### 4. Lighthouse監査 ```bash perf-audit lighthouse <url> [オプション] ``` オプション: - `--device <type>`: デバイスタイプ (mobile, desktop) [デフォルト: mobile] - `--no-throttling`: ネットワークスロットリングを無効化 - `--format <type>`: 出力形式 (json, console) [デフォルト: console] 例: ```bash perf-audit lighthouse https://example.com --device desktop --format json ``` ### 5. パフォーマンス履歴・トレンド ```bash perf-audit history [オプション] ``` オプション: - `--days <n>`: 表示する日数 [デフォルト: 30] - `--format <type>`: 出力形式 (json, console) [デフォルト: console] 例: ```bash perf-audit history --days 14 --format json ``` ### 6. Webダッシュボード(SSR対応) ```bash perf-audit dashboard [オプション] ``` オプション: - `--port <n>`: ダッシュボードのポート番号 [デフォルト: 3000] - `--host <host>`: バインドするホスト [デフォルト: localhost] - `--open`: ブラウザを自動で開く パフォーマンスデータを視覚化するWebダッシュボードを起動します。 **主な機能:** - クライアント・サーバーバンドル別の可視化 - 個別および統合トレンドグラフ - パフォーマンスバジェット状況の表示 - 履歴データのインタラクティブな分析 - レスポンシブ対応のダッシュボードUI ### 8. データクリーンアップ ```bash perf-audit clean [オプション] ``` オプション: - `--days <n>`: N日より古いデータを削除 [デフォルト: 30] - `--all`: すべてのパフォーマンスデータを削除 - `--force`: 確認プロンプトをスキップ パフォーマンスデータとレポートをクリーンアップします。 ## SSR(Server-Side Rendering)対応 Performance Audit CLI ToolはSSRアプリケーションにも対応しており、クライアントサイドとサーバーサイドのバンドルを個別に、または統合して解析できます。 ### SSRアプリケーションの設定 1. **設定ファイルの準備**: `perf-audit.config.js` でクライアント・サーバーの設定を個別に定義 2. **解析対象の選択**: `analysis.target` で解析対象を選択(`client`, `server`, `both`) 3. **バジェット管理**: クライアント・サーバー別に異なるパフォーマンスバジェットを設定 ### 使用例 ```bash # クライアント・サーバー両方を解析 perf-audit analyze # クライアントサイドのみ解析 # config.analysis.target = 'client' perf-audit analyze # サーバーサイドのみ解析 # config.analysis.target = 'server' perf-audit analyze ``` ### ダッシュボードでの可視化 Webダッシュボードでは以下の機能を提供: - **個別表示**: クライアント・サーバーバンドルを別々に表示 - **統合表示**: 総合的なパフォーマンス状況を表示 - **トレンド分析**: 時系列でのバンドルサイズ変化を追跡 - **バジェット管理**: 個別バジェットの遵守状況を監視 ## 設定 `perf-audit.config.js` でプロジェクトに合わせて設定をカスタマイズできます。 #### クライアントサイド設定 (`project.client`) | 項目 | | デフォルト | 説明 | | ------------ | ------ | ---------- | ---------------------------- | | `outputPath` | string | `'./dist'` | クライアント出力ディレクトリ | #### サーバーサイド設定 (`project.server`) | 項目 | | デフォルト | 説明 | | ------------ | ------ | ----------------- | ------------------------ | | `outputPath` | string | `'./dist/server'` | サーバー出力ディレクトリ | ### パフォーマンスバジェット設定 (`budgets`) - SSR対応 #### クライアントサイドバジェット (`budgets.client.bundles`) | 項目 | | 説明 | | | -------------- | ------ | ---------------------------------------- | ------------------------------------ | | `main` | object | クライアントメインバンドルのサイズ制限 | `{ max: '150KB', warning: '120KB' }` | | `vendor` | object | クライアントベンダーバンドルのサイズ制限 | `{ max: '100KB', warning: '80KB' }` | | `total` | object | クライアント全バンドルの合計サイズ制限 | `{ max: '500KB', warning: '400KB' }` | | `[カスタム名]` | object | 任意のバンドル名のサイズ制限 | `{ max: '50KB', warning: '40KB' }` | #### サーバーサイドバジェット (`budgets.server.bundles`) | 項目 | | 説明 | | | -------------- | ------ | ------------------------------------ | ------------------------------------ | | `main` | object | サーバーメインバンドルのサイズ制限 | `{ max: '200KB', warning: '150KB' }` | | `vendor` | object | サーバーベンダーバンドルのサイズ制限 | `{ max: '150KB', warning: '120KB' }` | | `total` | object | サーバー全バンドルの合計サイズ制限 | `{ max: '800KB', warning: '600KB' }` | | `[カスタム名]` | object | 任意のバンドル名のサイズ制限 | `{ max: '80KB', warning: '60KB' }` | #### Core Web Vitals バジェット (`budgets.metrics`) | 項目 | | 単位 | 説明 | | ------------- | ------ | ---- | --------------------------------- | | `fcp.max` | number | ms | First Contentful Paint の最大値 | | `fcp.warning` | number | ms | FCP の警告値 | | `lcp.max` | number | ms | Largest Contentful Paint の最大値 | | `lcp.warning` | number | ms | LCP の警告値 | | `cls.max` | number | - | Cumulative Layout Shift の最大値 | | `cls.warning` | number | - | CLS の警告値 | | `tti.max` | number | ms | Time to Interactive の最大値 | | `tti.warning` | number | ms | TTI の警告値 | ### 分析設定 (`analysis`) - SSR対応 | 項目 | | デフォルト | 説明 | | ------------- | -------- | ---------------------------------- | ------------------------------------- | | `target` | string | `'both'` | 解析対象 (`client`, `server`, `both`) | | `gzip` | boolean | `true` | gzip圧縮サイズを計測するか | | `ignorePaths` | string[] | `['**/*.test.js', '**/*.spec.js']` | 分析から除外するファイルパターン | ### レポート設定 (`reports`) | 項目 | | デフォルト | 説明 | | ----------- | -------- | ----------------------------- | ------------------------ | | `formats` | string[] | `['console', 'json', 'html']` | 利用可能な出力形式 | | `outputDir` | string | `'./performance-reports'` | レポート出力ディレクトリ | ### 設定例(SSR対応) ```javascript module.exports = { // プロジェクト設定 project: { // クライアントサイドの設定 client: { outputPath: './dist', }, // サーバーサイドの設定(SSR対応) server: { outputPath: './dist/server', }, }, // パフォーマンスバジェット budgets: { // クライアントサイドバジェット client: { bundles: { main: { max: '150KB', warning: '120KB' }, vendor: { max: '100KB', warning: '80KB' }, total: { max: '500KB', warning: '400KB' }, }, }, // サーバーサイドバジェット server: { bundles: { main: { max: '200KB', warning: '150KB' }, vendor: { max: '150KB', warning: '120KB' }, total: { max: '800KB', warning: '600KB' }, }, }, // メトリクス設定(クライアントサイドのみ) metrics: { fcp: { max: 1500, warning: 1000 }, lcp: { max: 2500, warning: 2000 }, cls: { max: 0.1, warning: 0.05 }, tti: { max: 3500, warning: 3000 }, }, }, // 分析設定 analysis: { // 解析対象の選択: 'client', 'server', 'both' target: 'both', gzip: true, ignorePaths: ['**/*.test.js', '**/*.spec.js'], }, // レポート設定 reports: { formats: ['console', 'json', 'html'], outputDir: './performance-reports', }, }; ``` ## CI/CD統合 ```yaml # GitHub Actions example name: Performance Audit on: push: branches: [ main, develop ] pull_request: branches: [ main ] jobs: performance-audit: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Build project run: npm run build - name: Install perf-audit-cli run: npm install -g . - name: Run bundle analysis run: | perf-audit analyze --format json > bundle-report.json perf-audit analyze --format html continue-on-error: true - name: Check performance budgets run: perf-audit budget --format json > budget-results.json - name: Upload performance reports uses: actions/upload-artifact@v4 if: always() with: name: performance-reports path: | performance-reports/ bundle-report.json budget-results.json - name: Comment PR with results if: github.event_name == 'pull_request' uses: actions/github-script@v7 with: script: | const fs = require('fs'); // Read budget results let budgetResults = {}; try { budgetResults = JSON.parse(fs.readFileSync('budget-results.json', 'utf8')); } catch (e) { console.log('Could not read budget results'); return; } // Generate comment const statusEmoji = { ok: '✅', warning: '⚠️', error: '❌' }; const emoji = statusEmoji[budgetResults.status] || '❓'; const status = budgetResults.status || 'unknown'; let comment = `## 🎯 Performance Audit Results ${emoji}\n\n`; comment += `**Status:** ${status.toUpperCase()}\n`; comment += `**Timestamp:** ${budgetResults.timestamp}\n\n`; if (budgetResults.violations && budgetResults.violations.length > 0) { comment += `### ⚠️ Budget Violations\n\n`; comment += `| Bundle | Size | Status |\n`; comment += `|--------|------|--------|\n`; budgetResults.violations.forEach(violation => { const size = (violation.size / 1024).toFixed(1) + 'KB'; comment += `| \`${violation.name}\` | ${size} | ${statusEmoji[violation.status]} ${violation.status} |\n`; }); comment += `\n`; } else { comment += `### All budgets passed!\n\n`; } comment += `---\n`; comment += `Generated by perf-audit-cli | [View detailed reports](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})\n`; // Post comment github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: comment }); lighthouse-audit: runs-on: ubuntu-latest if: github.event_name == 'pull_request' strategy: matrix: site: - url: "https://your-site.com" name: "Production" # Add more URLs as needed steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Build project run: npm run build - name: Install perf-audit-cli run: npm install -g . - name: Run Lighthouse audit (Mobile) run: | perf-audit lighthouse ${{ matrix.site.url }} --device mobile --format json > lighthouse-mobile-${{ matrix.site.name }}.json continue-on-error: true - name: Run Lighthouse audit (Desktop) run: | perf-audit lighthouse ${{ matrix.site.url }} --device desktop --format json > lighthouse-desktop-${{ matrix.site.name }}.json continue-on-error: true - name: Upload Lighthouse reports uses: actions/upload-artifact@v4 if: always() with: name: lighthouse-reports-${{ matrix.site.name }} path: | lighthouse-*.json performance-reports/ performance-history: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Build project run: npm run build - name: Install perf-audit-cli run: npm install -g . - name: Restore performance history uses: actions/cache@v4 with: path: .perf-audit/ key: perf-audit-${{ github.sha }} restore-keys: | perf-audit- - name: Generate performance history run: | perf-audit analyze perf-audit history --days 30 --format json > performance-history.json - name: Upload history uses: actions/upload-artifact@v4 with: name: performance-history path: | performance-history.json .perf-audit/ ``` 終了コード: - `0`: すべてのチェックが成功 - `1`: エラー(バジェット超過) - `2`: 警告 ## 開発 ### 事前準備 [volta](https://docs.volta.sh/guide/getting-started) のインストール必須 ### 各種コマンド ```bash # 依存関係のインストール npm ci # ビルド npm run build # 起動 npm start # テスト実行 npm test # Lint npm run lint # Type Check npm run typecheck # Format Check npm run format:check ``` ### 開発エディタ VSCode ## ライセンス MIT