事情是这样的。
上个月老板突然甩给我一个链接,说公司官网的首页在手机端打开要5秒多,客户都跑了。我点开一看,好家伙,首屏加载时间5.8秒,Lighthouse评分才38。老板的原话是:“你这个页面,比我妈做的红烧肉还慢。”
我当时心里不服,心想又不是我写的,这是外包团队半年前交付的。但没办法,锅在我头上,只能硬着头皮干。
先说说这个页面到底有多离谱。我用Chrome DevTools的Performance面板录了一段加载过程,发现最大的问题不是图片太大,而是那个“全屏轮播图”的JS插件。它加载了整整1.2MB的JavaScript,里面还打包了jQuery、Swiper、还有几个不知道哪来的polyfill。更离谱的是,这个轮播图在首屏根本不可见——它被一个loading遮罩挡住了,用户要先等那个遮罩消失才能看到轮播。
这不就是典型的“先拉一坨屎,再擦干净”吗?
我第一个动手的是图片。首页有12张产品展示图,全是1920px宽的PNG,每张大概800KB到1.2MB。我直接用Sharp在构建时转成WebP,尺寸按设备分辨率切成3档:320px、768px、1200px。图片体积直接缩到原来的15%到20%。举个例子,原来那张1.2MB的产品图,转成WebP之后只有180KB,肉眼几乎看不出区别。
然后我改图片加载方式。原来用的是`
`这种最原始的方式,所有图片一起下载。我换成`loading=”lazy”`加上`srcset`和`sizes`属性。具体配置长这样:
“`html
srcset=”product-320.webp 320w, product-768.webp 768w, product-1200.webp 1200w”
sizes=”(max-width: 768px) 100vw, 50vw”
loading=”lazy”
alt=”产品展示”>
“`
这样浏览器只在图片快进入视口时才下载,而且只下载适合当前屏幕尺寸的那一张。首屏的图片数量从12张降到了3张。
接着处理那个JS插件。我直接把它从首页移除,换成纯CSS实现的淡入效果。客户说轮播图很重要,但说实话,在首页放一个自动播放的大轮播,转化率数据从来就没好过。我改成3张静态图片加一个渐变切换动画,用CSS animation搞定,总共20行代码,0 JavaScript开销。JS体积从1.2MB降到0。
然后是字体。首页用了Google Fonts的Noto Sans SC,加载了4个字重。每次请求都要先连Google的CDN,在国内那个延迟简直感人。我直接把字体文件下载下来,用`font-display: swap`配合preload。只保留了Regular和Bold两个字重,其他用系统字体fallback。字体文件从原本的800KB降到320KB。
还有一个坑是那个第三方统计脚本。首页嵌了百度统计、Google Analytics、还有一个什么热力图工具。这三个脚本加起来将近400KB,而且都是阻塞渲染的。我把它们全部改为异步加载,用`