前端性能优化(理念篇)
前言
其实前端性能优化,按照我的理解,首先你公司的硬件条件跟其它资源跟的上,比如服务器资源,宽带怎么样,还有后端接口响应如何,这些资源都具备后,你再说前端的性能优化,因为,如果你服务器宽带垃圾,后端接口响应垃圾,前端优化了也没用,体验还是垃圾的,我相信这种公司,不会考虑前端性能的一个优化手段,考虑最多的是前端的用户交互如何,代码和人能有一样能跑就行了。但一个好的产品,肯定是追求用户的极致体验展现。
唠叨两句,我看到这样的一句话,大部分人智商条件不会有太多的差距,尤其是程序员这个群体,而好奇心可以让你比别人多迈出一步,经过长时间的积累就会拉开很大的差距。而平台可以让你保持专注,与优秀的人共事,获得更多专业的经验和知识、财富,建立自己的竞争壁垒。------ 其实这句话大多数人都是赞同的,但是当一个普通学历的程序员保持一个好奇心也没用,没有一个好的平台,因为可能会追求不到答案,或者是换来一颗能实现就行了,想那么多干嘛,变成了心态的改变。而一个普通学历的程序员想要一个拥有一个好的平台他要展现的东西可多了,各种能力的展现,才能换到好平台的青睐。这是一个社会的现实,因为高学历的人已经证明了他的一个学习能力,各项能力,而你作为一个普通学历的程序员你要让平台看到士别三日当刮目相待,你要展现出你非凡的能力,这样才能受到青睐吧。当然我也只是底层,不敢妄评。总而言之,言而总之,保持初心,坚持下去,活的自在舒服,就行了,工作也只是为了谋生。在哪吃饭不是吃饭~
为什么要做性能优化
性能优化是为了提高网页的加载速度和相应速度,给用户带来更好的体验和用户满意度,同时还能减少服务器的负载压力,以此来提升程序的稳定性,具体有以下几个因素:
- 提高用户体验
- 增加页面访问量
- 提高搜索引擎排名
- 减少服务器压力
- 节约成本
- 提高用户留存率
除此之外还有常见的258
原则、GOOGLE
团队建议
258原则
- 2:页面的加载时间应该控制在2秒以内,这是用户能够接受的最短时间。
- 5:页面的加载时间在5秒以内,用户对页面加载速度的不满意度开始上升。
- 8:页面的加载时间超过8秒,用户的流失率将急剧增加,用户很可能会放弃访问该页面。
对于性能优化看法
对于性能优化,应该是先掌握一些基本的概念,然后如何进行性能分析,而且不同的项目采用的方式不同,项目的大小,也采用的方案不同,如果项目比较小,你采用了大型项目的配置,反倒最后适得其反。 而且不同的项目使用的库不一样,优化的手段也不一样,有时候不是你能够说套用某个方案,就能够解决问题的,它需要进行调试,分析出那些性能问题,然后在对它进行一个性能的优化。因为我目前也在做公司的项目上的性能优化,刚开始我也在网上找各种方案,我想大多数人跟我一样,更关注的是打包优化就行了。一开始我也是怎么想,但当你做有性能需求的时候,你又无可奈何,就像我公司的组件库,大家都在用,但是它没有做动态的引入,而且还是连锁反应的,最后打包很大,使得我在做优化得时候气笑了,人无语得时候,真的会无奈的笑一下。所以这时候,也要尽量想办法进行优化。如果你不想只关心打包优化,你应该先了解一些关于性能的名词的概念,然后掌握如何进行性能分析,对症下药,才是关键。
就比如大家都知道的SSR服务端渲染,大家都知道它的好处,更快的首次渲染(FCP),更好的 SEO(搜索引擎优化),更好的用户体验(尤其在首次加载时),但是它也有弊端,虽然ssr服务端渲染可以加速页面的首次渲染(FCP),但它并不能完全避免 TBT 问题,因为服务端渲染只是将 HTML 页面返回给浏览器,而页面中的 JavaScript 和其他资源(如样式和脚本)仍然需要在浏览器端执行。这样就会造成了动态交互性差,而且服务器负载较重,开发和部署复杂性增加,缓存和优化问题。采用的方案不同,影响也不同。
为什么会有这种感受呢
像性能优化,需要结合项目上的真实情况进行的,还有现有的资源进行配合,它是一个探索而且痛苦的过程,之所以会写这篇文章,而不是实践篇,因为我正在实践着,很痛苦,而且还没有达到一个好的预期,因为我用的库跟工具,都是工具公司的,而且不同部门开发的库,有时候你是无可奈何的,就比如我公司的组件库,它配置说是支持es,按需引入,但是我看源码是不支持的,而且,如果按需引入找不到各种文件,在这它css都打在同一个包里面,又不支持按需引入,在项目做css优化,可笑的是,本身是2M的文件,打包后重复使用,变成了,6M,大家都知道插件purgecss-webpack-plugin插件去除未使用的 CSS,。但是它把我css文件都移出了,关键还不知道移出那些,可以设置白名单,但具体那些有用那些没有我也不知道,因为不是我一个人开发的项目。而是迭代很多次的项目,代代更新,而且不同人的命名,使用习惯不一样。前期没有一个好的规范,那后期做这种性能优化,只能说尽力而为。更重要的是公司的第三方库都是罪魁祸首了,但你也无可奈何。
常见性能优化有哪些关键指标
1.FCP
FCP(First Contentful Paint)即首次内容绘制。它统计的是从进入页面到首次有 DOM 内容绘制所用的时间。这里的 DOM 内容指的是文本、图片、非空的 canvas
或者 SVG。
FCP 和我们常说的白屏问题相关,它记录了页面首次绘制内容的时间。
下图可以看到为什么导致FCP慢,以及是什么导致FCP慢甚至点击蓝色的链接跳转相关如何解决这块的问题,能帮助我们快速定位到什么原因导致白屏的,已经响应的解决方案,红色的代表影响比较大,橙色是中等。
可以看到下面三条橙色的就是我们老生常谈的首屏优化,不过和红色一样,我们可以看到具体是哪里需要优化:
- 缩减 JavaScript
- 启用文本压缩
- 减少未使用的 CSS
2.LCP
LCP(Largest Contentful Paint)即最大内容绘制。它统计的是从页面开始加载到视窗内最大内容绘制的所需时间,这里的内容指文本、图片、视频、非空的 canvas 或者 SVG 等。
注意:FCP关注的是页面上任何内容的首次呈现时间,而LCP关注的是最大的内容元素的呈现时间。
例如:
这个图片太大了,完全呈现给用户需要1710毫秒,最大的内容渲染时间有点长了,所以我们就可以考虑优化这个块,压缩这个图片之类的。
3.SI
SI(Speed Index)即速度指数。Lighthouse 会在页面加载过程中捕获视频,并通过 speedline 计算帧与帧之间视觉变化的进度,这个指标反映了网页内容填充的速度。页面解析渲染过程中,资源的加载和主线程执行的任务会影响到速度指数的结果。
4.TBT
TBT(Total Blocking Time)是指在页面加载过程中,用户输入或交互受到阻塞的总时间。它衡量了在加载过程中由于JavaScript执行和主线程忙碌而导致用户输入延迟的总时间。 TBT 是 Web 性能指标之一,用于评估页面加载过程中的交互性能。 这个一般是由js引起,如下图:
TBT 的延迟通常由 JavaScript 的执行和主线程忙碌引起。当页面加载过程中存在大量的 JavaScript 代码执行或者主线程被长时间占用时,会导致用户输入或交互受到阻塞,从而增加 TBT。因此,优化 JavaScript 的加载和执行,以及减少主线程的繁忙程度,可以有助于减少 TBT。 根据上面提示,我们可以优化JavaScript 资源加载
资源加载的优化通常有几个思路:
- 合理的加载顺序/策略(延迟加载/预先加载)
- 压缩优化资源的体积
- 代码分割 & 公共提取 & 按需加载
5.CLS
CLS(Cumulative Layout Shift)即累计布局位移进行评估。这个指标是通过比较单个元素在帧与帧之间的位置偏移来计算
看的出来,使用LightHouse后很快可以定位到需要优化哪里
无障碍设计
Accessibility 辅助功能 : 无障碍设计,也称为网站可达性。是指所创建的网站对所有用户都可用/可访问,不管用户的生理/身体能力如何、不管用户是以何种方式访问网站。
比如:
Background and foreground colors do not have a sufficient contrast ratio. 这个意思就是某处文字背景色和文字颜色对比度不够,对于视障用户可能不好区分,展开可以看到具体是哪块元素。
最佳做法
最佳做法 : 实践性检测,如网页安全性,如是否开启 HTTPS、网页存在的漏洞等
SEO
SEO:搜索引擎优化检测,如网页 title 是否符合搜索引擎的优化标准等
性能分析
在讨论性能分析前,应该要学会如何看待性能如何,也必须掌握一些性能分析工具,不然都可以看做是再瞎蒙,凭感觉,或者是说再背八股文。
1. Chrome Performance 工具
用途:用于全面分析页面性能,包括加载时间、帧率、JavaScript 执行时间等。
操作步骤:
- 打开 Chrome DevTools(F12)。
- 切换到 Performance 标签页。
- 点击 Record 开始录制,执行页面操作后停止。
- 分析生成的性能时间轴,包括:
- 加载时间:识别资源加载、网络请求的瓶颈。
- 脚本执行:查看 JavaScript 执行时间,定位是否有耗时操作。
- 帧率分析:检查是否有掉帧(FPS < 60)。
优化方向:
- 减少渲染阻塞:优化 CSS 和 JS 的加载顺序,减少重绘与重排。
- 提高代码执行效率:定位长时间运行的 JS 函数,进行拆分或优化。
- 缓解网络瓶颈:通过懒加载、代码拆分、CDN 等减少关键资源的加载时间。
2. 使用 Lighthouse
Lighthouse 是一个自动化的性能分析工具,帮助你检测网页的性能、可访问性、SEO 等方面的问题。
如何使用 Lighthouse:
- 打开 Lighthouse 面板:
- 在 Chrome DevTools 中,点击顶部的
Lighthouse
选项卡。
- 在 Chrome DevTools 中,点击顶部的
- 选择要分析的项目:
- 选择你要分析的类别:性能、可访问性、SEO 等。
- 可以选择模拟不同的网络速度(例如,3G、4G)和设备类型(移动端或桌面端)。
- 点击 “Generate Report”:
- 点击 Generate Report 按钮,Lighthouse 会自动执行一系列测试并生成报告。
- 查看报告:
- 报告会提供详细的评分,并给出改进建议。重点关注性能相关的分数,并参考报告中提出的优化建议(例如,减少 JavaScript 执行时间、优化图片加载等)。
3. React DevTools
用途:专门用于分析 React 应用的性能,尤其适合排查渲染性能问题。
操作步骤:
- 安装 React DevTools 插件(Chrome 或 Firefox)。
- 打开 DevTools,切换到 Profiler 标签。
- 开始录制后,执行页面操作,观察组件的渲染情况。
- 查看哪些组件频繁渲染。
- 分析组件渲染时间是否过长。
优化方向:
- 避免不必要的重渲染:使用
React.memo
、useMemo
、useCallback
等。 - 减少状态提升:状态应尽量局限在需要的组件内,减少状态传递引发的级联渲染。
- 分割渲染任务:利用代码拆分、虚拟化列表等技术优化渲染性能。
4. 打包分析
用途:分析打包文件大小和模块依赖,优化资源加载速度。
工具推荐
-
Webpack Bundle Analyzer
使用webpack-bundle-analyzer
插件生成可视化报告:npm install --save-dev webpack-bundle-analyzer
在
webpack.config.js
中添加:const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { plugins: [ new BundleAnalyzerPlugin(), ], };
-
Vite 打包分析
使用rollup-plugin-visualizer
查看 Vite 打包大小:npm install --save-dev rollup-plugin-visualizer
配置
vite.config.js
:import { defineConfig } from 'vite'; import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig({ plugins: [ visualizer({ filename: 'stats.html', }), ], });
优化方向:
- 减少包大小:
- 按需加载:例如,使用
lodash-es
替代完整的lodash
。 - 删除未使用的代码:确保打包工具支持 Tree Shaking。
- 按需加载:例如,使用
- 代码拆分:
- 使用动态导入:将路由或功能模块分块,减少初始加载。
- 预加载关键资源:优先加载首屏内容。
- 优化依赖:避免大而全的库,选择体积小、功能专一的替代方案。
性能优化不是追求绝对的“完美”,而是找到瓶颈,进行合理取舍,最终为用户提供更流畅的体验!
性能优化
八股文总结
HTML&CSS
- 减少
DOM
数量,减轻浏览器渲染计算负担。 - 使用异步和延迟加载
js
文件,避免js
文件阻塞页面渲染 - 压缩
HTML、CSS
代码体积,删除不要的代码,合并CSS
文件,减少HTTP
请求次数和请求大小。 - 减少
CSS
选择器的复杂程度,复杂度与阿高浏览器解析时间越长。 - 避免使用
CSS
表达式在javascript
代码中 - 使用
css
渲染合成层如transform
、opacity
、will-change
等,提高页面相应速度减少卡顿现象。 - 动画使用
CSS3
过渡,减少动画复杂度,还可以使用硬件加速。
js
- 减少
DOM
操作数量 - 避免使用
with
语句、eval
函数,避免引擎难以优化。 - 尽量使用原生方法,执行效率高。
- 将
js
文件放到文件页面底部,避免阻塞页面渲染 - 使用事件委托,减少事件绑定次数。
- 合理使用缓存,避免重复请求数据。
Vue
- 合理使用
watch
和computed
,数据变化就会执行,避免使用太多,减少不必要的开销 - 合理使用组件,提高代码可维护性的同事也会降低代码组件的耦合性
- 使用路由懒加载,在需要的时候才会进行加载,避免一次性加载太多路由,导致页面阻塞
- 使用
Vuex
缓存数据 - 合理使用
mixins
,抽离公共代码封装成模块,避免重复代码。 - 合理使用
v-if
、v-show
v-for
不要和v-if
一起使用,v-for
的优先级会比v-if
高v-for
中不要用index
做key
,要保证key
的唯一性- 使用异步组件,避免一次性加载太多组件
- 避免使用
v-html
,存在安全问风险和性能问题,可以使用v-text
- 使用
keep-alive
缓存组件,避免组件重复加载
Webpack优化
- 代码切割,使用
code splitting
将代码进行分割,避免将所有代码打包到一个文件,减少响应体积。 - 按需加载代码,在使用使用的时候加载代码。
- 压缩代码体积,可以减小代码体积
- 优化静态资源,使用字体图标、雪碧图、webp格式的图片、svg图标等
- 使用
Tree Shaking
删除未被引用的代码 - 开启
gzip
压缩 - 静态资源使用
CDN
加载,减少服务器压力
网络优化
- 使用
HTTP/2
- 减少、合并
HTTP
请求,通过合并CSS、JS
文件、精灵图等方式减少请求数量。 - 压缩文件, 开启
nginx
,Gzip
对静态资源压缩 - 使用
HTTP
缓存,如强缓存、协商缓存 - 使用
CDN
,将网站资源分布到各地服务器上,减少访问延迟 dns-prefetch
预解析
React性能优化
-
PureComponent、React.memo
-
shouldComponentUpdate
-
useMemo、useCallback 实现稳定的 Props 值
React 渲染性能优化的三个方向,其实也适用于其他软件开发领域,这三个方向分别是:
- 减少计算的量。 -> 对应到 React 中就是减少渲染的节点 或者 降低组件渲染的复杂度
- 利用缓存。-> 对应到 React 中就是如何避免重新渲染,利用函数式编程的 memo 方式来避免组件重新渲染
- 精确重新计算的范围。 对应到 React 中就是绑定组件和状态关系, 精确判断更新的’时机’和’范围’. 只重新渲染’脏’的组件,或者说降低渲染范围
具体查看这篇:
浅谈React性能优化的方向本文来源于公司内部的一次闪电分享,稍作润色分享出来。主要讨论 React 性能优化的主要方向 - 掘金
React性能测量和分析上一篇文章讲了 React 性能优化的一些方向和手段,这篇文章再补充说一下如何进行性能测量和分析 - 掘金
其它
- 长时间操作的优化:除了提到的骨架屏和加载动画,长时间的操作(如长表单提交、复杂计算等)可以通过优化异步操作、Web Worker、Service Worker 等技术来减轻主线程压力。
- Progressive Web App(PWA):PWA 的离线能力和即时加载机制,通过缓存策略来优化页面的加载速度和交互体验,尤其是在移动端的应用。
- 微交互的优化:微交互(如按钮点击时的反馈、输入框的提示等)对用户体验有很大影响。可以利用简单的动画和过渡效果提高用户的感知速度,减少等待焦
交互体验优化
有时候性能是有瓶颈的,你无法达到百分之百的效果,因为总要有取舍的过程,因为请求资源是要时间的,而且,各种插件的影响,你也很难突破性能的瓶颈,而且还跟用户的网咯跟电脑配置有关。这时候你就要考虑如何提升用户的体验,如何改善交互效果,好的交互效果,也能让用户没感到那么卡,或者那么慢。
性能优化、减少页面加载时间、提升用户体验,是前端领域的一个永恒话题。在前后端分离、异步渲染在页面中被普遍应用的背景下,大量页面在用户访问时不可避免的会出现一段短时间白屏。目前的解决方案一般为以下几种:
- 服务端同步渲染
- 增加页面 loading
- 增加页面首屏骨架屏
这是对于首屏来说的,那其它页面,一些简洁的交互动画效果也要进行考虑。在性能优化难以突破的瓶颈时,交互体验的优化同样重要。通过增加加载动画、首屏骨架屏等手段,提升用户的感知体验,减少等待时的焦虑。
最后
性能优化它是需要一种实践的探索。AI的出现,更能有够配合我们去探索,提升探索实践。对于AI的看法,我是把它当作工具的,为什么很多人说AI取代程序员呢,如果说AI取代程序员,或者某一个行业,应该生成的是那个行业的产物,比如说AI不应该直接生成产品嘛,干嘛还要生成代码,多此一举,AI再快速发展,但它还没有产生“智”,那它就很难替代人,它可以作为效率工具,快速为我们试验快速的探索。为什么很多都是粗略的介绍呢,因为我正在探索,等我实践好之后,再分享一篇实践篇,以及我再现有的条件下,如何尽可能的做过那些优化。因为文章的每个技术点真正去探索的时候,都是可以长篇大论。
总结
性能优化是提升用户体验的关键因素,不仅仅是技术的堆砌,更是根据项目的需求和实际情况,结合多种优化方法,进行合理的取舍和实践。通过持续的性能分析和调优,最终能为用户提供更加流畅和快速的应用体验。
参考:
-
https://pagespeed.web.dev/(网站性能测试)
-
前端性能优化之利用 Chrome Dev Tools 进行页面性能分析 - 知乎
-
浅谈React性能优化的方向本文来源于公司内部的一次闪电分享,稍作润色分享出来。主要讨论 React 性能优化的主要方向 - 掘金
-
React性能测量和分析上一篇文章讲了 React 性能优化的一些方向和手段,这篇文章再补充说一下如何进行性能测量和分析 - 掘金