DokumentasiMode

SSR (rendering server)

Definisi

SSR adalah defaultnya: server merender halaman ke HTML untuk setiap permintaan. Tidak ada yang mengaktifkannya, dan tidak ada tanda yang mematikannya - proyek mode server dirender pada setiap permintaan kecuali halaman mendeklarasikan revalidate.

Bagaimana cara kerjanya

Berkas rute Apa yang menghasilkan HTML Kapan
.nexy modul Python yang dikompilasi, melalui Jinja2 setiap permintaan
.md Markdown, lalu tata letak terdekat setiap permintaan
.mdx, .tsx, .vue, .svelte kerangka kerja, dirender di Node di build ketika rute tidak memiliki tata letak, sebaliknya di browser
.py tidak ada: ia mengembalikan JSON atau Response -

Halaman Markdown dan pengendali, berdampingan dalam proyek yang sama:

src/rute/changelog.md
# Changelog Rendered to HTML on every request, then wrapped in the nearest layout.
src/routes/api/health.py
async def GET():    return {"status": "ok"}

Rute komponen adalah satu kasus yang memerlukan kalimat kedua. Dalam produksi, rute komponen tanpa tata letak disajikan dengan HTML yang diproduksi saat build, dan komponen menghidrasinya. Dengan tata letak, atau dalam pengembangan, wadahnya kosong dan komponen dirender di browser - halaman tersebut kemudian menjadi shell yang mengisi dirinya sendiri.

Rute komponen tabel, tanpa tata letak, sehingga produksi menyajikan HTML-nya dari build:

src/routes/pricing.tsx
export default function Pricing() {  return <h1>Pricing</h1>;}
Pengontrol kembali Apa yang menghasilkan HTML Kapan
useViews("....nexy") modul Python yang dikompilasi, melalui Jinja2 setiap permintaan
a dict, daftar, model tidak ada: FastAPI menjawab JSON -

Tampilan dan titik akhir JSON, berdampingan dalam modul yang sama:

src/apps/changelog_view.nexy
<h1>Changelog</h1><p>Rendered to HTML on every request.</p>
src/apps/site_controller.py
from nexy.decorators import Controllerfrom nexy.hooks import useViews  @Controller("/changelog")class ChangelogController:    async def get(self):        return useViews("src/apps/changelog_view.nexy")  @Controller("/api/health")class HealthController:    async def get(self):        return {"status": "ok"}

Siklus hidup rendering

  1. Permintaan tersebut mencapai router berbasis file. Jalurnya cocok, dan segmen dinamis dilemparkan ke tipe yang dideklarasikan oleh komponen.

    ---
    id: penyangga[int]
    ---
    <h1>Pesanan #{{ id + 1000 }}</h1>
    

    /orders/42 menerjemahkan Order #1042; /orders/abc jawaban 404.

  2. Komponen berjalan. Yang menunggu di Node - dokumen klien - berjalan di kumpulan thread, sehingga tidak menghentikan perulangan peristiwa.

  3. Tubuh dialirkan sebagai text/html. Komponen yang menghasilkan potongan akan mengalirkannya saat membuatnya.

  4. Browser menerima HTML. Pulau-pulau tersebut terhidrasi menurut arahan mereka.

Kesalahan muncul saat rendering diubah menjadi halaman oleh errors.nexy ketika proyek memilikinya: lihat halaman kesalahan.

  1. Permintaan tersebut mencapai pengontrol. Parameter jalurnya dimasukkan ke tipe yang dideklarasikan oleh metode, dan diteruskan ke tampilan:

    dari pengontrol impor nexy.decorators
    dari nexy.hooks impor useViews
    
    
    @Controller("/pesanan/{id}")
    pengontrol pesanan kelas:
        async def get(diri, id: int):
            kembalikan useViews("src/apps/order_view.nexy", konteks={"id": id})
    
    ---
    id: penyangga[int]
    ---
    <h1>Pesanan #{{ id + 1000 }}</h1>
    

    /orders/42/ menerjemahkan Order #1042; /orders/abc/ jawaban 404.

  2. Tampilan berjalan, dan useViews mengembalikan HTML-nya sebagai respons.

  3. Browser menerima HTML. Pulau-pulau tersebut terhidrasi menurut arahan mereka.

