React 很适合构建复杂交互,但个人博客首先是内容产品。如果所有页面都等浏览器下载 JavaScript 后才渲染,访问速度、搜索收录和链接预览都会受到影响。
更合适的组合
React Router Framework Mode 可以在构建阶段遍历文章和项目路径,为每个 URL 输出真实 HTML。部署平台只需托管生成结果,导航后仍然保留 React 的浏览器端体验。
这让架构形成了清晰的分工:
- Markdown 负责长期内容;
- 路由 loader 负责读取和校验数据;
- React 组件负责页面呈现;
- Vite 负责开发体验和生产构建;
- CDN 负责稳定交付。
不要让框架替代内容
个人网站最重要的不是技术栈标签,而是能否持续积累文章、案例和公开成果。架构应该降低发布一篇文章的成本,而不是让每次更新都变成一次开发任务。
预渲染究竟解决了什么
静态站的关键是:请求某篇文章 URL 时,服务器直接交付包含标题、摘要和正文的 HTML,而不是只返回一个待浏览器执行的空壳。浏览器仍可在加载脚本后接管交互,但内容阅读不应以 JavaScript 成功执行为前提。React Router 的预渲染文档也明确区分了预渲染路径和需要运行时处理的路径。
这有一个硬约束:构建时必须知道全部文章路径。新增 Markdown 后,构建流程要枚举出对应 URL 并生成 HTML;只让路由在开发环境里“能打开”是不够的。部署前可以直接检查输出目录里是否存在每篇文章的 index.html,再用 HTTP 请求确认深链接返回的是文章页而非统一的首页回退页。
自定义域名下的路径陷阱
本网站就踩过一次坑:站点挂在自定义域名根目录,资源却被构建为仓库子路径 /liangshanbobo/assets/...,结果 HTML 能打开,CSS 返回 404,页面变成未排版的文字。问题不在 React 组件,而在 base、路由前缀和实际托管路径不一致。
因此发布验证至少要覆盖首页、文章列表、单篇深链接、CSS、JavaScript 和 favicon。只看 GitHub Actions 显示绿色,或者只在本地开发服务器测试,不能证明正式域名已经正常工作。
何时不适合全量静态化
如果文章需要登录后按权限实时变化,或内容每分钟更新,全量预渲染可能不合适。可以把公开内容保持静态,把个性化数据交给独立 API;也可以换成支持服务端请求时渲染的平台。对个人博客而言,公开文章变化频率低,静态 HTML 加少量客户端交互通常是更简单、可核查的选择。
把发布流程变成可检查的契约
一次文章发布可以明确成几个条件:Markdown 的元数据完整、slug 唯一、静态构建包含文章 HTML、列表页包含入口、文章页中的站内链接可访问。构建成功只是第一道门;托管平台可能仍因路径前缀、缓存或部署配置导致线上失败。
所以发布后应从正式域名取回首页和新文章,检查状态码与内容,并请求 CSS、脚本等资源。如果站点接了自定义域名,测试也必须用那个域名,不能只测仓库的默认 Pages 地址。这套小检查比不断换框架更能改善读者实际体验。