mcpField
P
performance

performance

github.com/davila7開発33.0k212 回インストール今日更新
リポジトリ

performance について

このスキルは、Lighthouse監査に基づくWebパフォーマンス最適化の指針を提供します。開発者がボトルネックを特定し、Core Web Vitalsに沿って優先順位を決め、変更前後の指標で改善を測定できます。

主な機能

  1. 01コードとアセットのボトルネック特定
  2. 02Core Web Vitalsに基づく優先順位付け
  3. 03読み込みとレンダリングの最適化
  4. 04ランタイム効率の改善
  5. 05変更前後の結果測定

活用シーン

  1. 01ページ読み込みの遅さの診断
  2. 02JavaScriptやアセットの負荷削減
  3. 03レンダリングと操作応答性の改善
  4. 04Lighthouse指標による変更評価

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/davila7/claude-code-templates --skill performance

インストール後、Claude Code で/performanceを入力して読み込まれたか確認します。

詳細

パフォーマンス最適化

Lighthouse のパフォーマンス監査に基づく詳細なパフォーマンス最適化です。読み込み速度、ランタイム効率、リソース最適化に焦点を当てます。

仕組み

  1. コードとアセットにおけるパフォーマンスのボトルネックを特定します
  2. Core Web Vitals への影響度に基づいて優先順位を付けます
  3. コード例とともに具体的な最適化を提案します
  4. 最適化前後の指標で改善効果を測定します

パフォーマンスバジェット

リソースバジェット根拠
ページの総容量< 1.5 MB3G では約 4 秒で読み込み
JavaScript(圧縮後)< 300 KBパースと実行時間
CSS(圧縮後)< 100 KBレンダリングのブロック
画像(ファーストビュー)< 500 KBLCP への影響
フォント< 100 KBFOIT/FOUT の防止
サードパーティ< 200 KB制御できないレイテンシ

クリティカルレンダリングパス

サーバーレスポンス
  • TTFB < 800ms。 Time to First Byte は高速であるべきです。CDN、キャッシュ、効率的なバックエンドを使用してください。
  • 圧縮を有効にします。 テキストアセットには Gzip または Brotli を使用します。Brotli が推奨されます(15〜20% 小さくなります)。
  • HTTP/2 または HTTP/3。 多重化により接続のオーバーヘッドが減ります。
  • エッジキャッシュ。 可能な場合は CDN のエッジで HTML をキャッシュします。
リソースの読み込み

必要なオリジンへの事前接続:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>

重要なリソースのプリロード:


<link rel="preload" href="/hero.webp" as="image" fetchpriority="high">


<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>

重要でない CSS の遅延読み込み:


<style>/* Above-fold styles */</style>


<link rel="preload" href="/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles.css"></noscript>
JavaScript の最適化

重要でないスクリプトの遅延実行:


<script src="/critical.js"></script>


<script defer src="/app.js"></script>


<script async src="/analytics.js"></script>


<script type="module" src="/app.mjs"></script>

コード分割のパターン:

// Route-based splitting
const Dashboard = lazy(() => import('./Dashboard'));

// Component-based splitting
const HeavyChart = lazy(() => import('./HeavyChart'));

// Feature-based splitting
if (user.isPremium) {
  const PremiumFeatures = await import('./PremiumFeatures');
}

ツリーシェイキングのベストプラクティス:

// ❌ Imports entire library
import _ from 'lodash';
_.debounce(fn, 300);

// ✅ Imports only what's needed
import debounce from 'lodash/debounce';
debounce(fn, 300);

画像の最適化

フォーマットの選択
フォーマット用途ブラウザサポート
AVIF写真、最高の圧縮率92%以上
WebP写真、良好なフォールバック97%以上
PNG透過が必要なグラフィック全般対応
SVGアイコン、ロゴ、イラスト全般対応
レスポンシブ画像
<picture>
  
  <source 
    type="image/avif"
    srcset="hero-400.avif 400w,
            hero-800.avif 800w,
            hero-1200.avif 1200w"
    sizes="(max-width: 600px) 100vw, 50vw">
  
  
  <source 
    type="image/webp"
    srcset="hero-400.webp 400w,
            hero-800.webp 800w,
            hero-1200.webp 1200w"
    sizes="(max-width: 600px) 100vw, 50vw">
  
  
  <img 
    src="hero-800.jpg"
    srcset="hero-400.jpg 400w,
            hero-800.jpg 800w,
            hero-1200.jpg 1200w"
    sizes="(max-width: 600px) 100vw, 50vw"
    width="1200" 
    height="600"
    alt="Hero image"
    loading="lazy"
    decoding="async">
