
SSR为什么比SSG更好用
为什么只需要 SSR 就够了
SSR(server-side rendering),指在服务器运行时按需渲染页面,之后传送到前端。SSG(server-side generation),指事先编译好 HTML 等静态文件,在用户请求时直接把静态文件传到前端。
说清楚了定义就很容易想到,SSR 能嵌入动态的逻辑,但需要始终运行一个服务器,而 SSG 更适合静态的内容,可以放到 CDN 上。知名的 NextJS 框架便同时支持了 SSR 和 SSG。而后起之秀 Remix 则完全抛弃了 SSG,他们认为这样做有足够多的好处。根据我的体会,在现代 CDN 的加持下,这样做确实有一定的道理。
- 像 Cloudflare, Vercel 等现代 CDN 都支持 serverless 环境,部署 NodeJS 程序几乎和部署静态文件一样方便。
- SSG 的好处无非是将静态文件直接部署到 CDN 上,节省服务器资源。而 SSR 通过设置适当的
Cache-Control
,也能轻松的将内容缓存到 CDN 上。这样一来其实只有在第一次请求时才会运行 SSR 服务端,几乎和静态文件无异了 - 不用每次修改静态内容都重新编译、重新部署
- 一旦抛弃 NextJS 那样区分 SSG 和 SSR 的思路,思维负担就少了很多。缓存的设置完全依赖于
Cache-Control
等 HTML 标准,不需要额外学习一套接口。缓存的问题调试起来也方便很多,当浏览器缓存了不该缓存的请求,你只需要看看你编写的Response
即可。
举个例子
事实上,Remix 的官方网站就是一个绝好的例子。它的文档就是用 SSR 生成的。很多人会觉得,文档都是静态文字,用 SSG 不是最好吗?Remix 团队解释了这样做的原因。
他们的文档放在 Remix 的源代码仓库里,并没有直接写在官网里。这样文档和源代码放在一起的好处有
- 阅读代码的时候更有参考性
- 修改代码时能方便地修改文档
- git 会自动记录文档的变动,和源代码版本绑定在一起
官网的服务端读取了 Remix 源代码的仓库,通过 SSR 生成文档页面。这样做的好处是:
- 不用每次修改文档就重新编译和部署整个网站
- 可以直接从 Remix 源代码库里拿到某一版本的文档,甚至可以直接拿到 dev branch 上最新的文档。这样一来官网可以显示任意 Remix 版本所对应的文档。
文档毕竟不是实时变化的数据,所以他们还做了一些缓存优化
- 使用 lru-cache 来缓存文档结果。缓存在服务端,所以所有客户端都会受益。
- timeout 设置为 5 分钟
- 设置
Cache-Control
为stale-while-revalidate
。这样可以让 CDN 也缓存
这样一旦文档有任何修改,官网最多只会延迟 5 分钟(return json( { doc }, { headers: { "Cache-Control": "max-age=300, stale-while-revalidate=604800", }, } );
max-age=300
)显示。