Optimasi Performa Claude Code: dari Pengukuran ke Core Web Vitals
Ukur dan perbaiki LCP, INP, latensi API, bundle, dan cache dengan Claude Code serta contoh yang bisa dijalankan.
Optimasi performa web app bukan sekadar membuat aplikasi “terasa lebih cepat”. Artinya adalah mengukur berapa lama user menunggu, apa yang memblokir interaksi, bagian mana yang membuat layout bergeser, dan resource server apa yang terbuang. Setelah itu, kita menurunkannya dengan perubahan kecil yang bisa dibuktikan.
Claude Code cocok untuk pekerjaan ini karena bisa membaca kode, menelusuri bottleneck, mengusulkan patch, dan menulis langkah verifikasi. Urutannya tetap penting: ukur dulu, buat hipotesis, ubah satu hal, lalu ukur lagi dengan cara yang sama.
Gunakan referensi resmi sebagai dasar: web.dev Core Web Vitals, Lighthouse docs, dan MDN Performance API.
Definisikan Cepat Terlebih Dahulu
Performa web bukan satu skor tunggal. LCP, Largest Contentful Paint, mengukur kapan konten utama terlihat. INP, Interaction to Next Paint, mengukur seberapa responsif UI setelah klik, tap, atau input. CLS, Cumulative Layout Shift, mengukur pergeseran layout yang tidak diharapkan.
Di level aplikasi, lihat juga latensi API p75, jumlah query database, ukuran bundle JavaScript, transfer gambar, dan pekerjaan sinkron di main thread browser. Rata-rata sering menyembunyikan user yang lambat; p75 lebih praktis untuk melihat pengalaman mayoritas yang kurang baik.
flowchart LR
Measure["Ukur"] --> Hypothesis["Buat hipotesis"]
Hypothesis --> Patch["Ubah kecil"]
Patch --> Verify["Ukur lagi"]
Verify --> Keep["Simpan yang terbukti"]
| Metrik | Makna | Target awal |
|---|---|---|
| LCP | Konten utama terlihat | 2.5s atau kurang |
| INP | Respons interaksi | 200ms atau kurang |
| CLS | Pergeseran layout | 0.1 atau kurang |
| API p75 | Latensi yang dirasakan banyak user | Tentukan per layar |
| JS transfer | JavaScript yang dimuat awal | Bandingkan per route |
Beri Input Yang Baik Ke Claude Code
Prompt yang bagus berisi gejala, cara reproduksi, angka saat ini, dan batasan.
Halaman /products di repository ini lambat.
Targetnya menurunkan mobile LCP dan p75 /api/products.
Pengukuran saat ini:
- Lighthouse mobile Performance: 58
- LCP: 4.2s
- INP: 180ms
- CLS: 0.04
- /api/products p75: 920ms
Tolong:
1. Periksa gambar, bundle, API, dan akses database.
2. Jangan mengubah kode hanya berdasarkan tebakan; tulis file dan bukti.
3. Prioritaskan patch kecil yang bisa diukur.
4. Sertakan command untuk verifikasi setelah perubahan.
Bacaan terkait: panduan debugging Claude Code, pengembangan React dengan Claude Code, dan panduan optimasi gambar Claude Code.
Script Pengukuran Yang Bisa Dijalankan
Dengan Node.js 18+, script ini mengukur halaman atau API dan menampilkan rata-rata serta p75.
// measure-url.mjs
import { performance } from "node:perf_hooks";
const url = process.argv[2] ?? "https://example.com/";
const runs = Number(process.argv[3] ?? 5);
async function measureOnce() {
const start = performance.now();
const res = await fetch(url, { cache: "no-store" });
await res.arrayBuffer();
return {
status: res.status,
ms: performance.now() - start,
};
}
const samples = [];
for (let i = 0; i < runs; i += 1) {
samples.push(await measureOnce());
}
samples.sort((a, b) => a.ms - b.ms);
const avg = samples.reduce((sum, s) => sum + s.ms, 0) / samples.length;
const p75Index = Math.floor((samples.length - 1) * 0.75);
const p75 = samples[p75Index].ms;
console.table(
samples.map((sample, index) => ({
run: index + 1,
status: sample.status,
ms: sample.ms.toFixed(1),
}))
);
console.log(`avg=${avg.toFixed(1)}ms p75=${p75.toFixed(1)}ms`);
node measure-url.mjs http://localhost:3000/api/products 7
Berikan output ini ke Claude Code sebelum dan sesudah patch. Diskusi performa berubah dari perasaan menjadi perbandingan yang bisa diulang.
Use Case Realistis
| Use case | Penyebab umum | Yang diminta ke Claude Code |
|---|---|---|
| Dashboard SaaS lambat | Semua widget fetch saat awal; library chart besar | Tunda widget sekunder dan split kode chart |
| Listing ecommerce lambat | Gambar besar dan query N+1 untuk stok/review | Perbaiki ukuran gambar dan include/select database |
| Artikel media LCP buruk | Hero image terlambat; script iklan terlalu awal | Prioritaskan gambar utama dan tunda script pihak ketiga |
| Search admin freeze | Array besar difilter sinkron di main thread | Turunkan kompleksitas, paginasi, atau pindahkan pekerjaan |
N+1 berarti aplikasi mengambil list sekali, lalu menjalankan query tambahan untuk setiap baris. Cache berarti memakai ulang hasil untuk waktu singkat, tetapi data user, permission, harga, dan stok tidak boleh masuk shared cache tanpa key, TTL, dan invalidation yang jelas.
Contoh Cache Yang Bisa Dijalankan
Contoh Express ini membandingkan endpoint yang sengaja dibuat lambat dengan endpoint yang memakai cache. Produksi sering memakai Redis atau CDN, tetapi memory cache cukup untuk memahami efeknya.
npm init -y
npm install express
node cached-api.mjs
// cached-api.mjs
import express from "express";
import { performance } from "node:perf_hooks";
const app = express();
const cache = new Map();
const ttlMs = 30_000;
async function loadProducts() {
await new Promise((resolve) => setTimeout(resolve, 800));
return [
{ id: 1, name: "Starter Plan", price: 1200 },
{ id: 2, name: "Pro Plan", price: 4800 },
];
}
async function cached(key, loader) {
const now = Date.now();
const hit = cache.get(key);
if (hit && hit.expiresAt > now) return { data: hit.data, cache: "hit" };
const data = await loader();
cache.set(key, { data, expiresAt: now + ttlMs });
return { data, cache: "miss" };
}
app.get("/api/products/raw", async (_req, res) => {
const start = performance.now();
const data = await loadProducts();
res.json({ cache: "none", ms: performance.now() - start, data });
});
app.get("/api/products/cached", async (_req, res) => {
const start = performance.now();
const result = await cached("products", loadProducts);
res.json({ ...result, ms: performance.now() - start });
});
app.listen(3000, () => {
console.log("Open http://localhost:3000/api/products/raw");
});
node measure-url.mjs http://localhost:3000/api/products/raw 3
node measure-url.mjs http://localhost:3000/api/products/cached 3
Saat meminta Claude Code menambah cache, tulis cakupannya: produk populer 30 detik, stok tidak dicache, data user memakai userId di key.
Contoh Algoritma Yang Bisa Dijalankan
Bottleneck tidak selalu di network. JavaScript sinkron yang berat bisa memperburuk INP. Contoh ini mengganti scan includes berulang dengan Set.
// compare-lookup.mjs
import { performance } from "node:perf_hooks";
const a = Array.from({ length: 40_000 }, (_, i) => i);
const b = Array.from({ length: 40_000 }, (_, i) => i * 2);
function slowIntersection(left, right) {
return left.filter((item) => right.includes(item));
}
function fastIntersection(left, right) {
const rightSet = new Set(right);
return left.filter((item) => rightSet.has(item));
}
function time(label, fn) {
const start = performance.now();
const result = fn();
const ms = performance.now() - start;
console.log(`${label}: ${ms.toFixed(1)}ms (${result.length} hits)`);
}
time("slow", () => slowIntersection(a, b));
time("fast", () => fastIntersection(a, b));
node compare-lookup.mjs
Kesalahan Umum
Jangan optimasi hanya untuk skor Lighthouse. Lighthouse adalah data lab; user nyata punya perangkat, jaringan, dan cache yang berbeda. Gabungkan dengan Search Console, RUM, dan log server.
Jangan menambah cache tanpa aturan kebenaran data. Harga, stok, permission, dan data personal butuh key, TTL, dan invalidation.
Jangan memakai useMemo di semua tempat. Memoization React sebaiknya dipakai pada hot path yang sudah diukur.
Jangan membuat semua gambar priority. Gambar above-the-fold perlu ukuran stabil dan kadang priority, tetapi gambar di bawahnya biasanya tetap lazy.
Jangan split bundle secara buta. Gunakan analisis bundle Claude Code dan code splitting Claude Code untuk membandingkan dampak per route.
Aturan CLAUDE.md
## Performance rules
- Before optimizing, record the current metric and target metric.
- Prefer small, measurable changes over broad rewrites.
- Do not introduce shared cache for user-specific data.
- Avoid N+1 queries; use select/include or batching.
- Keep above-the-fold images sized and stable.
- After changes, report commands used for verification.
Aturan ini membuat Claude Code fokus pada improvement yang bisa dibuktikan.
CTA Konsultasi
ClaudeCodeLab dapat membantu audit performa web app dengan Claude Code, memperbaiki Core Web Vitals, memisahkan latensi API/DB, dan membuat runbook optimasi praktis. Untuk review awal, siapkan URL target, layar utama, hasil Lighthouse, log API lambat, dan tenggat perbaikan.
Hasil Uji Langsung
Saat dijalankan lokal, /api/products/raw tetap sekitar 800ms karena delay sengaja, sedangkan /api/products/cached turun ke beberapa milidetik setelah request pertama. compare-lookup.mjs juga menunjukkan versi Set jauh lebih cepat. Proyek nyata tidak selalu serapi itu, tetapi polanya sama: ukur p75, ubah satu hal, lalu ukur lagi dengan alat yang sama.
PDF gratis: cheatsheet Claude Code
Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.
Kami menjaga datamu dan tidak mengirim spam.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.
Artikel terkait
Permission receipt Claude Code: mencatat scope, bukti, dan rollback
Pola permission receipt untuk Claude Code: aksi yang diizinkan, batas approval, command verifikasi, rollback, dan cek CTA revenue.
Agent Harness Aman untuk Claude Code dan Codex: Permission, Verifikasi, dan Rollback
Rancang Agent Harness praktis untuk Claude Code dan Codex dengan policy, plan, verification, dan recovery layer.
Subagent Claude Code: panduan praktis untuk delegasi artikel dan kode
Panduan subagent Claude Code untuk membagi pekerjaan artikel dan kode: aturan delegasi, prompt, risiko, dan checklist.