Menu
Szybki wybór
Hosting Domeny VPS SSL Kalkulator Porównania FAQ
Aktywne kody
Wszystkie kody rabatowe

PHP profiling z Xdebug 3 — cachegrind i KCachegrind

Opublikowano: 10 kwietnia 2026 · Kategoria: Wydajność

WordPress ładuje się powoli, ale nie wiesz która funkcja to powoduje. Xdebug 3 pozwala nagrać każde wywołanie funkcji PHP z czasem wykonania — plik cachegrind otwierasz w KCachegrind i widzisz dokładnie co zajmuje 80% czasu. Ten przewodnik pokazuje instalację, konfigurację trybu profilowania i interpretację wyników. Na końcu porównanie z Blackfire.io.

Instalacja Xdebug 3

# Ubuntu / Debian — przez pecl lub apt
sudo apt install -y php-xdebug

# Lub przez pecl (najnowsza wersja)
sudo pecl install xdebug

# Sprawdź zainstalowaną wersję
php -v
# PHP 8.2.x (cli) with Xdebug v3.3.x

# Znajdź plik konfiguracyjny PHP
php --ini | grep "Loaded Configuration"
# Zazwyczaj: /etc/php/8.2/cli/php.ini lub /etc/php/8.2/fpm/php.ini

# Znajdź katalog conf.d
php --ini | grep "additional .ini"
# Zazwyczaj: /etc/php/8.2/fpm/conf.d/

# Sprawdź czy Xdebug jest załadowany
php -m | grep xdebug

Konfiguracja xdebug.ini — tryby pracy

Xdebug 3 wprowadził fundamentalną zmianę: jeden parametr xdebug.mode kontroluje wszystkie funkcje. Nie włączaj wielu trybów jednocześnie bez potrzeby — każdy dodaje narzut. Poniżej konfiguracje dla różnych scenariuszy:

# /etc/php/8.2/fpm/conf.d/20-xdebug.ini

[xdebug]
zend_extension = xdebug.so

# ============================================================
# TRYB: profiling — nagrywanie wywołań funkcji do cachegrind
# ============================================================
xdebug.mode = profiling
xdebug.output_dir = /tmp/xdebug        # katalog na pliki cachegrind
xdebug.profiler_output_name = cachegrind.out.%p.%r  # %p=PID, %r=random
xdebug.start_with_request = trigger    # tylko gdy XDEBUG_PROFILE=1 w URL/cookie

# ============================================================
# TRYB: debug — step debugger (VS Code, PhpStorm)
# ============================================================
; xdebug.mode = debug
; xdebug.client_host = 127.0.0.1
; xdebug.client_port = 9003
; xdebug.start_with_request = yes

# ============================================================
# TRYB: coverage — code coverage dla PHPUnit
# ============================================================
; xdebug.mode = coverage

# ============================================================
# TRYB: develop — ulepszone var_dump, error reporting
# ============================================================
; xdebug.mode = develop

# Kombinacja (np. debug + develop):
; xdebug.mode = debug,develop
# Utwórz katalog na pliki profilowania i nadaj uprawnienia
sudo mkdir -p /tmp/xdebug
sudo chown www-data:www-data /tmp/xdebug

# Przeładuj PHP-FPM po zmianie konfiguracji
sudo systemctl reload php8.2-fpm

# Weryfikacja: sprawdź czy tryb profiling jest aktywny
php -r "echo xdebug_info('mode');" 2>/dev/null || php -r "xdebug_info();" | grep mode

Uruchamianie profiling — trigger mode

# Z parametrem URL (GET)
curl "https://mojadomena.pl/?XDEBUG_PROFILE=1" -o /dev/null

# Z nagłówkiem HTTP (nie modyfikuje URL aplikacji)
curl "https://mojadomena.pl/" \
  -H "Cookie: XDEBUG_PROFILE=PHPSTORM" -o /dev/null

# Przez Xdebug Helper (rozszerzenie Chrome/Firefox)
# Kliknij ikonę → wybierz Profile → odśwież stronę

