一年前接了个官网的开发的活(这个文章其实也写了一年了!),使用 nuxt3 进行开发,使用 SSG 模式即执行 nuxt generate 后将产物进行部署
测试环境: mac m1 16、 谷歌 136
开发部署完成后客户反应说打开速度有点慢,实际测试了下发现确实有点慢,直接看图

在无痕模式禁用缓存的情况需要近 20 多秒才能加载完成,它不正常!
再来看下优化后的加载情况

一秒内!几乎是秒开了,那我都干了什么呢?
开启 http 2.0
让 gpt 先做个总结
| 特性 | HTTP/1.1 | HTTP/2.0 |
|---|---|---|
| 协议格式 | 文本格式 | 二进制格式 |
| 多路复用 | 不支持,一个连接一次只处理一个请求 | 支持,一个连接可同时处理多个请求 |
| 头部压缩 | 无(头部冗余较多) | 使用 HPACK 进行头部压缩 |
| 服务器推送 | 不支持 | 支持,服务器可主动推送资源 |
| 连接复用 | 多个请求需多个 TCP 连接或排队 | 所有请求共享一个 TCP 连接 |
| 队头阻塞(HOL) | 存在,阻塞严重 | 解决,通过帧分片并异步处理 |
| 加密(TLS) | 可选 | 可选(多数实现默认启用) |
还有一个很重要的点是 同一域名下的并发连接数限制 http 1.1 是最多 6个, http 2.0 则是所有请求复用单一连接,通过多路复用并发处理,效率更高
开启 gzip
nuxt3 貌似并没有提供 gzip 压缩的相关操作,这个项目使用 docker 部署在镜像 nginx 中配置了 gzip 压缩

调试面板这样显示表示 gzip 配置成功!
使用 NuxtPicture 优化图片加载
html
<NuxtPicture
format="avif,webp"
:src="getImg('/about/banner.png')"
:alt="$t('about.title')"
:img-attrs="{ style: 'width: 100%' }"
width="1920"
height="578"
placeholder
loading="lazy"
/>
loading img 原生属性图片可见时加载
format 响应式图片加载,单从图片压缩后大小来看 avif < webp < jpg < png 这里是如果浏览器支持 avif or webp 就使用 否则使用原始图片也就是 src 设置的图片
响应式图片加载
这里以首页封面图为例
html
<picture>
<source type="image/avif" srcset="home/banner.avif">
<source type="image/webp" srcset="home/banner.webp">
<img src="home/banner.png" alt="用中文链接世界"class="w-full">
</picture>
<picture>元素:用于为不同的设备或浏览器条件提供不同的图片资源。<source>标签:指定不同格式的图片(如 AVIF、WebP)。- 降级加载(Fallback) :如果浏览器不支持 AVIF,会加载 WebP;都不支持则加载 PNG。
| 格式 | 压缩类型 | 浏览器兼容性 | 文件大小(相同质量) | 加载速度 | 适用场景 |
|---|---|---|---|---|---|
| AVIF | 有损/无损 | 较新浏览器支持良好 | 最小(高压缩率) | 快 | 现代 Web,体积敏感场景 |
| WebP | 有损/无损 | 主流浏览器广泛支持 | 较小 | 快 | Web 图片优化 |
| PNG | 无损 | 全面支持 | 大 | 慢 | 图标、透明图、高质量图像 |
| JPG | 有损 | 全面支持 | 中 | 快 | 摄影、背景图等色彩丰富图片 |
通过上边的表格可以看出来同样质量的图片 AVIF、WebP 体积要小于 PNG、JPG 下边来对比一下
AVIF 440KB -> 156KB 减少了 65%

WebP 440KB -> 156KB 减少了 65%

看到这里你觉得也许不过如此!但是如果把图片质量下降到 70 AVIF 图片的体积可以减少到 35KB 减少 92% 的体积

AVIF 与 PNG 加载速度对比
AVIF- 34ms

PNG 3.36秒

1. 字体文件放到 cdn 2. 延迟字体加载
另一个拖慢加载的元凶是字体加载

最初的方式是创建一个 font.scss 文件
scss
@font-face {
font-family: 'AlibabaPuHuiTi-3-55-Regular';
src: url('/public/fonts/AlibabaPuHuiTi/AlibabaPuHuiTi-3-55-Regular.woff2') format('woff2');
font-weight: normal;
font-style: normal;
font-display: swap;
}
在 index.scss 中引入
scss
@use './font.scss';
然后配置 nuxt.config.ts
ts
css: [
'~/assets/style/index.scss',
],
这样做会导致字体文件参与打包并和其他js、css 等文件同时加载

可以这样改把 font.scss 改为 font.css 放到 public/fonts/font.css 中
然后修改 nuxt.config.ts
ts
app: {
head: {
link: [
{
rel: 'stylesheet',
href: '/fonts/font.css',
media: 'print',
onload: 'this.media=\'all\'',
},
],
},
},
这样 font.css 就会延迟加载从而延迟加载字体文件且字体文件不会参与打包

合理优化图片可以让官网加载速度提升
首页打开加载完成时间从 26 秒 减少到 2 秒,性能提升了约 92.31% ,即 13 倍。


总结
通过使用 http2.0 、gzip、图片懒加载、响应式图片加载、延迟字体加载等操作可以让首页达到秒开的效果
就这么简单的几步就可以让首页加载速度提升一个级别
这还是无痕禁用缓存下的数据,如果不禁用缓存还会更快
图片压缩工具是 squoosh.app