极致的SSR性能优化

前言

一谈到 SSR,大家可能立马想到以下关键词:

  • FCP首屏时间优化
  • SEO友好

现在去实现 SSR 并不难,Next.js / Nuxtjs 为我们提供了良好的上层封装,我们很容易获得上述 SSR 的好处。

但怎么进一步提升 SSR 的性能呢?

嘿嘿,这就是本文要讲的了。我们将会从以下三个模块入手,去将 SSR 性能优化到极致🔥🔥🔥

1. 关键性 CSS

首先解释一下,什么是关键性 CSS。

我们常规的一个 nextjs 项目,假设你使用 css module 的话,它是会将你的 css 抽取成为一个文件,然后去使用 link 标签去加载这个文件的地址,像 mini-css-extract-plugin 就是用来干这个的。

它的问题是什么呢?

chrome 的 web-vitals 团队已经把答案给我们了: 一个字,慢!。这是因为就算你的 html 已经加载完毕了,但如果此时 css 还没有加载好,页面也不会渲染。

有兴趣看这个图完整文章的可以戳这

那此时关键性 CSS 的意思已经呼之欲出了,它就是让我们的 html 不阻塞,直接渲染的 css。它的做法也很简单:不要去将 css 提取到一个文件中,而是直接在我们的页面渲染的时候,将 css 转换为 style 标签,插入到我们的 head 标签中。

最佳实践:将首屏的 css 提取为关键性 css,而次屏的 css 依然使用外链插入,这样可以减少 html体积

2. 流式渲染

流式渲染可以显着减少 TTFB(第一个字节时间)、FCP(首次内容绘制)和 TTI(交互时间)。

首先来看一看常规的 SSR 是怎么工作的

  1. 服务器请求后端接口
  2. 服务器渲染 html
  3. 服务器发送 **完整的 html **
  4. 浏览器解析 html, 请求 js css 图片,字体等静态资源。

它的问题又在哪?

步骤1,2,3,4是完全串行的,步骤1请求后端接口和步骤4其实可以并行进行,因为请求到达服务器时候,理论上我们就可以把这个页面需要的静态资源下发了。更大的问题是我们要在服务器等待页面所有的后端接口都返回,如果有一个后端接口很慢,它会推迟页面整体的渲染时间

流式渲染的目的就是解决常规 SSR 的问题。

流,顾名思义,就是把内容一部分一部分,像水一样流动出去,其实也就是在浏览器和服务器之间建立一个通道,持续传输 html

流式渲染的步骤如下

  1. 服务器先发送 head ,将 js css 字体,图片等静态资源下发
  2. 服务器请求快速的后端接口,对于慢的后端接口,直接把它相关的页面部分渲染成为骨架屏
  3. 服务器发送 html(含有骨架屏)
  4. 慢的接口返回之后,再将慢接口相关的页面部分渲染出来,发送一个 script 脚本来替换骨架屏

效果如下:

3. SPA回退

SPA回退是干什么的呢?

想象一个电商场景,一到 618,双十一这样的节日,页面的流量将会暴涨。

而我们的 SSR 服务器其实挺吃资源的,那么流量太大呢,很容易就把服务器打挂了。

所以这个时候我们就需要 SPA 回退了,也就是让服务器只发送一个空的 html 骨架,然后再让 js 去加载页面的内容,它能够大大提升服务器的吞吐量。

结语

讲了这么多,好像还剩下一个最大的问题:

怎么实现呢?

遗憾的是,像Next.js这样的框架中,并不支持对 css 模块的关键性 css提取,也不支持 SPA 回退, 只有流式渲染这个功能,会在 服务器组件 中捆绑支持,而 服务器组件 又是一个特别改变大家对 React 心智的新功能🤬🤬🤬。

不过对于那些使用自定义 webpack 来进行 ssr 的同学来说,好消息来啦!

我写了一个完全支持上述三个功能的 React 流式渲染 SSR框架,直接支持 React18 React19

同时,我也实现了一个对于 React17例子

你可以直接参照我的做法来给公司的项目接入流式渲染,性能优化的点这不就来了吗🔥🔥🔥

相关推荐
6***34911 分钟前
Vue混合现实案例
前端·vue.js·mr
p***434818 分钟前
Vue混合现实开发
前端·vue.js·mr
ArkPppp19 分钟前
大道至简-Shadcn/ui设计系统初体验(下):Theme与色彩系统实战
前端·前端框架
炒米233320 分钟前
通义千问Qwen3-Coder模型帮我总结的typescript笔记
前端
__花花世界26 分钟前
前端日常工作开发技巧汇总
前端·javascript·vue.js
0思必得038 分钟前
[Web自动化] HTTP/HTTPS协议
前端·python·http·自动化·网络基础·web自动化
冰封剑心1 小时前
MiniCPM-V-2_6 (4-bit 量化)使用
java·前端·数据库
q***42821 小时前
SpringCloudGateWay
android·前端·后端
爱泡脚的鸡腿1 小时前
uni-app D5 实战(小兔鲜)
前端
tomato_4041 小时前
本地系统、虚拟机、远程服务器三者之间的核心区别
前端