deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

Farm.js AOT compiler'ı, kanıtlanabilir state güncellemelerinde React'in render döngüsünü atlıyor

Farm.js'in deneysel ahead-of-time compiler'ı React bileşenlerini build sırasında analiz ediyor ve state'in hangi DOM node'larına dokunduğunu kanıtlayabildiğinde güncellemeleri doğrudan DOM'a yazarak React'in render döngüsünü tamamen atlıyor.

Farm.js AOT compiler'ı, kanıtlanabilir state güncellemelerinde React'in render döngüsünü atlıyor

Render'dan vazgeçen bir ahead-of-time compiler

Full-stack bir React framework'ü olan Farm.js, tamamen analiz edebildiği güncellemelerde React'in render döngüsünü devre dışı bırakan deneysel bir ahead-of-time compiler sundu. Proje yazarının dev.to'daki yazısına göre, compiler build sırasında bir state'in tam olarak hangi DOM node'larına dokunduğunu kanıtlayabiliyorsa, güncellemeleri doğrudan DOM'a yazıyor. Kanıtlayamadığında ise bileşen sıradan React üzerinde kalıyor — yeni bir sözdizimi ya da farklı bir bileşen modeli yok.\n Gerçek framework'ü StackBlitz üzerinde WebContainers aracılığıyla çalıştıran bir tarayıcı playground'u sayesinde her şey hiçbir şey yüklemeden denenebiliyor.

Compiler nasıl çalışıyor

Normal bir React güncellemesi şu şekilde işler: bileşen fonksiyonu yeniden çalıştırılır, yeni bir element ağacı kurulur, öncekiyle karşılaştırılır (diff) ve farklar commit edilir. Basit bir sayaç için — state'in yalnızca metin içeriğini ve className'i değiştirebildiği tek bir buton — yazar bu mekanizmanın saf bir yük olduğunu düşünüyor.

Farm compiler bu tür bileşenleri build sırasında analiz ediyor ve binding'ler etrafında kurulu bir derlenmiş tanım üretiyor: her binding, hangi state hücresinin belirli bir text node'a veya attribute'a beslendiğini, ayrıca değerini hesaplayan fonksiyonu kaydediyor. İlk mount hâlâ React'e ait, dolayısıyla hydration, ref'ler ve devtools normal bir bileşem görüyor. Mount'tan sonra setter çağrıldığında bağımlılık grafiği geziliyor ve etkilenen binding'ler doğrudan uygulanıyor — render yok, reconciliation yok, commit aşaması yok. Depoda, derlenmiş ve baseline sürümleri yan yana render eden ve derlenmiş olanın sıfır React render ile güncellendiğini doğrulayan bir runtime testi bulunuyor.

Derlenmiş bileşenler ayrıca bir yetenek listesi taşıyor. Keyed list'e, koşullu aralıklara veya iç içe derlenmiş bileşenlere ihtiyaç duyan bileşenler bu özellikler için modülleri içe aktarıyor; bir özelliği kullanmayan bileşenler onu hiçbir zaman içe aktarmıyor, böylece kullanılmayan yapısal runtime'lar tree-shaking ile eleniyor. Yazar, yalnızca doğrudan binding'lerden oluşan çıktının runtime yükünü, tam runtime'ı göndermeye kıyasla %73,6 daha küçük ölçtü.

Muhafazakâr geri dönüşler

Compiler bilinçli olarak muhafazakâr: yalnızca tek bir kararlı host element ağacı olduğunu ve desteklenen her state değerinin bilinen metin veya attribute hedeflerine denk düştüğünü kanıtlayabildiğinde bir bileşeni dönüştürüyor. Projenin dokümanlarına göre her zaman React'te kalan yapılar şunlar: key'siz veya index-key'li liste render'ı, desteklenen useState biçimi dışındaki effect ve hook'lar, ref, dangerouslySetInnerHTML, JSX spread'leri, çoklu veya koşullu return'ler, güncellemeleri kimlik taşıyan prop'lar (obje, dizi, fonksiyon, element), async bileşenler ve JSX event handler'ları dışından çağrılan setter'lar.