# Sprawdź wygenerowane pliki cachegrind
ls -la /tmp/xdebug/
# -rw-r--r-- 1 www-data www-data 1.8M cachegrind.out.12345.a1b2c3

# Dla CLI (np. profilowanie skryptu PHP)
XDEBUG_MODE=profiling XDEBUG_OUTPUT_DIR=/tmp/xdebug \
  php moj-skrypt.php

# Profilowanie konkretnej strony WordPress
XDEBUG_MODE=profiling php /var/www/wordpress/wp-cron.php

Analiza w KCachegrind / QCachegrind

KCachegrind (Linux) i QCachegrind (Windows/macOS) to graficzne narzędzia do analizy plików cachegrind. Otwórz plik z /tmp/xdebug/ i skup się na trzech widokach:

# Instalacja KCachegrind (Linux)
sudo apt install kcachegrind

# Instalacja QCachegrind (Windows — dostępny jako portable binary)
# Pobierz z: https://github.com/KDE/kcachegrind

# Otwórz plik cachegrind
kcachegrind /tmp/xdebug/cachegrind.out.12345.a1b2c3

# Kluczowe widoki i kolumny:
# Flat Profile — sortuj po "Self" (czas w tej funkcji, bez wywołań)
#   → Szukaj funkcji z Self > 5% — to kandydaci do optymalizacji
#
# Call Graph — wizualizacja grafu wywołań
#   → Grube strzałki = gorące ścieżki wywołań
#
# Callee Map (treemap) — proporcjonalna mapa funkcji według czasu
#   → Duże prostokąty = funkcje z największym kosztem

# Alternatywa online: wgrep plik cachegrind na
# https://www.speedscope.app (format cachegrind obsługiwany)

WordPress — typowe wąskie gardła

# Profiling WordPress — szukaj tych problemów w KCachegrind:

# 1. Zbyt wiele zapytań SQL
#    Funkcja: wpdb::query — duże Self Time, setki wywołań
#    Fix: cache WP_Query, używaj transients, ogranicz pętle WP_Query

# 2. Nieoptymalne WP_Query / get_posts
#    Fix: dodaj 'no_found_rows' => true (wyłącza SQL_CALC_FOUND_ROWS)
#         'update_post_meta_cache' => false (gdy nie potrzebujesz meta)
#         'update_post_term_cache' => false (gdy nie potrzebujesz taksonomii)

# Przykład optymalnego WP_Query:
# $args = array(
#   'posts_per_page'         => 10,
#   'no_found_rows'          => true,
#   'update_post_meta_cache' => false,
#   'update_post_term_cache' => false,
# );

# 3. Niebuforowane opcje WordPress (wp_options z autoload=yes)
#    Sprawdź przez: SELECT option_name, LENGTH(option_value)
#    FROM wp_options WHERE autoload='yes' ORDER BY LENGTH(option_value) DESC;
#    Fix: usuń autoload dla dużych opcji pluginów

# 4. Zewnętrzne HTTP w hookach
#    Funkcja: WP_HTTP::request lub curl_exec — duże czasy oczekiwania
#    Fix: cache odpowiedzi API przez set_transient()

# 5. Powolne pluginy w wp_head / wp_footer
#    Sprawdź hook: do_action('wp_head') — czas Self vs Inclusive
#    Fix: usuń zbędne pluginy, lazy-load przez wp_enqueue_scripts

Blackfire.io — alternatywa do profilowania produkcji

Cecha Xdebug 3 Blackfire.io
Cena Darmowy (open-source) Darmowy plan (1 środowisko) + płatne
Narzut wydajności 2-5x wolniej (profilowanie) <5% (zoptymalizowany do produkcji)
UI / wizualizacja KCachegrind (lokalne) lub speedscope Wbudowany UI w przeglądarce, timeline
CI/CD integracja Manualna (phpunit --coverage) Natywna (GitHub Actions, GitLab CI)
Alerty anomalii Brak Automatyczne alerty (regresje wydajności)
Wsparcie dla produkcji Trigger mode (ograniczone) Tak (stały monitoring z minimalnym narzutem)
Najlepszy dla Lokalne dev, step debugger, code coverage Produkcja, CI/CD, porównywanie wersji
# Instalacja Blackfire agent i PHP extension
curl -sS https://packages.blackfire.io/gpg.key | sudo gpg --dearmor \
  -o /usr/share/keyrings/blackfire.gpg