</picture>
LCP 画像の優先度

<img 
  src="hero.webp" 
  fetchpriority="high"
  loading="eager"
  decoding="sync"
  alt="Hero">


<img 
  src="product.webp" 
  loading="lazy"
  decoding="async"
  alt="Product">

フォントの最適化

読み込み戦略
/* System font stack as fallback */
body {
  font-family: 'Custom Font', -apple-system, BlinkMacSystemFont, 
               'Segoe UI', Roboto, sans-serif;
}

/* Prevent invisible text */
@font-face {
  font-family: 'Custom Font';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: swap; /* or optional for non-critical */
  font-weight: 400;
  font-style: normal;
  unicode-range: U+0000-00FF; /* Subset to Latin */
}
重要なフォントのプリロード
<link rel="preload" href="/fonts/heading.woff2" as="font" type="font/woff2" crossorigin>
可変フォント
/* One file instead of multiple weights */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
}

キャッシュ戦略

Cache-Control ヘッダー
# HTML (short or no cache)
Cache-Control: no-cache, must-revalidate

# Static assets with hash (immutable)
Cache-Control: public, max-age=31536000, immutable

# Static assets without hash
Cache-Control: public, max-age=86400, stale-while-revalidate=604800

# API responses
Cache-Control: private, max-age=0, must-revalidate
Service Worker によるキャッシュ
// Cache-first for static assets
self.addEventListener('fetch', (event) => {
  if (event.request.destination === 'image' ||
      event.request.destination === 'style' ||
      event.request.destination === 'script') {
    event.respondWith(
      caches.match(event.request).then((cached) => {
        return cached || fetch(event.request).then((response) => {
          const clone = response.clone();
          caches.open('static-v1').then((cache) => cache.put(event.request, clone));
          return response;
        });
      })
    );
  }
});

ランタイムのパフォーマンス

レイアウトスラッシングの回避
// ❌ Forces multiple reflows
elements.forEach(el => {
  const height = el.offsetHeight; // Read
  el.style.height = height + 10 + 'px'; // Write
});

// ✅ Batch reads, then batch writes
const heights = elements.map(el => el.offsetHeight); // All reads
elements.forEach((el, i) => {
  el.style.height = heights[i] + 10 + 'px'; // All writes
});
負荷の高い処理のデバウンス
function debounce(fn, delay) {
  let timeout;
  return (...args) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => fn(...args), delay);
  };
}

// Debounce scroll/resize handlers
window.addEventListener('scroll', debounce(handleScroll, 100));
requestAnimationFrame の使用
// ❌ May cause jank
setInterval(animate, 16);

// ✅ Synced with display refresh
function animate() {
  // Animation logic
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
長いリストの仮想化
// For lists > 100 items, render only visible items
// Use libraries like react-window, vue-virtual-scroller, or native CSS:
.virtual-list {
  content-visibility: auto;
  contain-intrinsic-size: 0 50px; /* Estimated item height */
}

サードパーティスクリプト

読み込み戦略
// ❌ Blocks main thread
<script src="https://analytics.example.com/script.js"></script>

// ✅ Async loading
<script async src="https://analytics.example.com/script.js"></script>

// ✅ Delay until interaction
<script>
document.addEventListener('DOMContentLoaded', () => {
  const observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) {
      const script = document.createElement('script');
      script.src = 'https://widget.example.com/embed.js';
      document.body.appendChild(script);
      observer.disconnect();
    }
  });
  observer.observe(document.querySelector('#widget-container'));
});
</script>
ファサードパターン

<div class="youtube-facade" 
     data-video-id="abc123" 
     onclick="loadYouTube(this)">
  <img src="/thumbnails/abc123.jpg" alt="Video title">
  <button aria-label="Play video">▶</button>
</div>

計測

主要な指標
指標目標ツール
LCP< 2.5sLighthouse, CrUX
FCP< 1.8sLighthouse
Speed Index< 3.4sLighthouse
TBT< 200msLighthouse
TTI< 3.8sLighthouse
テストコマンド
# Lighthouse CLI
npx lighthouse https://example.com --output html --output-path report.html

# Web Vitals library
import {onLCP, onINP, onCLS} from 'web-vitals';
onLCP(console.log);
onINP(console.log);
onCLS(console.log);

参考資料

Core Web Vitals 固有の最適化については、Core Web Vitals を参照してください。

コメント