初衷

先介绍下之前博客的技术栈

  • 前端,单纯的 vite+react,SSR 也是自己折腾的,然后 SSR 做了个缓存,在第一次访问后会将服务器渲染的结果缓存,一段时间后失效。使用 docker 部署到自己服务器上的
  • 后端,用的 nestjs+graphql,数据库用的 PostgreSQL,都是 docker 部署到自己服务器的
  • 博客内容,这里也是单独开了一个仓库,然后用 github action 在文件更新时上传到服务器上

实际操作下拉我发现我这样设计下来有很多问题

  1. 仓库太多,每次调整都很麻烦,都要启动很多服务,再小的改动都要提交两个仓库。
  2. github action 失败后调整太麻烦,之前在 action 中加入了 gpt 生成摘要的功能,后面发现这个 gpt 请求的失败频率太高了,每次都要去数据库手动调整,还不如手动复制到 gpt 生成。
  3. 体验问题,虽然 SSR 能保证首屏渲染速度,但是后续页面跳转还是需要等待请求的,虽然后面我尝试在鼠标悬浮在链接上时预加载,但还是有一定的延迟,作为一个几乎静态的内容,这个请求完全是可以避免的。

前两个问题很容易处理,第三个问题我发现react 的服务器组件能很好地解决,虽然名字叫服务器组件,但是实际上并不需要服务器,完全可以打包成静态文件。

重构

事实上这几乎算是完全重写了,重构后的技术栈非常简单

  • 前端,nextjs+turbo,使用服务器组件基本只能使用 nextjs,没办法。页面样式也是重新实现了,一切从简。部署是直接打包成静态文件了,这里为了方便直接放 vercel 上了。
  • 后端和数据库,使用了免费planetscale,因为是完全的静态部署,其实后端和数据库都不需要了,但是为了方便记录一些数据,还是加了数据库
  • 博客内容,和前端放在一个仓库,更新时本地跑下个上传命令到数据库,还是这种能直接有结果的方式更适合我

重构下来的我最大的感慨是当时使用 nextjs 能少走很多弯路,不过这都是马后炮了,毕竟当时 nextjs 还不支持服务器组件。

体验

开发

先说下我开发中的一些体验

文档

nextjs 的开发体验并不是很友好,中文文档更是落后非常多,尤其是服务器静态打包这里,文档里很多都没介绍,我这里也是摸索了很久才搞定。

路由

nextjs 的路由不能根据 query 参数来打包,一般分页查询是会在 query 上增加参数,这里是只能将查询参数放在 path 上。

水合

之前 SSR 的时候很容易碰到水合问题,不过使用了服务器组件后,这个目前还没碰到过。因为客户端和服务端都是用的同一个序列化结果,这个很大程度上就避免了水合问题。

页面

首屏渲染

首屏渲染这点和之前 SSR 的方式没什么差距,lighthouse 都能到满分,毕竟页面比较简单。不过之前 ssr 没缓存的时候,首屏渲染速度还是有一定的延迟,对比下来还是有一定地提升。

页面跳转

页面跳转这个提升非常明显,现在跳转只需要获取一个打包好的序列化文件,甚至可以在页面打开或者鼠标悬浮时预加载,并且服务器组件的渲染速度也是比客户端组件快很多,所以点击跳转的速度非常快,基本看不出任何延迟。

这里说一下Astro,之前也考虑使用这个框架,虽然它首屏做了很多优化,但它这个跳转体验我觉得有些糟糕,它不同页面都是一个新的 html,所以每次跳转返回都需要重新加载刷新页面,会有一段时间的白屏,这个给人的体验是非常差的。

总结

服务器组件大概是目前最适合搭建博客的方式了,首屏渲染速度也不错,很容易增加动态的交互内容,而且静态内容的跳转体验非常好