echo "deb [signed-by=/usr/share/keyrings/blackfire.gpg] http://packages.blackfire.io/debian any main" \
  | sudo tee /etc/apt/sources.list.d/blackfire.list
sudo apt update && sudo apt install -y blackfire blackfire-php

# Skonfiguruj agenta (klucze z blackfire.io/my/settings/credentials)
sudo blackfire agent:config

# Przeładuj PHP-FPM
sudo systemctl reload php8.2-fpm

# Profiluj przez CLI
blackfire curl https://mojadomena.pl/

# Profiluj przez przeglądarkę
# Zainstaluj Blackfire Companion (Chrome/Firefox)
# Kliknij ikonę → Profile → otwórz wyniki na blackfire.io

Najczęstsze pytania

Czym różni się Xdebug od Blackfire.io? +
Xdebug to darmowe rozszerzenie PHP open-source. Obsługuje debugowanie krok-po-kroku (step debugger), profiling i code coverage. Generuje pliki cachegrind do analizy w KCachegrind/QCachegrind. Blackfire.io to komercyjny profiler (darmowy plan dla developerów) z wbudowanym UI w przeglądarce, automatycznym wykrywaniem anomalii i integracją z CI/CD. Blackfire jest łatwiejszy w użyciu i ma lepsze UI, ale Xdebug jest darmowy i doskonały do lokalnego profilowania. Na produkcji zdecydowanie Blackfire — Xdebug profiling znacząco spowalnia PHP.
Jak skonfigurować Xdebug 3 do profilowania (nie debugowania)? +
W Xdebug 3 tryb jest wybierany przez xdebug.mode = profiling (nie debugowania jak w wersji 2). Dodaj do php.ini lub xdebug.ini: xdebug.mode = profiling oraz xdebug.output_dir = /tmp/xdebug. Profiling uruchamia się przez parametr URL XDEBUG_PROFILE=1 lub przez xdebug.start_with_request = trigger (tylko gdy parametr w URL) albo yes (każde żądanie — uwaga: bardzo wolne). Pliki cachegrind trafiają do output_dir i można je otworzyć w KCachegrind.
Jak znaleźć wąskie gardła w WordPress przez Xdebug? +
Uruchom żądanie z XDEBUG_PROFILE=1, otwórz wygenerowany plik cachegrind w KCachegrind. Szukaj funkcji z najwyższym Self Time (czas spędzony w tej funkcji) i Inclusive Time (z wywołaniami potomnymi). Typowe wąskie gardła WordPress: zbyt wiele zapytań SQL (wpdb->query), nieoptymalne pętle WP_Query z get_posts(), brak cache dla opcji autoload (wp_options), wolne pluginy wywoływane w hookach wp_head/wp_footer, niebuforowane żądania HTTP do zewnętrznych API przez wp_remote_get.
Czy można używać Xdebug na serwerze produkcyjnym? +
Xdebug profiling spowalnia PHP 2-5x — absolutnie nie nadaje się do włączenia na produkcji dla wszystkich żądań. Możesz go użyć tymczasowo na produkcji (lub staging) z xdebug.start_with_request = trigger — wtedy profiler aktywuje się tylko gdy w żądaniu jest parametr XDEBUG_PROFILE=1 lub cookie XDEBUG_PROFILE. Przy tym ustawieniu normalni użytkownicy nie odczuwają spowolnienia. Na produkcji do stałego monitorowania lepiej użyć Blackfire.io lub Tideways — są zoptymalizowane do ciągłego profilowania z minimalnym narzutem.

Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.