Proje: Okul Platform · Hub: Okul Platform — Decisions
Karar
resources/views/responsive/profiling/test/index.blade.php’de wizard skeleton’ı statik ilk soru markup’ı ile değiştirildi. Ayrıca profiling.js için <link rel="preload" as="script"> eklendi.
Problem
Önceki PR (2026-05-11-responsive-tracking-defer-and-css-inline) tracking defer + CSS inline ile render-blocking ve TBT düşürdü, ama LCP hâlâ yüksek (~8.6s).
Root cause — LCP candidate shift:
t=3.2s FCP: h1 hero paint → LCP candidate = h1 (~360×100px)
t=8.6s Alpine init → ready=true → x-cloak kalkar → wizard kart paint
→ LCP candidate = wizard kart (text-rich, 360×400px) ← FİNAL LCP
Skeleton text içermediği için LCP eligible değildi (LCP sadece img/text/bg-image elementlerini sayar). Wizard kartının içindeki gerçek soru text’i yalnızca <template x-for="(q, idx) in questions"> Alpine boot’tan sonra expand olurdu → LCP wizard kartının paint anına kadar gecikiyordu.
Çözüm
İlk soruyu Blade’de statik HTML olarak render et. Alpine boot beklemeden FCP anında gerçek içerik paint olur:
- LCP element = h1 hero VEYA statik wizard text bloğu (her ikisi de t=FCP’de paint)
- Alpine boot olunca:
x-show="!ready"statik bloku gizler,x-show="ready" x-cloakdinamik wizard’ı gösterir - Statik ve dinamik versiyon görsel olarak identical → no flicker, no CLS
pointer-events: none ile statik blok’ta tıklamalar engellenir (Alpine state’e propagate olmaz, kayıp tıklama riski yok).
Ek olarak <link rel="preload" as="script"> ile profiling.js download’u HTML parse esnasında başlar (eskiden body sonu defer → daha geç başlıyordu). ~300-500ms erken hydrate.
Trade-off
Pros:
- LCP 8.6s → ~3.5s beklentisi (FCP’ye kilitlenir)
- CLS değişmez (static/dynamic identical sized)
- Skeleton’a göre semantic değer artar (ilk soru SEO/SR için de görünür)
Cons:
- ⚠ Dual source of truth:
scoring-data.jsquestions[0]değişirse Blade statik markup manuel güncellenmeli. Yorum satırı eklendi. - Statik ve dinamik wizard kısa süreli (Alpine boot sırasında) DOM’da aynı anda var → minimal SR re-announce ihtimali
- HTML payload ~1KB artar
Alternatifler ve neden seçilmedi
- Hero h1’i büyütüp LCP yapma — Tasarım kararı, brand impact, scoring belirsiz (text-22 → text-32 hâlâ wizard kartı geçemeyebilir)
- Controller’dan
@json($questions)ile inject — BE değişikliği gerektirir; CLAUDE.md “ALWAYS ask before BE changes”. Plusscoring-data.js’i PHP’ye port etmek ek bakım yükü - Alpine bundle code-split (sadece wizard component) — Build pipeline değişikliği (webpack entry restructure), team review gerekir; ayrı PR
Uygulanan dosyalar
resources/views/responsive/profiling/test/index.blade.php- Skeleton blok → statik ilk soru markup’ı
@section('head_extra')ileprofiling.jspreload
Etki kapsamı
Sadece egitim-yaklasimi-testi sayfası. Result/finder sayfalarında LCP başka faktörlere bağlı (sonuç render’ı async AJAX).
Related
- 2026-05-11-responsive-tracking-defer-and-css-inline — Tracking defer + CSS inline (paralel optimizasyon, LCP’yi tek başına çözmedi)
- 2026-04-15-responsive-module-structure — Responsive bundle yapısı
- 2026-04-15-profiling-event-taxonomy — Wizard event taxonomy (statik blok event fire etmez, Alpine devraldıktan sonra normal akış)