SSR(Server-Side Rendering 服务端渲染)是一种在请求时在服务器上而不是在浏览器中渲染 Web 页面的技术, 这允许 Web 页面在服务器上呈现并作为静态 HTML 发送到客户端。SSR 有很多好处:
servite 已经默认开启了 SSR,无需额外配置。
为了让渲染的内容在服务端和客户端保持一致,需要注意以下几点:
当 SSR 出错,或者因为机器性能瓶颈等原因,我们需要将 SSR 降级为 CSR,以提高页面的可用性。
当 SSR 出错时,Servite 会主动降级为 CSR,这无需开发者手动操作。
给页面 URL 添加 ssr_fallback=1
参数,可以主动降级为 CSR。
例如,将原始地址 https://www.xyz.com/pageA
修改为 http://www.xyz.com/pageA?ssr_fallback=1
,
使降级即时生效。
给页面添加 x-ssr-fallback: 1
请求头,也可以主动降级为 CSR。
在中间件 onRequest 里可以通过设置 event.context.ssr = false
在请求处理过程中主动降级为 CSR。
// src/server/middlewares/<name>.ts
import { defineMiddleware } from 'servite/runtime/server';
import os from 'os';
export default defineMiddleware(async (event, next) => {
// 如果系统负载过高,则主动降级为 CSR
if (event.path === '/pageA' && os.loadavg()[0] > 1.5) {
event.context.ssr = false;
}
return next();
});
TODO
在中间件 onRequest 里可以通过 event.context.html.inject()
方法给 SSR 返回的 HTML 注入标签。
// src/server/middlewares/<name>.ts
import { defineMiddleware } from 'servite/runtime/server';
export default defineMiddleware(async (event, next) => {
if (event.path === '/pageA') {
// 给 ssr 返回的 html body 加上额外的 script
event.context.html.inject({
injectTo: 'body',
tag: 'script',
attrs: {
src: '...'
}
});
}
return next();
});
也可以通过 event.context.html.addTransformer()
方法修改 SSR 返回的 HTML 内容:
// src/server/middlewares/<name>.ts
import { defineMiddleware } from 'servite/runtime/server';
export default defineMiddleware(async (event, next) => {
if (event.path === '/pageA') {
// 修改 ssr 返回的 html string
event.context.html.addTransformer(html => {
return html.replace('<body>', '<body><div>Hello World</div>');
});
}
return next();
});
需要注意的是,Servite 使用的是 Streaming SSR,所以上述 html transformer 会被多次调用,即每个 html 分块都会被调用一次 transform, 所以在 transform 函数中修改 html 内容时需要注意避免重复修改。