Console.log() to przeszłość — debugowanie JS jak doświadczony programista

Poznaj skuteczniejsze metody debugowania JavaScript niż samo console.log. Breakpoints, logpoints, Network, Performance, Memory i workflow pracy w DevTools.

Opublikowano

19 grudnia 2025 15:02

Czytanie

8 min czytania

Aktualizacja

15 kwietnia 2026 11:52

console.log() jest jak śrubokręt. Przydaje się często, ale nie chcesz nim robić wszystkiego. Problem zaczyna się wtedy, gdy staje się jedyną metodą debugowania: log tutaj, log tam, odśwież, kolejny log, zgaduj dalej.

To normalny etap. Sam pracowałem tak długo. Tyle że nowoczesne DevTools pozwalają debugować dużo precyzyjniej: zatrzymać wykonanie w konkretnym momencie, sprawdzić stan aplikacji, podejrzeć requesty, zmierzyć wydajność i znaleźć wycieki pamięci bez zasypywania kodu tymczasowymi logami.

Chrome DevTools i ich odpowiedniki w Edge czy Firefoxie zmieniają debugowanie z "strzału w ciemno" w kontrolowaną analizę. W tym artykule pokażę techniki, które realnie skracają czas dochodzenia do przyczyny problemu.

Krótka odpowiedź: Zamiast polegać wyłącznie na console.log(), używaj breakpointów i logpointów w DevTools, które pozwalają zatrzymać wykonanie kodu i zbadać stan aplikacji bez modyfikowania źródeł. Do problemów z requestami HTTP sięgaj po panel Network, do wydajności — Performance, do wycieków pamięci — Memory. Podejście systematyczne (hipoteza → breakpoint → inspekcja → iteracja) skraca czas diagnozy bardziej niż znajomość konkretnych trików.

Zanim zaczniemy: skróty klawiszowe

Code
F12 lub Ctrl+Shift+I  → Otwórz DevTools
Ctrl+Shift+P          → Command Palette (jak w VS Code)
Ctrl+P                → Szybkie otwieranie plików
Ctrl+Shift+F          → Szukaj we wszystkich plikach
Esc                   → Toggle Console drawer

Zapamiętaj te skróty. Reszta przyjdzie z praktyką.

1. Lepsze console.log() — metody, o których nie wiesz

Zanim porzucimy console.log(), poznajmy jego pełne możliwości:

console.table() — czytelne tablice i obiekty

Code
const users = [
  { name: 'Jan', age: 25, role: 'admin' },
  { name: 'Anna', age: 30, role: 'user' },
  { name: 'Piotr', age: 28, role: 'user' },
]
 
// ❌ Nieczytelne
console.log(users)
 
// ✅ Czytelna tabelka
console.table(users)

Możesz też wybrać kolumny:

Code
console.table(users, ['name', 'role'])

console.group() — organizacja logów

Code
console.group('User Authentication')
console.log('Checking credentials...')
console.log('Token valid')
console.groupEnd()
 
console.group('Data Fetch')
console.log('Fetching posts...')
console.log('Received 42 posts')
console.groupEnd()

Użyj console.groupCollapsed(), jeśli grup ma być dużo i nie chcesz zalewać konsoli.

console.time() — pomiar czasu

Code
console.time('fetchUsers')
const users = await fetchUsers()
console.timeEnd('fetchUsers')  // fetchUsers: 234.5ms

console.trace() — skąd to wywołanie?

Code
function deepFunction() {
  console.trace('How did we get here?')
}

Wyświetla pełny call stack.

console.assert() — warunkowe logowanie

Code
// Wyświetla tylko gdy warunek jest false
console.assert(user.age >= 18, 'User is underage:', user)

Stylowanie logów

Code
console.log(
  '%cWażne!%c To jest ostrzeżenie',
  'color: red; font-weight: bold; font-size: 16px',
  'color: orange'
)

2. Breakpoints — zatrzymaj czas

Breakpoints to najpotężniejsze narzędzie debugowania. Pozwalają zatrzymać wykonanie kodu i zbadać stan aplikacji.

Podstawowe breakpoints

  1. Otwórz DevTools → Sources
  2. Znajdź plik (Ctrl+P)
  3. Kliknij na numer linii