Kesalahan yang muncul saat rendering dijawab dengan halaman kesalahan default.

Kapan harus digunakan

  • Halaman tersebut menunjukkan sesuatu yang dimiliki pembaca: sesi, akun, keranjang.
  • Data harus segar pada setiap pemuatan.
  • Konten harus dalam HTML untuk crawler yang tidak berjalan JavaScript.
  • Halaman ini murah untuk dirender: satu kueri, satu templat.

Kasus pertama, halaman yang menyapa pembaca dari sesi tersebut. useSession membaca sesi useSession di nexyconfig.py, yang tanpanya akan gagal:

nexyconfig.py
from nexy.core.models import NexyConfigModel  class NexyConfig(NexyConfigModel):    useSession = {"secret_key": "change-me"}
src/routes/akun.nexy
---from nexy import useSession user = useSession().get("user", "guest")---<h1>Signed in as {{ user }}</h1>
src/apps/account_view.nexy
---from nexy import useSession user = useSession().get("user", "guest")---<h1>Signed in as {{ user }}</h1>

Konfigurasi

Tidak ada. Ada dua jalan keluar, dan mereka tidak memiliki butir yang sama:

Meninggalkan SSR untuk Lakukan ini Gandum
satu halaman, dengan cache revalidate = 60 di bagian depannya → ISR halaman
keseluruhan proyek, dialihkan ke klien useCSR = True di nexyconfig.py → CSR proyek

Peralihan seluruh proyek, di nexyconfig.py. Mode klien memerlukan kerangka klien:

nexyconfig.py
from nexy.core.models import NexyConfigModelfrom nexy.frontend import react  class NexyConfig(NexyConfigModel):    useFF = react()    useCSR = True

Tidak ada. Setiap tampilan yang dikembalikan pengontrol dirender pada setiap permintaan: ISR dan CSR adalah mode router berbasis file.

Contoh

src/rute/blog/[siput].nexy
---slug: prop[str] = "untitled"---<h1>{{ slug }}</h1>

GET /blog/hello menjalankan templat ini satu kali, dengan slug disetel ke hello. Permintaan kedua menjalankannya lagi: tidak ada yang disimpan di antara keduanya. String kueri bukan penyangga - bacalah dengan kait di navigasi.

src/apps/blog_controller.py
from nexy.decorators import Controllerfrom nexy.hooks import useViews  @Controller("/blog/{slug}")class PostController:    async def get(self, slug: str):        return useViews("src/apps/post_view.nexy", context={"slug": slug})
src/apps/post_view.nexy
---slug: prop[str] = "untitled"---<h1>{{ slug }}</h1>

GET /blog/hello/ menjalankan tampilan ini satu kali, dengan slug diatur ke hello. Permintaan kedua menjalankannya lagi: tidak ada yang disimpan di antara keduanya. String kueri bukan prop - bacalah dengan useSearchParams.

Keterbatasan

  • Satu render per permintaan. Dua pengunjung dalam detik yang sama masing-masing membayar untuk render dan pertanyaan di baliknya.
  • Tidak ada cache. Tidak ada cache respons bersama untuk menghangatkan: dengan rute file, ISR menambahkan satu, per URL.
  • Streaming hanya membantu komponen yang menghasilkan. Permintaan yang lambat di bagian atas halaman masih menunda byte pertama.
  • Tidak ada keluaran statis. Dalam mode server tidak ada yang dibekukan saat build: tidak ada mode SSG, dan tidak ada perintah ekspor. Lihat Render.
  • Pelarian otomatis tidak aktif di .nexy templat. Hindari nilai-nilai yang tidak dipercaya dengan | e.
src/rute/pencarian.nexy
---from nexy import useSearchParams q = useSearchParams().get("q", "")---<p>Results for {{ q | e }}</p>
src/apps/search_view.nexy
---from nexy import useSearchParams q = useSearchParams().get("q", "")---<p>Results for {{ q | e }}</p>

Langkah selanjutnya

  • ISR: cache halaman ini per URL
  • Pulau: pertahankan SSR dan buat satu widget menjadi interaktif
  • CSR: navigasi tangan ke browser

Sunting di GitHub

Enter membuka hasil, Esc menutup.