Przejdź do głównej zawartości

Analiza wydajności z terminala

Twoje API średnio odpowiadało w 120ms trzy miesiące temu. Dzisiaj to 1.8 sekundy. Nikt nie zmienił niczego oczywistego — żaden pojedynczy commit nie wskazuje winowajcy. Zespół produktowy pyta, dlaczego dashboard jest ospały. Zespół infrastruktury już podwoił liczbę serwerów i nie przyniosło to żadnej różnicy. Musisz znaleźć wąskie gardło, ale narzędzia profilowania mają krzywą uczenia się, a ty potrzebujesz odpowiedzi dzisiaj po południu.

  • Workflow Claude Code do profilowania wydajności Node.js, Python i baz danych z terminala bez instalowania dedykowanych narzędzi APM
  • Prompty do skopiowania identyfikujące zapytania N+1, nieindeksowane skany tabel, wycieki pamięci i przewymiarowane bundle w twoim kodzie
  • Systematyczne podejście do optymalizacji wydajności: mierz, identyfikuj, napraw, zweryfikuj

Zanim zaczniesz cokolwiek optymalizować, potrzebujesz danych. Claude Code może zinstrumentować twoją aplikację do zbierania danych czasowych bez konieczności korzystania z dostawcy APM.

Po wygenerowaniu instrumentacji przez Claude, uruchom ją na kilku reprezentatywnych zapytaniach:

Okno terminala
PERF_TRACE=1 node dist/index.js &
curl http://localhost:3000/api/users
curl http://localhost:3000/api/orders?limit=100
curl http://localhost:3000/api/dashboard

Następnie przekaż wyniki z powrotem do Claude Code:

Here are the performance logs from three API endpoints. Identify which endpoint is slowest, which phase (database, external API, business logic) is the bottleneck, and suggest specific optimizations. Show me the exact queries or function calls that need attention.

Ta pętla zwrotna — instrumentuj, mierz, analizuj, napraw — to podstawowy workflow. Claude Code zajmuje się uciążliwą instrumentacją, podczas gdy ty koncentrujesz się na zrozumieniu wyników.

Najczęstszym problemem wydajnościowym jest baza danych. Wolne zapytania, brakujące indeksy i wzorce N+1 odpowiadają za większość opóźnień backendu.

Claude Code czyta definicje modeli ORM, pliki migracji i handlery tras, aby zbudować kompletny obraz. Na przykład może znaleźć:

// Before: N+1 -- one query per order to fetch the user
const orders = await db.query('SELECT * FROM orders WHERE status = $1', ['pending']);
for (const order of orders) {
const user = await db.query('SELECT * FROM users WHERE id = $1', [order.userId]);
order.user = user;
}
// After: Single query with JOIN
const orders = await db.query(`
SELECT o.id, o.total, o.status, u.name, u.email
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE o.status = $1
`, ['pending']);

Po naprawieniu zapytań poproś Claude Code o wygenerowanie brakujących indeksów:

Based on the queries in our codebase, generate a migration file that adds indexes for all columns used in WHERE clauses, JOIN conditions, and ORDER BY clauses that do not already have indexes. Use CREATE INDEX CONCURRENTLY to avoid locking the table.

Dla endpointów, które są wolne, ale zapytania bazodanowe wyglądają dobrze, problem często tkwi w logice biznesowej — transformacji danych, serializacji lub niepotrzebnych obliczeniach.

Profile our /api/dashboard endpoint. It currently takes 3 seconds. Trace the execution path from the route handler through every function it calls. For each function, estimate the time complexity based on the data structures used. Identify any: 1) nested loops over large arrays, 2) synchronous operations that should be async, 3) repeated computation that could be cached, 4) unnecessary data fetching (fields computed but never sent to the client).

Claude Code prześledzi łańcuch wywołań i oznaczy wzorce takie jak:

  • map wewnątrz filter wewnątrz innego map, które mogłoby być jednym przejściem
  • Funkcja pobierająca preferencje użytkownika przy każdym zapytaniu, podczas gdy zmieniają się raz dziennie
  • Serializacja JSON ogromnego obiektu, gdy klient używa tylko trzech pól