Gdy kod dojdzie do tej linii, wykonanie się zatrzyma. Możesz:

  • Sprawdzić wartości zmiennych (panel Scope)
  • Wykonać kod krok po kroku (F10 = next, F11 = step into)
  • Kontynuować (F8)

Conditional breakpoints

Prawy klik na breakpoint → "Edit breakpoint":

Code
// Zatrzymaj tylko gdy userId === 42
userId === 42
 
// Zatrzymaj tylko co 10. iterację
i % 10 === 0

Logpoints — console.log bez edycji kodu

Prawy klik na numer linii → "Add logpoint":

Code
// Wpisz wyrażenie do zalogowania
'User:', user.name, 'Age:', user.age

Kod nie jest modyfikowany, log pojawia się w konsoli gdy wykonanie przechodzi przez tę linię.

DOM breakpoints

W panelu Elements, prawy klik na element:

  • Subtree modifications — gdy dzieci się zmieniają
  • Attribute modifications — gdy atrybuty się zmieniają
  • Node removal — gdy element jest usuwany

Idealne do debugowania "kto zmienia mój DOM?".

Event listener breakpoints

Sources → Event Listener Breakpoints:

  • Mouse → click
  • Keyboard → keydown
  • XHR → readystatechange

Zatrzymaj się przy każdym kliknięciu, bez szukania handlera w kodzie.

Exception breakpoints

Sources → Breakpoints → ✓ "Pause on uncaught exceptions"

Automatycznie zatrzymuje się gdy leci błąd, zanim konsola go wyświetli.

W trudniejszych przypadkach warto włączyć też Pause on caught exceptions. To pomaga, gdy aplikacja łapie błąd wewnętrznie i tylko "cicho" psuje stan UI, czyli User Interface, to wizualna i interakcyjna warstwa produktu..

3. Watch expressions — śledź zmienne

W panelu Sources → Watch, dodaj wyrażenia do śledzenia:

Code
user.isAuthenticated
cart.items.length
window.innerWidth

Wartości aktualizują się w czasie rzeczywistym podczas debugowania.

4. Call Stack — rozumienie flow

Gdy kod jest zatrzymany na breakpoint, panel Call Stack pokazuje:

  • Która funkcja wywołała którą
  • Z jakiego pliku i linii
  • Możesz kliknąć na dowolną ramkę żeby zobaczyć jej kontekst

5. Network panel — debugowanie requestów

Filtrowanie

  • method:POST — tylko POST requesty
  • domain:api.example.com — tylko ta domena
  • larger-than:1M — pliki większe niż 1MB
  • -type:image — wszystko oprócz obrazków

W SPA, czyli Single Page Application, działa bez pełnego przeładowania dokumentu przy każdej nawigacji. bardzo przydaje się też:

  • Preserve log — zachowaj requesty po nawigacji
  • Disable cache — wyłącz cache, gdy DevTools są otwarte

Podgląd requestu

Kliknij na request:

  • Headersnagłówki, status code
  • Payload — wysłane dane
  • Preview — odpowiedź (sformatowana)
  • Response — surowa odpowiedź
  • Timing — ile trwały poszczególne fazy

Copy as fetch/cURL

Prawy klik na request → Copy → Copy as fetch

Code
// Wklej do konsoli i zmodyfikuj
fetch("https://api.example.com/users", {
  headers: { "Authorization": "Bearer ..." },
  method: "GET",
})

Throttling

Symuluj wolne połączenie:

  • Network → No throttling → Slow 3G

Sprawdź, jak aplikacja działa na słabym internecie. To szczególnie ważne przy debugowaniu loaderów, skeletonów i błędów w sekwencji requestów.

Block requests

Prawy klik na request → Block request URL

Sprawdź jak aplikacja radzi sobie gdy API, czyli Application Programming Interface, definiuje sposób komunikacji między aplikacjami lub modułami. nie odpowiada.

6. Performance panel — znajdź wąskie gardła

Nagrywanie

  1. Performance → Record (Ctrl+E)
  2. Wykonaj akcję w aplikacji
  3. Stop

Analiza

  • Flame chart — co zajmuje czas
  • Main thread — czy jest blokowany
  • Network timeline — kolejność requestów
  • Frames — czy są frame drops

Szukaj:

  • Długich tasków (czerwone trójkąty) — wpływają na INP
  • Forced reflow (fioletowe)
  • Layout thrashing (częste przeliczanie layoutu)

Tip: CPU throttling

