Chuyển đến nội dung chính

レッスン 27: パフォーマンスの最適化 — フロントエンドとバックエンド

フロントエンド: コード分割、遅延読み込み MFE、共有依存関係の重複排除、CDN キャッシュ戦略。バックエンド: 接続プーリング、キャッシュ層 (Redis)、データベース クエリの最適化、非同期処理。パフォーマンス予算の執行。

🏗️ 建築 — レッスン 27 レッスン 27: パフォーマンスの最適化 — フロントエンドとバックエンド

マイクロサービスとマイクロ フロントエンドのシステム設計 — 基本から運用まで

パート 9: 可観測性と実稼働の準備状況

xdev.asia

はじめに

マイクロ フロントエンド + マイクロサービスにより、多くのネットワーク呼び出し、重複コード、複数のバンドルなどのオーバーヘッドが追加されます。この記事では、ブラウザからデータベースまでの両方のレベルでパフォーマンスを最適化します。


1. フロントエンドのパフォーマンス

1.1 モジュールフェデレーションの最適化

Vấn đề: 5 MFEs, mỗi MFE load remoteEntry.js + chunks

Giải pháp:
├── Shared dependencies: React loaded 1 lần (singleton)
├── Lazy loading: MFE load khi navigate đến route
├── Prefetch: Prefetch MFE khi user hover nav link
└── CDN caching: Cache remoteEntry.js (short TTL) + chunks (long TTL)

1.2 コード分割戦略

// Per-route code splitting
const ProductList = React.lazy(() => import('product/ProductList'));
const ProductDetail = React.lazy(() => import('product/ProductDetail'));

// Load riêng, chỉ khi cần
<Route path="/products" element={
  <Suspense fallback={<ProductListSkeleton />}>
    <ProductList />
  </Suspense>
} />

1.3 CDN キャッシング

Cache Strategy:
├── remoteEntry.js: Cache 5 min (changes on deploy)
├── Chunk files (hashed): Cache 1 year (immutable)
├── CSS files (hashed): Cache 1 year
├── Images: Cache 1 month
└── API responses: Vary by user (no CDN cache)
Cache-Control headers:
remoteEntry.js: public, max-age=300, must-revalidate
chunk-abc123.js: public, max-age=31536000, immutable

1.4 パフォーマンスの予算

Per MFE:
├── JS Bundle: max 200KB gzipped
├── CSS: max 30KB gzipped
├── LCP: < 2.5s
├── FID: < 100ms
├── CLS: < 0.1
└── Total Load Time: < 3s (on 3G)

2. バックエンドのパフォーマンス

2.1 キャッシュ層

Request Flow with Caching:

Browser Cache ← CDN Cache ← API Gateway Cache ← BFF Cache ← Service Cache ← DB
     (1)          (2)           (3)               (4)          (5)

Layer 1: Browser - HTTP cache headers
Layer 2: CDN - Static assets + API GET responses
Layer 3: Gateway - Rate limiting cache
Layer 4: BFF - Aggregated response cache (Redis)
Layer 5: Service - Entity cache (Redis)

2.2 Redis キャッシュ パターン

// Cache-Aside Pattern
async function getProduct(id) {
  // 1. Check cache
  const cached = await redis.get(`product:${id}`);
  if (cached) return JSON.parse(cached);
  
  // 2. Cache miss → query DB
  const product = await db.query('SELECT * FROM products WHERE id = $1', [id]);
  
  // 3. Set cache (TTL 5 min)
  await redis.set(`product:${id}`, JSON.stringify(product), 'EX', 300);
  
  return product;
}

// Cache Invalidation on Update
async function updateProduct(id, data) {
  await db.query('UPDATE products SET ...', [data, id]);
  await redis.del(`product:${id}`);  // Invalidate
  await redis.del('products:list');    // Invalidate list cache
}

2.3 接続プーリング

// PostgreSQL connection pool
const pool = new Pool({
  max: 20,               // Max connections
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
});

// Reuse connections, don't create per request
app.get('/api/products', async (req, res) => {
  const client = await pool.connect();
  try {
    const { rows } = await client.query('SELECT * FROM products LIMIT 20');
    res.json(rows);
  } finally {
    client.release(); // Return to pool
  }
});

2.4 データベースクエリの最適化

-- Compound index cho frequently queried patterns
CREATE INDEX idx_products_category_price ON products(category_id, price);

-- Partial index cho active products only
CREATE INDEX idx_products_active ON products(id) WHERE is_active = true;

-- Cover index (avoid table lookup)
CREATE INDEX idx_orders_user_status ON orders(user_id, status) 
  INCLUDE (total, created_at);

3. 非同期処理

Move heavy work off critical path:

Synchronous (user waits):
├── Validate order
├── Reserve payment
└── Return order ID

Asynchronous (background):
├── Send confirmation email → Message Queue
├── Generate invoice PDF → Message Queue
├── Update analytics → Event Stream
├── Resize product images → Message Queue
└── Send push notification → Message Queue

4. パフォーマンス監視ダッシュボード

Grafana Dashboard:
┌─────────────────────────────────────┐
│ Frontend Metrics                    │
│ LCP: 1.8s │ FID: 45ms │ CLS: 0.05 │
├─────────────────────────────────────┤
│ Backend Metrics                     │
│ p50: 50ms │ p95: 200ms │ p99: 500ms│
├─────────────────────────────────────┤
│ Cache Hit Rate                      │
│ Redis: 92% │ CDN: 85% │ Browser: 70%│
├─────────────────────────────────────┤
│ Error Rate                          │
│ 5xx: 0.1% │ 4xx: 2.3% │ Timeout:0%│
└─────────────────────────────────────┘

概要

レイヤー最適化影響
フロントエンド遅延読み込み、共有 Deps、CDNページの読み込みが高速化
キャッシングRedis、CDN、ブラウザキャッシュ待ち時間の短縮
データベースインデックス、接続プールクエリの高速化
非同期負荷の高い作業のためのメッセージ キュー応答時間の短縮
モニタリングパフォーマンス バジェット、アラート劣化を防ぐ

次の記事: レッスン 28: 本番準備チェックリスト — セキ​​ュリティ、信頼性、コンプライアンス