DocsModos
SSR (renderizado del servidor)
Definición
SSR es el valor predeterminado: el servidor representa la página en HTML para cada solicitud. Nada lo habilita y ningún indicador lo desactiva: un proyecto en modo servidor se procesa en cada solicitud a menos que una página declare revalidate.
como funciona
| Archivo de ruta | ¿Qué produce el HTML? | cuando |
|---|---|---|
.nexy |
el módulo compilado Python, hasta Jinja2 | cada solicitud |
.md |
Markdown, luego el diseño más cercano | cada solicitud |
.mdx, .tsx, .vue, .svelte |
el marco, representado en Node | en la compilación cuando la ruta no tiene diseño; de lo contrario, en el navegador |
.py |
nada: devuelve JSON o un Response |
- |
Una página Markdown y un controlador, uno al lado del otro en el mismo proyecto:
# Changelog Rendered to HTML on every request, then wrapped in the nearest layout.async def GET(): return {"status": "ok"}Una ruta componente es el único caso que necesita una segunda oración. En producción, una ruta de componente sin un diseño se entrega con el HTML producido en la compilación y el componente lo hidrata. Con un diseño, o en desarrollo, el contenedor está vacío y el componente se representa en el navegador; la página es entonces un caparazón que se llena solo.
La ruta del componente de la tabla, sin diseño, por lo que la producción entrega su HTML desde la compilación:
export default function Pricing() { return <h1>Pricing</h1>;}| Un controlador regresa | ¿Qué produce el HTML? | cuando |
|---|---|---|
useViews("....nexy") |
el módulo compilado Python, hasta Jinja2 | cada solicitud |
un dict, una lista, un modelo |
nada: FastAPI responde JSON | - |
Una vista y un punto final JSON, uno al lado del otro en el mismo módulo:
<h1>Changelog</h1><p>Rendered to HTML on every request.</p>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"}Ciclo de vida de renderizado
-
La solicitud llega al enrutador basado en archivos. La ruta coincide y los segmentos dinámicos se convierten en los tipos que declara el componente.
id: propiedad[int]<h1>N.º de pedido{{ id + 1000 }}</h1>/orders/42representaOrder #1042;/orders/abcresponde404. -
El componente se ejecuta. Uno que espera en Node (un documento de cliente) se ejecuta en un grupo de subprocesos, por lo que no detiene el bucle de eventos.
-
El cuerpo se transmite como
text/html. Un componente que produce trozos los transmite a medida que los produce. -
El navegador recibe HTML. Las islas se hidratan según su directiva.
Un error generado durante el renderizado se convierte en una página mediante errors.nexy cuando el proyecto tiene una: consulte páginas de error.
-
La solicitud llega al controlador. Sus parámetros de ruta se convierten a los tipos que declara el método y se pasan a la vista:
desde nexy.decorators importar controladordesde nexy.hooks importar useViews @Controller("/pedidos/{id}")clase Controlador de pedidos: asíncrono def get(self, id: int): devolver useViews("src/apps/order_view.nexy", contexto={"id": id})id: propiedad[int]<h1>N.º de pedido{{ id + 1000 }}</h1>/orders/42/representaOrder #1042;/orders/abc/responde404. -
La vista se ejecuta y
useViewsdevuelve su HTML como respuesta. -
El navegador recibe HTML. Las islas se hidratan según su directiva.
Un error generado durante la renderización se responde con la página de error predeterminada.
cuando usar
- La página muestra algo que pertenece al lector: una sesión, una cuenta, un carrito.
- Los datos deben estar actualizados en cada carga.
- El contenido debe estar en HTML para los rastreadores que no ejecutan JavaScript.
- La página es barata de renderizar: una consulta, una plantilla.
El primer caso, una página que saluda al lector desde la sesión. useSession lee la sesión de useSession en nexyconfig.py, sin la cual falla:
from nexy.core.models import NexyConfigModel class NexyConfig(NexyConfigModel): useSession = {"secret_key": "change-me"}from nexy import useSession user = useSession().get("user", "guest")<h1>Signed in as {{ user }}</h1>from nexy import useSession user = useSession().get("user", "guest")<h1>Signed in as {{ user }}</h1>Configuración
Ninguno. Dos salidas y no tienen el mismo grano:
| Dejar SSR por | haz esto | grano |
|---|---|---|
| una página, con un caché | revalidate = 60 en su introducción → ISR |
página |
| todo el proyecto, enrutado por el cliente | useCSR = True en nexyconfig.py → RSE |
proyecto |
El cambio de todo el proyecto, en nexyconfig.py. El modo cliente necesita un marco de cliente:
from nexy.core.models import NexyConfigModelfrom nexy.frontend import react class NexyConfig(NexyConfigModel): useFF = react() useCSR = TrueNinguno. Cada vista que devuelve un controlador se representa en cada solicitud: ISR y CSR son modos del enrutador basado en archivos.
Ejemplo
slug: prop[str] = "untitled"<h1>{{ slug }}</h1>GET /blog/hello ejecuta esta plantilla una vez, con slug establecida en hello. Una segunda solicitud lo ejecuta nuevamente: no se guarda nada entre los dos. La cadena de consulta no es un accesorio; léala con los ganchos en navegación.
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})slug: prop[str] = "untitled"<h1>{{ slug }}</h1>GET /blog/hello/ ejecuta esta vista una vez, con slug establecido en hello. Una segunda solicitud lo ejecuta nuevamente: no se guarda nada entre los dos. La cadena de consulta no es un accesorio; léala con useSearchParams.
Limitaciones
- Un render por solicitud. Dos visitantes en el mismo segundo pagan cada uno por el render y por las consultas detrás de él.
- Sin caché. No hay un caché de respuesta compartido para calentar: con rutas de archivos, ISR agrega uno por URL.
- La transmisión por secuencias solo ayuda a un componente que rinde. Una consulta lenta en la parte superior de la página aún retrasa el primer byte.
- Sin salida estática. En el modo servidor, nada se congela en la compilación: no hay modo SSG ni comando de exportación. Consulte Renderizado.
- El escape automático está desactivado en
.nexyplantillas. Escapa de valores que no son de confianza con| e.
from nexy import useSearchParams q = useSearchParams().get("q", "")<p>Results for {{ q | e }}</p>from nexy import useSearchParams q = useSearchParams().get("q", "")<p>Results for {{ q | e }}</p>Próximos pasos
- ISR: almacena en caché esta página por URL
- Islas: mantenga SSR y haga que un widget sea interactivo
- CSR: navegación manual al navegador