Lighthouse CI Nedir? Her Deploy'da Performans Testi Nasıl Otomatikleştirilir?
Lighthouse CI, her deploy'da performans regresyonunu otomatik yakalar. GitHub Actions entegrasyonu, budget.json eşikleri ve assert bloğuyla PR merge edilmeden önce sorun tespit edilir.
Performans bir özellik değil, bir alışkanlık. Bir sayfayı optimize etmek tek başına yeterli değil; her deploy sonrasında bu optimizasyonun yerinde durduğunu doğrulamak asıl iştir. Bir geliştirici yeni bir bileşen ekler, başka biri üçüncü taraf bir script entegre eder ve fark edilmeden skor 20 puan aşağı düşer. Lighthouse CI (LHCI), tam bu boşluğu kapatmak için tasarlanmış, Google'ın açık kaynak otomasyon katmanı.
Lighthouse'u tarayıcıdan ya da DevTools'tan çalıştırmak düzenli ölçüm alışkanlığı için yeterli değil. El ile yapılan ölçümler tutarsız: makine yükü, ağ koşulları, tarayıcı önbelleği sonucu doğrudan etkiler. Üstelik her deploy'da elle test etmek pratik değil. LHCI bu süreci CI/CD pipeline'ına bağlar; her pull request ya da her main branch push'unda Lighthouse ölçümünü otomatik çalıştırır, belirlediğiniz eşiklerin altına düşülünce build'i kırar.
Senaryo şu: orta büyüklükte bir frontend projesi, birden fazla geliştiriciyle ilerliyor. Performans skoru zaman zaman 90'ın altına düşüyor ama kimse fark etmiyor çünkü düzenli kontrol mekanizması yok. LHCI bu duruma son verir; regresyon production'a çıkmadan, PR merge edilmeden yakalanır.
CLI, Collector ve Server: LHCI Üç Parçadan Oluşur
LHCI üç ayrı bileşenden oluşur ve her birinin sorumluluğu farklı. @lhci/cli paketi, Lighthouse'u headless Chrome üzerinde çalıştıran ve ham sonuçları toplayan komut satırı aracı. Bu araç build artifact'ını alır, belirtilen URL'leri açar, ölçümleri gerçekleştirir ve çıktıları bir hedefe gönderir. Collector katmanı bu çıktıları ya LHCI Server'a, ya geçici bir bulut storage'a, ya da yerel dosya sistemine yönlendirir. LHCI Server ise isteğe bağlı kalıcı bileşen; tarihsel karşılaştırma, görsel fark analizi ve PR bağlantısı sunar.
Minimal kurulum için LHCI Server zorunlu değil. GitHub Actions ile birlikte geçici storage kullanmak, regresyon tespiti için yeterli bir altyapı sağlar. Sunucu, takım büyüyünce veya performans geçmişini görselleştirmek istediğinizde anlamlı hale gelir. Yeni başlayan projeler için bu karmaşıklığı baştan eklemek gerekmez.
@lhci/cli tek npm bağımlılığı:
npm install --save-dev @lhci/cli
Konfigürasyon proje kökündeki lighthouserc.json dosyasıyla yönetilir. Hangi URL'lerin test edileceği, kaç kez çalışacağı ve hangi kategorilerin dahil edileceği burada tanımlanır. Birden fazla URL desteklenir; her biri ayrı raporlanır, ayrı assert kontrolünden geçer.
{
"ci": {
"collect": {
"url": ["http://localhost:3000", "http://localhost:3000/hakkimizda"],
"numberOfRuns": 3
}
}
}
numberOfRuns: 3 medyan sonucu alır ve tek çalıştırmadan daha güvenilir puan üretir; headless ortamlarda çalışma süreleri arası varyasyon bazen 5-10 puan arasında gezinebilir.
GitHub Actions'a Bağlamak: Temel Workflow Yapısı
LHCI'ı GitHub Actions'a entegre etmek için hazır bir action var: treosh/lighthouse-ci-action. Alternatif olarak lhci CLI'ı doğrudan workflow adımı olarak çalıştırabilirsiniz. İkinci yöntem daha fazla kontrol sağlar çünkü build süreci, dev server başlatma ve LHCI çalıştırma adımlarını birbirinden bağımsız tanımlayabilirsiniz.
Temel workflow dosyası .github/workflows/lighthouse.yml olarak oluşturulur:
name: Lighthouse CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run build
- name: Serve static build
run: npx serve dist -p 3000 &
- name: Wait for server
run: sleep 3
- name: Run LHCI
run: npx lhci autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
LHCI'ın test yapabilmesi için sitenin çalışıyor olması gerekir. serve dist komutu derlenen çıktıyı yerel 3000 portunda sunar; arka planda çalışması için & eklenir. Ardından kısa bir bekleme adımı eklenir, aksi hâlde LHCI sunucu henüz hazır olmadan istek gönderebilir. Statik site yerine SSR veya dev server kullanıyorsanız npm run dev ile değiştirin ancak port tutarlı olsun.
lighthouserc.json içinde upload hedefini geçici storage olarak belirtmek en hızlı başlangıç yöntemi:
{
"ci": {
"collect": {
"url": ["http://localhost:3000"],
"numberOfRuns": 3
},
"upload": {
"target": "temporary-public-storage"
}
}
}
Geçici storage seçeneğiyle rapor bağlantısı doğrudan PR yorumuna düşer. Kalıcı depolama kurulmadan önce bu yöntem hem sonuçları hem de olası ayar sorunlarını görmek için idealdir.
budget.json ve assert Bloğu: Eşikleri Sayıyla Tanımlamak
LHCI'ın temel gücü performans eşiklerini rakamla belirlemek. Skor 85'in altına düşerse build kırılsın, LCP 2500 ms'yi geçerse uyarı verilsin gibi kurallar assert bloğunda yazılır. İki seviye yanıt tanımlanabilir: error build'i durdurur, warn yalnızca log çıktısı üretir.
{
"ci": {
"assert": {
"preset": "lighthouse:no-pwa",
"assertions": {
"categories:performance": ["error", {"minScore": 0.85}],
"categories:accessibility": ["warn", {"minScore": 0.9}],
"largest-contentful-paint": ["error", {"maxNumericValue": 2500}],
"first-contentful-paint": ["error", {"maxNumericValue": 2000}],
"total-blocking-time": ["warn", {"maxNumericValue": 300}],
"cumulative-layout-shift": ["error", {"maxNumericValue": 0.1}]
}
}
}
}
Eşikleri projenin mevcut durumuna göre kademeli sıkılaştırmak daha sağlıklı. 62 puanda duran bir projeye hemen 85 eşiği koymak yerine önce 68, ardından 75 şeklinde ilerlemek daha işlevsel. Başlangıçta büyük sıçramalar her commit'te build kırar ve ekip uyarıları anlamlı bulmaktan çıkar.
budget.json formatı ise kaynak boyutu ve istek sayısı gibi düşük seviye metrikler için ayrıca kullanılır. Değerler KB cinsindendir:
[
{
"path": "/*",
"resourceSizes": [
{"resourceType": "script", "budget": 200},
{"resourceType": "stylesheet", "budget": 50},
{"resourceType": "total", "budget": 500}
],
"resourceCounts": [
{"resourceType": "third-party", "budget": 5}
]
}
]
Bu dosya lighthouserc.json içinde budgetPath alanıyla referans gösterilir. assert ve budgetPath birlikte kullanıldığında hem puan kategorilerine hem ham metriklere aynı anda göz kulak olunur. Puan tek başına yanıltıcı olabilir; 200 KB fazladan script eklense de puan bazen sabit kalabilir çünkü Lighthouse puan ağırlıkları her versiyonda biraz farklı davranır. Ham metrik eşikleri bu tutarsızlığı bypass eder.
Regresyon Tespiti: PR'da Ne Görünür, Ne Anlama Gelir?
LHCI, GitHub App aracılığıyla PR'lara yorum bırakır ve commit status olarak sonucu işaretler. Bu entegrasyon için LHCI_GITHUB_APP_TOKEN secret'ı gerekir. GitHub Apps üzerinden "Lighthouse CI" uygulamasını yükleyip token alınır, ardından repository secret'ına eklenir.
Entegrasyon çalıştığında her PR'da şunlar görünür: hangi kategorilerin puanı ne kadar değişti, hangi assert kuralı ihlal edildi, tam Lighthouse rapor bağlantısı. Geliştirici PR açmadan önce bu bilgiye sahip değil, ama kod review başlamadan önce, yani pipeline tamamlandığında, build kırılıp kırılmadığını görür. Düzeltme merge öncesinde yapılır.
Salt puan karşılaştırmasına bakmak yanıltıcı bir alışkanlık. 88'den 85'e düşmek her zaman kritik değil; bağlam önemli. Asıl sinyaller şunlar: bütçeyi aşan bir script eklendi mi, yeni bir render-blocking kaynak girdi mi, CLS sıfırdan 0.12'ye çıktı mı. Ham metrikler puandan daha güvenilir göstergedir. Bu yüzden assert bloğunu puan yerine metrik odaklı kurmak daha sağlam bir temel oluşturur.
Yanlış pozitif oranını düşük tutmak da önemli. Üç çalışmanın medyanı alındığında tek çalıştırmaya göre varyasyon azalır. Ama headless CI ortamı yavaş bir makineyse medyan puan bile stabil olmayabilir. numberOfRuns: 5 daha güvenilir ama daha uzun sürer; projenin büyüklüğüne ve pipeline bütçesine göre karar verilir.
LHCI Server: Tarihsel Veri Ne Zaman Değer Kazanır?
LHCI Server, zaman serisi karşılaştırması ve görsel fark analizi sunan isteğe bağlı kalıcı bileşen. Kendi sunucunuza ya da Railway, Render gibi platformlara deploy edilir. SQLite veya PostgreSQL ile çalışır; küçük projeler için SQLite yeterli.
Docker ile hızlı başlatma:
docker run -d \
-p 9001:9001 \
-v lhci-data:/data \
--name lhci-server \
patrickhulce/lhci-server
lighthouserc.json içinde upload hedefi değişir:
"upload": {
"target": "lhci",
"serverBaseUrl": "https://lhci.sizin-alan.com",
"token": "${{ secrets.LHCI_TOKEN }}"
}
Server'ın gerçek değeri birkaç hafta veri birikmesinden sonra ortaya çıkar. "Geçen sprint'te performans düştü mü, hangi commit'le başladı?" sorusunu dakikalar içinde yanıtlamak için bu gerekli bir araç. Tek geliştirici projelerinde geçici storage yeterlidir. Takım büyüdükçe ya da sprint bazlı performans revizyonları planlandıkça sunucu anlamlı hale gelir.
Her Projeye Uymaz: Fayda ve Maliyet Dengesi
LHCI her projeye aynı değeri katmaz. Aktif geliştirme döneminde, birden fazla kişinin aynı codebase'e commit attığı bir projede, düzenli deploy yapılan bir ürün sitesinde net fayda sağlar. Regresyon build aşamasında yakalandığı için production'a ulaşmaz, geri alma kargaşası yaşanmaz.
Ters etki senaryoları da gerçek. Her CI çalışması ekstra dakikalar ekler; headless Chrome başlatmak ağır, üç çalışma artı build süresi toplam 5-10 dakika arasında değişebilir. Pipeline zaten uzunsa bu maliyet gözden geçirilmeli. Haftada birkaç deploy yapan küçük projeler için yalnızca main branch'e kısıtlamak, PR'larda çalıştırmamak akıllıca bir kısıntı.
Eşikler gerçekçi olmazsa CI gürültüye döner. Her ihlalde build kırılıyor ve bunların çoğu anlamsız değişimlerden kaynaklanıyorsa ekip uyarıları görmezden gelmeye başlar. Alarmı kapatmak, alarmı düzeltmekten kolay. Başlangıçta warn ağırlıklı, error az; zamanla mevcut ortalamalara bakarak sıkılaştırmak, canlı ve işe yarar bir sistem oluşturur.
Statik sayfalarda LHCI en düzgün çalışır çünkü her çalışmada aynı içerik sunulur. Dinamik içerik, A/B testi ya da gerçek zamanlı veri içeren sayfalar için ölçüm tutarsız olabilir. Ana sayfa, ürün sayfası, fiyatlandırma gibi kritik ama stabil rotaları hedef almak daha anlamlı sonuçlar verir.
LHCI kurulumu tek seferlik bir iş, faydası tekrar eden her deploy'da birikir. Pipeline'a eklendikten sonra ekip performansı takip etmekle değil, performansın korunduğunu varsayarak ilerleyebilir. Regresyon artık "sonunda fark ettik" değil, "merge edilmeden yakalandı" olur.
Minimum yüzey üç parçadır: @lhci/cli kurulumu, bir lighthouserc.json, GitHub Actions'ta üç ek adım. İlk çalışmada puanlar görünür, ikinci haftada eşikler netleşir, üçüncü ayda ekip performans konuşmalarını veriyle yapar. Araç arka planda çalışır; kod incelemesi eşik ihlaline bakarak ilerler.