Wydajność backendu to tylko połowa historii. Jeśli twój bundle JavaScript waży 2 MB, przeglądarka ciężko pracuje, zanim użytkownik zobaczy cokolwiek.

Jeśli twój projekt używa webpack lub Vite, Claude Code może również wygenerować konfigurację analizy:

Add webpack-bundle-analyzer (or rollup-plugin-visualizer for Vite) to our build and generate a treemap HTML report. Also add a CI check that fails if the main bundle exceeds 200 KB gzipped.

Wycieki pamięci są notorycznie trudne do znalezienia, ponieważ objawiają się powoli. Claude Code może przejrzeć twój kod pod kątem typowych wzorców wycieków bez konieczności robienia heap dumpa.

Review our Node.js application for memory leak patterns. Check for: 1) event listeners added in request handlers but never removed, 2) closures that capture large objects and prevent garbage collection, 3) caches (Maps, arrays) that grow unbounded without eviction, 4) streams that are not properly closed on error, 5) module-level state that accumulates per-request data. For each finding, show the leak pattern and the fix.

Do aktywnego badania wycieków Claude Code może wygenerować skrypt diagnostyczny:

Create a diagnostic endpoint at /debug/memory (only accessible from localhost) that returns: process.memoryUsage(), the count of active event listeners on the global event bus, the sizes of all in-memory caches, and active timer/interval counts. Also create a script that hits this endpoint every 30 seconds and writes the data to a CSV file so we can graph memory growth over time.

Po optymalizacji musisz zweryfikować poprawę pod realistycznym obciążeniem. Claude Code może wygenerować skrypty testów obciążeniowych.

Generate a k6 load test script for our API that simulates realistic traffic: 70% reads (GET /api/products with pagination), 20% writes (POST /api/orders with a realistic order payload), 10% search (GET /api/search?q=random_term). Ramp up from 10 to 200 virtual users over 5 minutes, hold for 10 minutes, then ramp down. Assert that p95 response time stays under 500ms and error rate stays under 0.1%.

Uruchom test przed i po optymalizacji, aby skwantyfikować poprawę. Przekaż wyniki z powrotem do Claude Code do analizy:

Here are the k6 results from before and after our optimization. Summarize the improvement in a table showing p50, p95, p99 latency, requests per second, and error rate. Identify any endpoints that did not improve and suggest next steps.

Sama instrumentacja spowalnia aplikację. Opakowywanie każdej funkcji kodem mierzącym czas dodaje narzut. Użyj przełącznika PERF_TRACE, aby trzymać go wyłączonego na produkcji. Dla zawsze włączonego monitorowania użyj samplowania: “Update the instrumentation to only measure 1% of requests in production, selected randomly.”

Claude sugeruje indeks, ale migracja blokuje tabele. Na dużych tabelach CREATE INDEX może zablokować zapisy na minuty. Zawsze używaj CREATE INDEX CONCURRENTLY w PostgreSQL. Poproś Claude Code: “This table has 50 million rows and serves write traffic. Generate the index creation as a concurrent, non-locking migration.”

Naprawa N+1 wprowadza masywny JOIN. Czasami joinowanie pięciu tabel jest gorsze niż pięć małych zapytań, szczególnie przy dużych zbiorach wyników. Po wygenerowaniu optymalizacji przez Claude, uruchom EXPLAIN ANALYZE na nowym zapytaniu i wklej wynik: “Here is the EXPLAIN ANALYZE output for the optimized query. Is this plan efficient or should we use a different strategy like a subquery or materialized view?”

Dzielenie bundla spowalnia początkowe ładowanie przez wodospad zapytań. Agresywne dzielenie kodu może tworzyć zbyt wiele małych chunków ładowanych sekwencyjnie. Powiedz Claude o swoim ograniczeniu: “We want at most 5 chunks on the critical path. Merge the route-level chunks for the three most visited pages into the main bundle and only lazy-load the rest.”