前端性能优化之首屏提速

一、问题

在页面运行过程中,我明显发现web的首屏加载时间很长,用户点击后会出现长时间白屏,体验非常不好。我在build log里看到了warning,打包后的文件体积过大,解决对策是做代码分块。

这一块我之前完全没有实战经验,一开始几乎没有思路,也不理解首屏变慢的根本原因。后来才知道主要是资源下载耗时久、网络带宽有限,以及资源解析与编译阻塞渲染。

不过这一块我没有深刻学习,只是简单记录一下,复盘与反思,太多底层原理没有深究,零散地看了资料...

二、优化:减小前端包体积

在进入具体技术实现前,先统一对"性能"的认知。性能优化不能凭感觉,必须基于数据和用户体验。

  • 分块(Code Splitting):这不仅仅是 React.lazy 或 Webpack 的 splitChunks 配置,它本质上是资源加载时机与优先级管理。
  • 首屏速度(First Contentful Paint/LCP):这是性能优化最核心的指标。
  • 懒加载:这是一种延迟满足的策略。

为了减小前端包体积,我去看了一个ytb视频,了解到可以用 React lazy、路由分包、按需加载、动态加载等方式,避免一次性导入整个依赖包。

ES6 Module是 ES6 官方定义的标准化模块化方案 ,旨在统一浏览器与服务器端的模块化语法,解决传统模块化方案(如 CommonJS、AMD)的碎片化问题,其核心特性包括静态化设计,可实现Tree-Shaking(摇树优化,剔除未使用的代码)。

例如这里我采用动态导包,不是在首屏的时候就导这些包。

ts 复制代码
export const exportToPdf = async (editor: any): Promise<Blob> => {
  const [{ PDFExporter, pdfDefaultSchemaMappings }, { default: ReactPDF }] =
    await Promise.all([
      import("@blocknote/xl-pdf-exporter"),
      import("@react-pdf/renderer"),
    ]);
  const exporter = new PDFExporter(
    editor.schema,
    pdfDefaultSchemaMappings as any,
  );
  const pdfDocument = await exporter.toReactPDFDocument(editor.document);
  const blob = await ReactPDF.pdf(pdfDocument).toBlob();

  return blob;
};

这块没有大量写业务代码,更多是在理解原理,做了一个通识性质认识。看得不算深/(ㄒoㄒ)/~~

三、工具配置:Rollup 与包体积分析

我先配置了 rollup-plugin-visualizer 做打包分析

  • rollup-plugin-visualizer 用于可视化和分析 Rollup 打包产物,查看哪些模块占用了更多空间,可通过配置生成不同类型的视觉化报告,支持计算并展示压缩后的文件大小信息。

一开始我很疑惑,项目用的是 Vite,为什么会用到 Rollup?

查资料后才明白,Vite 在生产构建时底层就是基于 Rollup。

当需要将应用部署到生产环境时,运行 vite build 命令,Vite 会生成能够静态部署的应用程序包,其构建过程底层基于 Rollup,可通过 build.rollupOptions 直接调整底层的 Rollup 选项。

在看 Rollup 文档时,又遇到了 CommonJS、ES5、ES6 模块化规范,这部分我不太熟悉,重新查了资料,大概理解这是模块化语法的历史演进:

CommonJS 是 Node.js 主要实践的模块化规范,通过 module.exports 定义模块对外接口,用 require 加载模块,采用同步加载方式;

ES6 Module 是官方标准化方案,每个 js 文件都是一个独立的模块,通过 import 导入、export 导出模块成员,采用编译时静态加载。

四、分包不是越细越好

我当时最大的瓶颈就是打包体积太大,必须做拆包优化。在 HTTP 多路复用机制下,包拆得越碎,性能就越好吗?分块并不是越多越好,因为 HTTP 协议存在请求并发限制。

HTTP/1.1 中,现代浏览器通常限制单个域名同时建立6-8个并发连接;HTTP/2 引入多路复用后,通常只需1个连接,但每连接可并发多流(100-128流/连接),分包过细会受限于协议层的并发限制,反而影响性能。

五、性能测评

配置完插件后,就要对网页做性能测评。我之前完全不会用 Lighthouse 做性能评估,也没有用过专业的性能分析工具,更不清楚移动端网页有更严格的评测标准。我之前还错误地以为,看构建日志和构建速度,就能判断性能好坏。

打包后我还踩了一个坑:一开始直接在开发环境看性能,正确的方式应该以生产构建为准!!!

Vite 的开发环境与生产环境存在差异,生产构建会对代码进行压缩、优化,生成可直接部署的产物,而开发环境主要用于开发调试,不适合用于性能测评,需运行build生成生产包后再进行性能测试。

我也学着看网络瀑布流,分析请求排队、服务器响应、资源下载等阶段耗时,还尝试观察性能火焰图。期间我误读了耗时指标,以为性能变差,反复做了多次首屏时间测试与模拟验证。

六、实践总结

整个过程下来,工作量不算复杂,但暴露了很多基础问题。

我最大的误区就是用生产环境直接调试,正确做法应该使用构建后的产物做分环境部署。另外安装新插件后,lock 文件也要同步更新。

这轮优化我没写多少代码,就做了配置,但深刻感受到自己很多技术都没接触过,也缺少很多"常识"。对于前端开发的学习远远不够,还是要坚持学习,多思考。

相关推荐
AnalogElectronic2 小时前
树莓派 RP2040 学习笔记1
笔记·学习
秋饼2 小时前
[EXPLAIN:SQL 执行计划分析与性能优化实战]
android·sql·性能优化
_下雨天.2 小时前
Linux系统安全学习
linux·学习·系统安全
我命由我123452 小时前
Git 创建新分支并推送到远程仓库
java·服务器·git·后端·学习·java-ee·学习方法
天天向上10242 小时前
vue 大屏适配的一种实现思路
前端·javascript·vue.js
SuperEugene2 小时前
Vue/Vite 多环境配置实战:dev、test、prod 差异区分与避坑指南|Vue 工程化篇
前端·javascript·vue.js
山峰哥2 小时前
SQL优化全攻略:从索引策略到Explain实战解析
大数据·数据库·sql·oracle·性能优化·编辑器
结网的兔子2 小时前
前端学习笔记(实战准备篇)——用vite构建一个项目【吐血整理】
前端·学习·elementui·npm·node.js·vue