Sorun: “Bu metin ne kadar yer kaplar?”
Diyelim ki 10 bin mesajlık bir sohbet ekranı yapıyorsun. Hepsini sayfaya koyarsan tarayıcı boğulur. Bu yüzden sanallaştırma yaparsın: Sadece ekranda görünen mesajları çizersin. Ama kaydırma çubuğunun doğru boyda olması için her mesajın yüksekliğini önceden bilmen gerekir. Bir mesajın yüksekliği de metnin kaç satıra bölündüğüne bağlı.
Bunu öğrenmenin klasik yolu, metni sayfaya koyup offsetHeight ya da getBoundingClientRect() ile ölçmek. Sorun şu: Tarayıcı sana doğru cevabı verebilmek için reflow yapmak zorunda kalıyor, yani sayfadaki öğelerin konumunu ve boyutunu yeniden hesaplıyor. Bu, tarayıcının en pahalı işlerinden biri. Okuma ve yazmayı arka arkaya yaparsan (layout thrashing) bu hesap defalarca tekrarlanıyor.
Diğer yol tahmin etmek: Karakter sayısını satır genişliğine böl, satır yüksekliğiyle çarp. Hızlı ama farklı fontlarda, emojilerde, uzun kelimelerde yanlış. Pierre’in diffs kütüphanesi yazısında bu tahmin-ve-düzelt yaklaşımını anlatmıştık.
Pretext ne yapıyor?
Pretext, React Motion’ın yazarı ve eski React çekirdek ekibi üyesi Cheng Lou’nun açık kaynak (MIT) kütüphanesi. İlk sürümü 27 Mart 2026’da npm’e çıktı. Fikir, ölçümü DOM’dan tamamen çıkarmak.
İki adımda çalışıyor:
prepare(metin, font): Tek seferlik iş. Boşlukları düzenliyor, metni satırın bölünebileceği noktalardan parçalara ayırıyor ve her parçanın genişliğini canvas ile ölçüp saklıyor. Canvas’ınmeasureText()fonksiyonu DOM’un dışında çalışıyor, reflow tetiklemiyor.layout(hazırlanan, genişlik, satırYüksekliği): Saklanan genişlikler üzerinde sadece toplama ve karşılaştırma. Sonuç: yükseklik ve satır sayısı. Pencere boyutu değişince sadece bunu tekrar çağırıyorsun.
Zor kısım, satırın nerede bölüneceğine tarayıcıyla birebir aynı kararı vermek. Boşluklar, tireler, emojiler, Çince ya da Tayca gibi kelimeler arasında boşluk olmayan diller… Pretext bazı diller için tarayıcının kelime bölücüsü Intl.Segmenter’ı kullanıyor. Doğruluğu da tarayıcının kendi font motorunu “doğru cevap” kabul edip onunla karşılaştırarak test ediyor. README bunu “yapay zekâ dostu bir yineleme yöntemi” diye anıyor. Videoya göre Cheng Lou haftalarca yapay zekâ ajanlarına satır bölme kodunu yazdırıp sonucu gerçek tarayıcılarla kıyaslatmış.
Neleri mümkün kılıyor?
- Tahminsiz sanallaştırma ve yeni metin yüklenince kaydırma konumunun kaymaması.
- Masonry gibi JavaScript ile hesaplanan yerleşimler.
- Bir sohbet balonunu en uzun satırı kadar daraltmak. CSS bunu tek başına yapamıyor.
- Metni bir resmin etrafından satır satır akıtmak (
layoutNextLineRange). - Tarayıcı açmadan, test sırasında “bu buton yazısı alt satıra taşıyor mu?” kontrolü.
Çıktıyı DOM’a, canvas’a ya da SVG’ye çizebiliyorsun. Syntax’ta Wes Bos ve Scott Tolinski de bu demoların internette nasıl yayıldığını konuştu.
Sınırları
Pretext tam bir font motoru değil. Web fontları yüklenmeden ölçüm yaparsan sonuç yanlış çıkar. README’ye göre macOS’ta system-ui güvenilmez, text-wrap: balance ve otomatik tireleme gibi bazı CSS özellikleri desteklenmiyor. Sağdan sola yazılan metinlerde de sadece satırları veriyor, görsel sıralamayı tarayıcıya bırakıyor.
Sonra ne oldu?
Proje Ekim 2026’da hâlâ aktif geliştiriliyor ve GitHub’da 50 binden fazla yıldızı var. Bugün karışık fontlar, etiketler ve satır içi resimler için ayrı bir “rich inline” API’si ve textarea benzeri metin desteği de sunuyor. Sürüm numarası hâlâ 0.0.x, yani API değişebilir.
Düşün
- Senin projende DOM’dan boyut okuyan hangi kod parçası, kaydırırken ya da pencere boyutu değişirken takılmaya yol açıyor olabilir?
- Metin ölçümü ucuzlarsa, CSS’in bugün yapamadığı hangi yerleşimi denemek isterdin?
Videoyu izle
Kaynaklar (9, İngilizce)
- Fireship: He just crawled through hell to fix the browser… (video) (yeni sekmede açılır)
- Syntax #993: It's Been A Hell Of Week (yeni sekmede açılır)
- Pretext (GitHub) (yeni sekmede açılır)
- Pretext demoları (yeni sekmede açılır)
- npm: @chenglou/pretext (yeni sekmede açılır)
- web.dev: Avoid large, complex layouts and layout thrashing (yeni sekmede açılır)
- MDN: Reflow (yeni sekmede açılır)
- MDN: CanvasRenderingContext2D.measureText() (yeni sekmede açılır)
- MDN: Intl.Segmenter (yeni sekmede açılır)
Kendi cümlelerimizle yazılmış bir özettir, çeviri değildir. Tüm kaynaklar yukarıda.