PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Blackfire – instalacja w DDEV, profilowanie HTTP i CLI, asercje w CI/CD

by Henryk Tews / poniedziałek, 03 czerwca 2024 / Opublikowano w PHP, Środowiska

var_dump() i microtime() to debugowanie na oko. Blackfire to profesjonalny profiler który pokazuje dokładnie ile czasu i pamięci zajmuje każde wywołanie funkcji w całym stosie – w czasie rzeczywistym, z wizualizacją call graph. Pokazuję jak zainstalować Blackfire w DDEV, jak profilować requesty HTTP i komendy CLI, i jak interpretować wyniki żeby znaleźć prawdziwe wąskie gardła w Magento 2.

Blackfire vs inne narzędzia profilujące

Narzędzie Co mierzy Narzut na wydajność Produkcja?
microtime() Czas wybranego fragmentu kodu Minimalny Tak
Xdebug profiler Pełny call graph, czas, liczba wywołań Bardzo duży (5-10x) Nie
Blackfire Pełny call graph, CPU, RAM, I/O Mały (2x) Możliwe (ostrożnie)
New Relic APM Agregacja metryk, slow queries Minimalny Tak (do tego służy)
Tideways XHProf Call graph, czas, pamięć Mały Możliwe

Instalacja w DDEV

# Blackfire wymaga konta na blackfire.io (darmowe dla developerów)
# Po rejestracji dostaniesz Server ID i Server Token

# Dodaj Blackfire do DDEV projektu
ddev get ddev/ddev-blackfire

# Lub ręcznie - .ddev/docker-compose.blackfire.yaml
# .ddev/docker-compose.blackfire.yaml
version: '3.6'
services:
  blackfire:
    image: blackfire/blackfire:2
    environment:
      BLACKFIRE_SERVER_ID: "${BLACKFIRE_SERVER_ID}"
      BLACKFIRE_SERVER_TOKEN: "${BLACKFIRE_SERVER_TOKEN}"
      BLACKFIRE_CLIENT_ID: "${BLACKFIRE_CLIENT_ID}"
      BLACKFIRE_CLIENT_TOKEN: "${BLACKFIRE_CLIENT_TOKEN}"
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}

  web:
    environment:
      BLACKFIRE_AGENT_SOCKET: "tcp://blackfire:8307"
# Ustaw tokeny w .ddev/.env (nie commituj do repo!)
echo "BLACKFIRE_SERVER_ID=twoje-server-id" >> .ddev/.env
echo "BLACKFIRE_SERVER_TOKEN=twoj-token" >> .ddev/.env

# Zainstaluj probe PHP w kontenerze web
ddev ssh
pecl install blackfire

# Zrestartuj
ddev restart

Profilowanie requestu HTTP

# Przez CLI - profiluj konkretny URL
blackfire curl https://magento2-dev.ddev.site/catalog/product/view/id/42

# Z przeglądarki - zainstaluj rozszerzenie Blackfire Companion
# (Chrome/Firefox) i kliknij przycisk Profile

# Profilowanie z parametrami
blackfire curl \
    --samples 5 \   # średnia z 5 requestów
    https://magento2-dev.ddev.site/

# Profilowanie komendy CLI - bardzo przydatne dla Magento
blackfire run php bin/magento catalog:reindex
blackfire run php bin/magento indexer:reindex catalog_product_price

Interpretacja wyników – call graph

Blackfire pokazuje call graph jako drzewo wywołań. Kluczowe metryki:

  • Wall Time – całkowity czas wykonania (z czekaniem na I/O)
  • CPU Time – czas procesora (bez I/O wait)
  • Memory – szczytowe zużycie pamięci
  • I/O Time – czas spędzony na operacjach I/O (baza, pliki)
  • HTTP calls – liczba requestów do zewnętrznych serwisów
<?php

// Typowe problemy które Blackfire ujawnia w Magento 2:

// 1. N+1 queries - widać jako setki wywołań mysql_query
//    Rozwiązanie: eager loading przez joinField() lub zbiorcze zapytania

// 2. Zbędna serializacja/deserializacja
//    Widać jako dużo czasu w json_decode/json_encode w pętlach

// 3. Layout rendering - czas w Magento\Framework\View\Layout::generateXml
//    Rozwiązanie: cache layout, lazy loading bloków