Performance → ⚙️ → CPU: 4x slowdown

Symuluj słabszy procesor, szczególnie jeśli próbujesz zrozumieć problemy z responsywnością na mobile.

7. Memory panel — wycieki pamięci

Heap snapshot

  1. Memory → Heap snapshot → Take snapshot
  2. Wykonaj akcję (np. otwórz/zamknij modal)
  3. Take another snapshot
  4. Comparison view — co zostało?

Szukaj:

  • Detached DOM elements — usunięte z DOM, ale wciąż w pamięci
  • Growing arrays — tablice które rosną bez limitu
  • Event listeners — niezdjęte listenery

8. Application panel — storage debugging

Local Storage / Session Storage

  • Podgląd i edycja wartości
  • Clear all

Cookies

  • Wszystkie ciasteczka dla domeny
  • Dodawanie, edycja, usuwanie

Service Workers

  • Status
  • Update
  • Unregister

Cache Storage

  • Podgląd zcachowanych zasobów
  • Manualne czyszczenie

9. Snippets — własne skrypty

Sources → Snippets — zapisz często używane skrypty:

Code
// clear-storage.js
localStorage.clear()
sessionStorage.clear()
document.cookie.split(";").forEach(c => {
  document.cookie = c.replace(/^ +/, "")
    .replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/")
})
console.log('All storage cleared!')

Uruchom: prawy klik → Run (Ctrl+Enter)

10. Live expressions

Console → ikona oka → dodaj wyrażenie:

Code
document.activeElement
performance.memory.usedJSHeapSize / 1048576

Wartość aktualizuje się w czasie rzeczywistym, bez spamowania konsoli. Pamiętaj tylko, że performance.memory jest zależne od przeglądarki i najlepiej działa w Chromium.

11. Overrides — edycja produkcyjnego kodu

Sources → Overrides → Select folder

Możesz edytować JavaScript/CSS na produkcji i zmiany przetrwają odświeżenie (lokalnie). Idealne do testowania fixów przed deployem.

12. Debugging w VS Code

Jeśli wolisz debugować w edytorze:

Code
// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "pwa-chrome",
      "request": "launch",
      "name": "Debug Chrome",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}"
    }
  ]
}

F5 uruchomi Chrome z podłączonym debuggerem VS Code.

Workflow senior developera

  1. Reprodukuj problem — upewnij się że wiesz jak wywołać bug
  2. Sformułuj hipotezę — co może być przyczyną?
  3. Ustaw breakpoint — w miejscu gdzie hipoteza powinna być testowalna
  4. Sprawdź stan — zmienne, call stack, network
  5. Iteruj — jeśli hipoteza zła, sformułuj nową

Zamiast losowego console.log() wszędzie, podejdź do problemu systematycznie. Największa różnica między juniorem a seniorem często nie polega na tym, że senior "zna więcej trików", tylko że szybciej zawęża przestrzeń możliwych przyczyn.

FAQ

Czy console.log() jest złą praktyką?

Nie — console.log() to dobre narzędzie do szybkiego sprawdzenia wartości lub tymczasowego śladu lokalnego. Problem pojawia się, gdy staje się jedyną metodą debugowania: zamiast zatrzymać kod w konkretnym miejscu i zbadać stan, programista dodaje kolejne logi i zgaduje. Do bardziej złożonych problemów DevTools są po prostu skuteczniejsze.

Czym różni się breakpoint od logpointa?

Breakpoint zatrzymuje wykonanie kodu w danej linii — możesz wtedy sprawdzić zmienne, prześledzić call stack i krok po kroku przejść przez kod. Logpoint natomiast tylko wypisuje wyrażenie do konsoli, nie przerywając wykonania. Logpoint jest wygodny gdy nie chcesz modyfikować kodu źródłowego, ale potrzebujesz informacji o wartościach w konkretnym miejscu.

Jak debugować asynchroniczny kod JavaScript?

Ustaw breakpoint wewnątrz callbacku, funkcji async lub handlera Promisa. DevTools obsługuje asynchroniczny call stack — po zatrzymaniu zobaczysz nie tylko aktualną ramkę, ale też skąd zostało wywołanie uruchomione. Możesz też włączyć "Async stack traces" w ustawieniach DevTools dla pełniejszego widoku.

Jak znaleźć wyciek pamięci w JavaScript?

