パフォーマンスTips

アプリケーションのパフォーマンスを向上させるためのヒントとコツを記載します。

フロントエンド最適化

フロントエンドのパフォーマンス改善について記載します。

画像最適化

<!-- WebP フォーマットの使用 -->
<picture>
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" alt="説明">
</picture>

<!-- 遅延読み込み -->
<img src="image.jpg" loading="lazy" alt="説明">

JavaScript最適化

// コード分割
const LazyComponent = React.lazy(() => import('./LazyComponent'));

// メモ化
const MemoizedComponent = React.memo(({ data }) => {
  return <div>{data}</div>;
});

// useMemo の活用
const expensiveValue = useMemo(() => {
  return computeExpensiveValue(props.data);
}, [props.data]);

CSS最適化

/* クリティカルCSS の分離 */
/* critical.css - above the fold content */
.header { /* スタイル */ }
.hero { /* スタイル */ }

/* non-critical.css - 遅延読み込み */
.footer { /* スタイル */ }

バックエンド最適化

サーバーサイドのパフォーマンス改善について記載します。

データベース最適化

-- インデックスの作成
CREATE INDEX idx_user_email ON users(email);
CREATE INDEX idx_post_created_at ON posts(created_at);

-- クエリの最適化
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'example@email.com';

キャッシュ戦略

# Redis を使用したキャッシュ
import redis

cache = redis.Redis(host='localhost', port=6379, db=0)

def get_user_data(user_id):
    # キャッシュから取得を試行
    cached_data = cache.get(f"user:{user_id}")
    if cached_data:
        return json.loads(cached_data)
    
    # データベースから取得
    user_data = fetch_user_from_db(user_id)
    
    # キャッシュに保存(1時間)
    cache.setex(f"user:{user_id}", 3600, json.dumps(user_data))
    
    return user_data

API最適化

// GraphQL での効率的なデータ取得
query GetUserPosts($userId: ID!) {
  user(id: $userId) {
    name
    posts(limit: 10) {
      title
      createdAt
    }
  }
}

// REST API でのページネーション
GET /api/posts?page=1&limit=20&sort=createdAt:desc

メモリ管理

効率的なメモリ使用について記載します。

メモリリークの防止

// イベントリスナーの適切な削除
useEffect(() => {
  const handleScroll = () => {
    // スクロール処理
  };
  
  window.addEventListener('scroll', handleScroll);
  
  // クリーンアップ
  return () => {
    window.removeEventListener('scroll', handleScroll);
  };
}, []);

ガベージコレクション

各言語でのガベージコレクション最適化について記載します。

並行処理・非同期処理

パフォーマンス向上のための並行処理について記載します。

Promise の並列実行

// 逐次実行(遅い)
const result1 = await fetchData1();
const result2 = await fetchData2();

// 並列実行(早い)
const [result1, result2] = await Promise.all([
  fetchData1(),
  fetchData2()
]);

ワーカースレッド

// Web Worker の使用
const worker = new Worker('worker.js');

worker.postMessage({ data: heavyData });

worker.onmessage = (event) => {
  console.log('Worker result:', event.data);
};

監視とプロファイリング

パフォーマンスの監視方法について記載します。

Web Vitals

// Core Web Vitals の測定
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';

getCLS(console.log);
getFID(console.log);
getFCP(console.log);
getLCP(console.log);
getTTFB(console.log);

APM ツール

アプリケーションパフォーマンス監視ツールの設定について記載します。

ベンチマーク

パフォーマンステストの実行方法について記載します。

負荷テスト

# Apache Bench
ab -n 1000 -c 10 http://localhost:3000/

# Artillery
artillery run load-test.yml

パフォーマンステスト

// Jest でのパフォーマンステスト
test('function should execute within 100ms', async () => {
  const start = Date.now();
  await myFunction();
  const end = Date.now();
  
  expect(end - start).toBeLessThan(100);
});

最適化のベストプラクティス

一般的な最適化のベストプラクティスを記載します。

  1. 測定してから最適化: 推測ではなく実際の測定に基づく

  2. ボトルネックの特定: 最も影響の大きい部分を優先

  3. 段階的な改善: 小さな改善を積み重ねる

  4. 継続的な監視: パフォーマンスの継続的な監視