
首页加载时间一直停留在5秒左右,跳出率很高。主要问题不是后端接口,而是前端资源大小和网速慢。解决思路有三条:减小文件大小、延迟加载、使用CDN边缘节点进行缓存,这三者之间相互影响,形成了一个循环。
资源压缩:由“可以节约就节约”转变为“最大限度节省”。
- 使用JavaScript和CSS进行Gzip+Brotli双重压缩之后,文本资源的体积减少了65%以上。
- 把所有的图片都转换成WebP或者AVIF格式,并且使用响应式的
srcset来优化首屏图片的大小,由原来的3.2MB减少到480KB。 - 去掉没有用的CSS和死代码之后用PurgeCSS进行扫描,使CSS文件大小由原来的180KB减少到现在的42KB。
- 把重要的CSS放在
<head>中,不重要的CSS则异步加载,防止页面被阻塞。
懒加载:把看不见的数据先不动
- 除了第一页之外的所有图片和iframe都加上了
loading="lazy"属性,并且用Intersection Observer来实现组件级别的懒加载。 - 采用路由级别进行代码分割,把非首页的路由对应的JavaScript文件单独打包成一个chunk,使首页加载时间由原来的1.8MB减少到现在的620KB左右。
- 使用
font-display: swap来防止FOIT造成的白屏问题。
CDN边缘缓存:把内容推送到距离用户最近的地方
- 所有静态资源(包括JavaScript、CSS、图片和字体等)都放在了CDN的边缘节点上,设置了
max-age=31536000, immutable的缓存策略。 - 设置HTML文档的边缘缓存为60秒,使用
stale-while-revalidate来保证数据的新鲜度并减少请求次数。 - 采用HTTP/2 Server Push以及后来升级到HTTP/3的方式来进行多路复用来降低握手时间,边缘节点的命中率为92%左右。
协同作用:1+1+1>3
经过压缩之后的小文件使得CDN传输速度更快了,懒加载减少了首屏请求的数量从而提高了CDN边缘缓存命中率,再加上CDN本身具有低延迟的特点,三者共同作用之下,首屏加载时间由原来的5秒缩短到了1秒左右,Lighthouse性能评分也从38分提高到了92分,跳出率降低了41%。
前端资源压缩、懒加载和CDN边缘缓存不是单独的作用方式,而是互相咬合在一起的齿轮。压缩可以减少一次传输的成本,懒加载可以减小首屏请求的数量,而CDN边缘缓存则能缩短网络路径。三者共同作用之下把加载时间由原来的5秒缩短到了现在的1秒左右,证明了“性能优化没有银弹,只有系统性的配合”的说法是正确的。