Geri dönüş varsayılan olarak sessiz, ancak diagnostic'ler bir bileşenin neden atlandığını log'layabiliyor ve bir report seçeneği hangi bileşenlerin derlendiğini hangilerinin geri döndüğünü, nedenleri ve sayılarıyla tam olarak listeleyen bir .farm/react-compiler. dosyası yazıyor. Herhangi bir bileşen bir "use no compiler" directive'i ile derlemeden çıkarılabilir. Compiler'ı etkinleştirmek, React renderer üzerindeki tek bir deneysel flag.

Kendi ölçümlerine dayanan benchmark'lar

Yazar, js-framework-benchmark tarzı keyed bir tabloyu benchmark'ladı — 1.000 satır oluştur, her 10. etiketi güncelle, seçimi ilerlet, iki satırı takas et, temizle — Playwright Chromium ile yönlendirilen production build'leri üzerinde; gecikme ise frame sınırlarına yuvarlanmak yerine click dispatch'ten MutationObserver callback'ine kadar ölçüldü. Benchmark runner, workspace'i link'lemek yerine yayınlanmış npm paketlerini kuruyor ve compiler raporu iş yükü bileşeninin gerçekten derlendiğini kanıtlamazsa sert şekilde başarısız oluyor, böylece karşılaştırma sessizce baseline ile baseline'a dönüşemiyor.

Medyan sonuçlar: takas 3,40ms'den 0,50ms'ye (6,80x), temizleme 3,80ms'den 0,70ms'ye (5,43x), oluşturma 1,17x, seçme 1,20x iyileşti — ve güncelleme tam olarak 1,00x kaldı. Yazar bu düz sayı hakkında açık konuşuyor: satır etiketi güncellemeleri React'te zaten ucuzdu ve derlenmiş yol, DOM yazımının kendisini geçemez. Kazançlar, reconciliation'un maliyet olduğu yerde ortaya çıkıyor — takaslar, temizlemeler ve keyed list'lerdeki yapısal değişimler. Tam bir eylem döngüsü başına toplam CPU işi (script, style ve layout) 18,71ms'den 9,05ms'ye, kabaca yarıya düştü. Bunlar yazarın kendi sayıları; örnek başına veriler ve metodoloji, repo'nun benchmarks dizininde duruyor.

Compiler'ı çevreleyen framework

Farm aynı zamanda geleneksel bir full-stack framework: bir Vite dev server, alışıldık page, layout, loading ve error dosyaları ile dinamik ve catch-all segmentlerin eklendiği dosya tabanlı app dizini yönlendirmesi, streaming SSR ve Nitro production çıktısı. Routelar uçtan uca tipli — framework app dizininden bir route-path union type üretiyor, böylece yazım hatasıyla bozulmuş bir iç link bir type error'a dönüşüyor ve tipler, dev başlangıcında ve routelar her değiştiğinde yeniden üretiliyor.

Server fonksiyonları hem girdi hem çıktı için zod şemaları alıyor ve hat sınırını her iki yönde doğruluyor; bir useServerFn hook'u progressive enhancement için bir formAction sunuyor ve client bileşenlerinden çağrıldığında bile handler'lar sunucuda çalışıyor.

Neden önemli

Farm'ın compiler'ı, UI güncellemelerinin build zamanında optimize edilmesine doğru kayışta somut bir veri noktası. Yeniden render'ları azaltmak için bileşenleri memoize etmek yerine, güvenli olduğunu kanıtlayabildiği güncellemelerde render'ı tamamen kaldırıyor ve başka her yerde saf React'e geri dönüyor — bir yeniden yazım değil, opt-in bir optimizasyon. İki mühendislik tercihi öne çıkıyor: optimizasyonun hiçbir şey yapmadığı yerde 1,00x sonucunu yayınlamak ve "sıcak bileşenim gerçekten derlendi mi?" sorusunu denetlenebilir bir soruya dönüştüren, makine tarafından okunabilir bir compile raporu. Proje hâlâ deneysel, tek yazarlı bir çalışma ve benchmark'lar kendi ölçümlerine dayandığından, bugün production'a bahse girmek için değil, React araçing'i için umut verici bir yön olarak okunması en doğrusu.

  • #react
  • #compilers
  • #web-frameworks
  • #performance
  • #javascript

İlgili yazılar