访客对页面耐心的阈值极低,加载稍慢便会流失。提升速度不是某个岗位的孤军奋战,而是从代码打包、网络传输、缓存命中到浏览器绘制的系统性工程。下面这套前后端配合的执行方案,帮你逐层减少耗时。
打包产物体积直接划定了网络传输的下限。除了启用压缩插件清理注释和空白符,务必开启 Tree Shaking 以自动移除未引用的导出代码,防止冗余模块进入最终文件。同时,将固定的第三方库(如框架、工具库)单独打包成独立 chunk,利用浏览器持久缓存,后续发版时访客只增量下载业务代码。
判断标准:打开开发者工具的 Network 面板,重点看瀑布图中是否存在超过 200KB 的单文件。若有,需考虑将该模块改为按需加载或拆分为动态 import 路由级代码。
自定义字体常拖慢首屏,为 @font-face 添加 font-display: swap 属性,让文字先用系统字体占位,避免白屏。图片则采用响应式方案(srcset 配合 sizes),让 CDN 依据设备宽度返回裁剪后的图片,阻止手机访问时下载桌面端大图。
避坑提醒:拆分代码时需合理设置 splitChunks 的最小体积阈值,若拆分过碎产生大量小于 10KB 的请求,反而会导致握手开销超过传输收益。
传输阶段的收益十分直观。后端确认已开启 Brotli 压缩(比 Gzip 进一步缩小体积),并确保 HTTPS 下启用 HTTP/2,实现单连接多路并行下载,绕开浏览器对同域名的并发限制。
前端可主动减少握手等待:在 HTML 头部对即将访问的第三方域名或 CDN 节点添加预连接声明,提前完成 DNS 解析和 TCP 握手。对于需要点击才出现的弹窗、懒加载组件,使用动态 import 将请求推迟到用户触发那一刻。
评估标准:利用 WebPageTest 观察 TTFB 数值,若持续超过 600 毫秒,瓶颈多半在服务端响应逻辑或路由节点,应先排查后端吞吐量与网络链路。
警惕压缩误区:对 JPEG、WebP 等已压缩的二进制资源启用文本压缩,只会徒增 CPU 计算开销,不会带来任何体积收益。
浏览器解析 HTML 时遇到同步脚本会暂停解析。把所有脚本移至 body 底部或添加 defer 属性,优先保证 DOM 构建。首屏关键 CSS 采用内联方式放入 head,非关键样式通过 media 属性或异步加载,避免样式表阻塞首次绘制。
布局抖动常源于脚本高频交替读写 DOM。把读取操作(如 getBoundingClientRect)集中完成,再统一执行写操作,可显著减少强制同步布局。动画实现优先使用 transform 和 opacity 属性,两者由 GPU 合成处理,不占用主线程。
排查方法:在 Performance 面板录制加载过程,观察主线程中标识为红色的长任务。针对任意超过 100 毫秒的脚本任务,尝试拆分任务或将其延迟到 requestIdleCallback 中执行。
缓存是重复访问加速的核心。前端构建时给静态资源文件生成内容哈希指纹,文件名一变即表示内容更新;后端响应头中为这些带指纹的资源设置 Cache-Control: max-age=31536000, immutable,实现长期强缓存。而 HTML 文档本身设置为 no-cache,确保每次回源校验版本。
协同做法:服务端需配合处理协商缓存,基于 ETag 或 Last-Modified 判断资源是否变化。若未变化则返回 304 响应,浏览器直接复用本地缓存,不重新下载正文。
避坑建议:不要对所有资源统一设置长时间缓存。对于不带哈希指纹的入口文件,应设置较短的缓存时间或禁止缓存,否则发布新版时浏览器可能继续使用旧文件导致功能异常。
发布前记录优化前的 Lighthouse 性能得分、TTFB 和 LCP 数据作为基准,上线后对比同网络环境下的同项指标。重点观察 LCP 是否小于 2.5 秒,且用户反馈中关于白屏的投诉是否减少,而不只关注得分数字。
HTTP/2 已能解决并发连接限制问题,适合大多数站点。HTTP/3 基于 UDP 协议,在弱网或高丢包环境下改善明显,但对服务器和 CDN 支持有额外要求。建议先确认 CDN 是否支持,再逐步灰度切换测试对比效果。
先审查每个第三方脚本的用途,移除可有可无的统计或客服组件。保留的脚本尽量添加 async 或 defer 属性以避开阻塞。对体积较大的第三方服务,考虑延迟加载,或待用户交互后再插入脚本标签。
性能提升不是一次性修复,而是持续调优的过程。建议先通过 Performance 面板定位当前最大瓶颈,优先解决阻塞渲染和超大资源问题,再逐层优化传输与缓存。