簡介
微前端 + 微服務增加了開銷:許多網路呼叫、重複程式碼、多個捆綁包。本文優化了從瀏覽器到資料庫兩個層級的效能。
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%│
└─────────────────────────────────────┘
總結
| 層 | 優化 | 影響 |
|---|---|---|
| 前端 | 延遲載入、共享依賴、CDN | 更快的頁面載入 |
| 快取 | Redis、CDN、瀏覽器快取 | 減少延遲 |
| 資料庫 | 索引、連接池 | 更快的查詢 |
| 非同步 | 繁重工作的訊息佇列 | 縮短回應時間 |
| 監控 | 績效預算、警報 | 防止降解 |
下一篇文章: 第 28 課:生產準備清單 — 安全性、可靠性和合規性