// 4. Plugin chains - dużo czasu w Interceptor::__callPlugins
//    Rozwiązanie: sprawdź czy plugin naprawdę musi być "around"

// Przykład - instrumentacja własnego kodu dla Blackfire
class ProductImporter
{
    public function importBatch(array $products): void
    {
        // Blackfire SDK - oznacz sekcję kodu jako "transaction"
        $probe = \BlackfireProbe::getMainInstance();
        $probe->createTransaction('Product Import Batch', count($products) . ' products');

        foreach ($products as $product) {
            $this->importSingle($product);
        }

        $probe->stopTransaction();
    }
}

Blackfire Builds – automatyczne profilowanie w CI/CD

# .blackfire.yaml - scenariusze testowe i asercje wydajnościowe
scenarios:
  Homepage:
    - /

  Product Page:
    - /catalog/product/view/id/42

  Category:
    - /women/tops-women/jackets-women.html

# Asercje - CI/CD zakończy się błędem jeśli przekroczone
tests:
  "Homepage loads fast":
    path: /
    assertions:
      - "main.wall_time < 2s"
      - "main.peak_memory < 64mb"
      - "metrics.sql.queries.count < 30"

  "No slow queries":
    path: /
    assertions:
      - "metrics.sql.queries.wall_time < 500ms"
# GitHub Actions - profilowanie przy każdym PR
# .github/workflows/blackfire.yml
name: Blackfire Performance Tests

on: [pull_request]

jobs:
  blackfire:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Blackfire Build
        uses: blackfireio/github-action@v1
        with:
          blackfire-server-id: ${{ secrets.BLACKFIRE_SERVER_ID }}
          blackfire-server-token: ${{ secrets.BLACKFIRE_SERVER_TOKEN }}
          blackfire-client-id: ${{ secrets.BLACKFIRE_CLIENT_ID }}
          blackfire-client-token: ${{ secrets.BLACKFIRE_CLIENT_TOKEN }}
          ref: ${{ github.head_ref }}
          base-ref: main

Praktyczna sesja profilowania – przykład

# Krok 1: profil bazowy przed optymalizacją
blackfire curl https://magento2-dev.ddev.site/catalog/category/view/id/11
# Wynik: Wall Time 3.2s, 147 SQL queries, 82MB RAM

# Krok 2: zidentyfikuj problemy
# Blackfire pokazuje: CategoryCollection::load() - 89 queries
# Wszystkie przez getProductCount() w pętli - N+1!

# Krok 3: poprawka - eager loading przez join
# Zamiast: foreach($categories as $cat) { $cat->getProductCount(); }
# Użyj: $collection->addProductCount();

# Krok 4: profil po poprawce
blackfire curl https://magento2-dev.ddev.site/catalog/category/view/id/11
# Wynik: Wall Time 0.8s, 12 SQL queries, 54MB RAM - 4x szybciej!

# Krok 5: porównaj dwa profile
blackfire compare PROFILE_ID_BEFORE PROFILE_ID_AFTER

Podsumowanie

Blackfire zmienia podejście do optymalizacji wydajności – zamiast zgadywać gdzie jest problem, masz twarde dane. Instalacja w DDEV zajmuje kilka minut, a wyniki pierwszego profilowania Magento 2 często ujawniają N+1 queries albo zbędne renderowanie bloków które da się wyeliminować w godzinę i zaoszczędzić sekundy czasu odpowiedzi. Asercje wydajnościowe w CI/CD to warstwa ochronna przed regresją – nikt nie commituje kodu który spowalnia stronę o 50% bez automatycznego alarmu.

About Henryk Tews

Co możesz przeczytać następne

OpenTelemetry – distributed tracing, auto-instrumentacja, Jaeger w DDEV
PHP 8.4 preview – property hooks, asymmetric visibility, chaining new
PHP 8.2 po premierze – readonly classes w praktyce, deprecacje, Rector, checklist migracji
  • Publikacje
  • O autorze
  • Kontakt

© 2026 Created by

GÓRA
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Zawsze aktywne
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Zarządzaj opcjami
  • Zarządzaj serwisami
  • Zarządzaj {vendor_count} dostawcami
  • Przeczytaj więcej o tych celach
Zobacz preferencje
  • {title}
  • {title}
  • {title}