Zrób heap snapshot przed i po podejrzanej operacji (np. otwarcie i zamknięcie modalu), a następnie w widoku "Comparison" sprawdź, które obiekty zostały w pamięci. Szczególnie szukaj "Detached DOM nodes" — elementów usuniętych z drzewa DOM, ale wciąż trzymanych przez closure lub tablicę w JavaScript.

Czy można debugować kod produkcyjny przez DevTools?

Tak, przy użyciu funkcji Overrides (Sources → Overrides). Możesz lokalnie nadpisać pliki JavaScript lub CSS z produkcji, edytować je w przeglądarce i zmiany przetrwają odświeżenie strony. To przydatne do testowania fixów bez deployowania. Pamiętaj, że zmiany są tylko lokalne — dla innych użytkowników produkcja pozostaje niezmieniona.

Czym jest throttling w DevTools i kiedy go używać?

Throttling w panelu Network symuluje wolne połączenie internetowe (np. Slow 3G), a w panelu Performance — wolniejszy procesor (CPU throttling). Używaj go, żeby sprawdzić jak aplikacja zachowuje się na słabszych urządzeniach lub gorszym zasięgu. To szczególnie ważne przy debugowaniu loaderów, skeletonów, INP, czyli Interaction to Next Paint, mierzy jak szybko interfejs reaguje po interakcji użytkownika. i problemów z responsywnością na mobile.

Jak debugować problemy z CSS w DevTools?

W panelu Elements możesz bezpośrednio edytować style — kliknij na regułę CSS w panelu Styles i zmień wartość. Możesz też używać DOM breakpointów (prawy klik na element → Break on → Attribute modifications) żeby złapać skrypt, który dynamicznie zmienia klasy lub style elementu. Panel Computed pokazuje ostateczne wartości po kaskadzie.

Podsumowanie

NarzędzieKiedy używać
console.table/groupOrganizacja logów
BreakpointsZatrzymanie i inspekcja
Conditional breakpointsDebugowanie pętli
LogpointsLogi bez edycji kodu
Watch expressionsŚledzenie zmiennych
Network panelProblemy z API
Performance panelWolna aplikacja
Memory panelWycieki pamięci
OverridesTestowanie fixów na prod

console.log() nadal ma swoje miejsce, zwłaszcza do szybkiego sprawdzenia wartości albo jako tymczasowy telemetryczny ślad w lokalnym środowisku. Ale jeśli problem dotyczy flow wykonania, requestów, wydajności albo pamięci, DevTools są po prostu lepszym narzędziem.

Najlepiej zacząć od trzech rzeczy: breakpoints, logpoints i Network panel. To trio daje największy zwrot z inwestycji praktycznie od razu. Dopiero potem dokładaj Performance i Memory, gdy faktycznie pojawi się problem z wydajnością lub wyciekiem.

Źródła i dokumentacja


Chcesz więcej? Sprawdź 10 sztuczek JavaScript dla czytelniejszego kodu lub poznaj pułapki async/await i jak je naprawić.

Pracuję z tym zawodowo.

Jeśli chcesz przełożyć ten temat na lepszą architekturę frontendu, uporządkować React lub Next.js i podnieść jakość pracy zespołu, skontaktuj się ze mną. Pomagam zamieniać wiedzę z artykułów w praktyczne decyzje technologiczne.

O autorze

Maciej Sala

Maciej Sala — project manager i frontendowiec z doświadczeniem w marketingu internetowym. Na co dzień pracuję z Reactem, Next.js i TypeScriptem, łącząc perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat związany z branżą gier wideo jako project manager i game designer.

Absolwent historii na Uniwersytecie Jagiellońskim i studiów podyplomowych z marketingu internetowego na Akademii Górniczo-Hutniczej w Krakowie. Poza pracą trenuje na siłowni, maluje figurki i realizuje własne projekty.

Biblioteka wiedzy

Czytaj dalej

Zobacz więcej wpisów
Astro.js vs Next.js — które narzędzie wybrać w 2026 roku?

Astro.js vs Next.js — które narzędzie wybrać w 2026 roku?

Fachowe porównanie Astro.js i Next.js z perspektywy developera pracującego na co dzień w Next.js. Architektura, wydajność, SEO, DX, koszty i konkretne use case — z benchmarkami i przykładami kodu.

Maciej Sala

Maciej Sala

Founder Strivelab