← Blog

Konsolda sunucuda render etme

Text.js 0.4, bir sayfayı sunucuda render edip karelerini hücre farkları olarak konsola akışla aktarabilir. Statik rotalar ayrıca ilk karelerini HTML içine ön render eder.

Adam

Text.js 0.4, bir sayfanın render edilebileceği ikinci bir yer ekledi. Varsayılan olarak, sayfanın React ağacı tarayıcı sekmesinde çalışır. runtime = "server" dışa aktaran bir sayfa ise sunucuda çalışır ve tarayıcı bu sayfanın karelerini alır.

app/status/page.tsxtsx
import { Suspense, type ReactNode } from "react";import os from "node:os";import { Box, Text } from "textjs";export const runtime = "server";async function Load(): Promise<ReactNode> {  const [one, five] = os.loadavg();  return <Text>{`load ${one.toFixed(2)} ${five.toFixed(2)}`}</Text>;}export default function StatusPage(): ReactNode {  return (    <Box flexDirection="column">      <Text bold>Status</Text>      <Suspense fallback={<Text color="gray">Reading host…</Text>}>        <Load />      </Suspense>    </Box>  );}

Load, bir async function bileşenidir. Sunucuda promise’i sonuçlanana kadar en yakın <Suspense> veya loading.tsx sınırında askıya alınır ve dosyaları, veritabanlarını ve node:* modüllerini doğrudan okuyabilir. Asenkron bileşenler veri yükler ve hook kullanamaz. Çevrelerindeki normal bileşenler, her iki çalışma zamanında da aynı davranan hook’ları, odağı, useInput, <Link> ve useRouter() API’lerini korur.

Tarayıcının indirdikleri

Sunucuda render edilen bir sayfa React, Yoga veya rotalarınızı tarayıcıya göndermez. Tarayıcı, bir CellBuffer ve istemci render motorunun kullandığı aynı CssConsoleDriver sınıfını içeren, gzip ile yaklaşık 21 kB boyutunda bir kare oynatıcısı yükler. Kareleri aynı 15 fps hızında oynatır; böylece sunucuda render edilen bir kare, istemcinin üreteceğiyle aynı console.log çağrısını üretir.

Protokol

Her sekme sunucuda kendi oturumunu açar: bir React kökü, bellekte tutulan bir yönlendirici geçmişi ve bir hücre arabelleği. Tek bir uç nokta her iki yöndeki trafiği taşır:

browser tab ──(GET /__textjs/live, server-sent events)──▶ frame deltasbrowser tab ──(POST /__textjs/live, JSON)──────────────▶ keys, paste, wheel, resize, focus, Back/Forward

Sunucu, bağlantının aldığı son kareden bu yana yalnızca hash değeri değişen satırları gönderir. Her satır, yalnızca sonuna ekleme yapılan bir stil tablosuna göre metin dizileri olarak gönderilir. Geniş grafemler, emoji kümeleri ve yarı saydam renkler bozulmadan ulaşır.

Kareler arasında en az 66 ms vardır ve her karenin farkı, soketin en son kabul ettiği kareye göre hesaplanır. Yavaş bir bağlantı veri aktaramaz hâle geldiğinde ara durumlar atlanır ve sonraki kare en güncel duruma geçer.

Akış koparsa oynatıcı, oturum kimliğini x-textjs-live başlığında göndererek yeniden bağlanır ve durumu korunmuş aynı oturumu yeni bir anahtar kareden sürdürür. Oturum kimlikleri, URL’de değil bellekte tutulan 192 bitlik rastgele değerlerdir. Bağlantısı olmayan bir oturum render etmeyi durdurur ve 30 saniye sonra kaldırılır.

Her iki uç nokta da siteler arası istekleri reddeder ve her girdi olayı sabit bir şemaya göre doğrulanır. Bir oturum, POST başına en fazla 64, saniyede ise yaklaşık 240 olay kabul eder.

Asenkron bileşenler ve veri

Her asenkron bileşenin promise’i, bileşen ve prop’ları anahtar olarak kullanılarak oturum başına önbelleğe alınır; böylece yeniden denenen bir render, hâlihazırda devam eden isteği tekrar kullanır. Rota değiştiğinde ve router.refresh() çağırdığınızda önbellek temizlenir:

const router = useRouter();useInput((e) => e.input === "r" && router.refresh());

Yalnızca sunucuda kullanılan modüller *.server.ts olarak adlandırılır. Tarayıcıya gönderilen kod bunlardan birini veya yerleşik bir node:* modülünü içe aktarırsa derleme başarısız olur ve içe aktaran modülün adını belirtir.

Kısmi ön render

Kısmi ön render, sunucu olmadan çalışır. text build artık her statik rotayı bir kez render eder ve ilk karesini küçük bir klasik <script> olarak rotanın HTML’ine gömer; böylece herhangi bir modül yüklenmeden önce konsol çizilir.

Kabuk, eşzamanlı olarak render edilen her şeydir. Hâlâ bekleyen bir <Suspense> sınırı, asenkron bileşenler de dahil olmak üzere yedek içeriğini gösterir ve kabuk render edilirken fetch() hiçbir zaman sonuçlanmaz.

JavaScript başladığında istemci render motoru veya kare oynatıcısı gerçek kareyi akışla iletir. 0.4, temizlemek yerine kareleri sona da eklediğinden, hidrasyon yapan render motoru initialClear: false ile başlar ve kabuğun altına günlük kaydı yazar; perdesi de aynı DevTools çiziminde kabuğu görüş alanından çıkarır. Konsolu tam olarak bir kez kabuk temizler.

 ✓ Prerendering console shells (5/5) · 1 server-rendered, frame player 56.5 kB (21.3 kB gzip)

Derleme ziyaretçinin konsol boyutunu bilemeyeceğinden kabuk, varsayılanı 120 × 36 olan yapılandırılmış viewport boyutunda render edilir. viewport.responsive açıkken ilk canlı kare, kenetlenmiş konsola göre yeniden boyutlanır. Dinamik rotalar kabuk render etmez ve text.config.ts dosyasındaki ppr: false ön render işlemini kapatır.

Çalışma zamanı seçimi

İstemci çalışma zamanı varsayılan olarak kalır. Tuş vuruşları aynı görev içinde çizilir ve uygulama herhangi bir statik barındırma hizmetine dağıtılabilir. Sunucu çalışma zamanı, özel verileri okuyan panolara ve yönetici görünümlerine, ayrıca bağımlılıklarını tarayıcı paketinde istemediğiniz rotalara uygundur. Bir uygulama her ikisini birlikte kullanabilir ve aralarında gezinmek hedef URL’yi yeni bir belge olarak yükler.

Tam başvuru kaynağı Sunucuda render etme sayfasındadır.