学习记录,部分内容版权归@妙码学院
1.优化内容包括那些
其实前端的优化,整体粗略概括下来,白话之:
- 打开速度怎么变快
- 再次打开速度怎么变快
- 操作怎么才顺滑
- 动画怎么保证流畅
2.性能优化
2.1首屏加载优化
在了解优化方法和策略之前,先了解一下首屏加载的量化指标有哪些:
指标
性能指标
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_CSS](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc2e74325876.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_CSS_02](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc4b54717085.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
- 白屏时间:从输入URL到FP的时间段,受网络链路(DNS/TCP)和主文档加载影响。
- 测量工具:可通过performance.getEntriesByName('first-paint')获取FP/FCP数据,LCP需结合浏览器API(如PerformanceObserver)或工具库(如web-vitals)
策略
减少首屏加载资源体积(优化策略)
一、加载阶段优化
目标:缩短网络请求时间,加速资源下载,直接影响 TTFB、FP、FCP
核心逻辑:减少首屏资源体积 → 减少传输时间 → 更快启动渲染
1. 网络传输优化
• CDN加速
- [x] 将静态资源(图片、CSS/JS、字体)部署到全球CDN节点,缩短资源传输距离,降低TTFB。
• 启用Gzip/Brotli压缩
- [x] 对文本类资源(HTML/CSS/JS)压缩,体积减少60%以上,降低传输耗时。
2. 资源体积控制
• 优化图片
- [x] 使用WebP格式(比JPEG体积小30%)、压缩图片(ImageOptim)、按需裁剪尺寸。
• 字体子集化
- [x] 通过Fontmin提取页面实际使用的字符,减少字体文件体积(如从2MB降至50KB)。
• 移除冗余第三方库
- [x] 分析依赖,替换臃肿库(如全量Lodash → 按需加载),减少JS体积。
3. 请求数量优化
- [x] 合并CSS/JS文件减少HTTP请求次数(如将10个小文件合并为1个),降低网络开销。
二、渲染阶段优化
目标:加速首屏内容渲染,保障视觉稳定性,直接影响 LCP、CLS
核心逻辑:优先渲染关键内容 → 快速达到可交互状态 → 避免布局偏移
1. 关键资源优先级
• 动态加载非关键CSS/JS
- [x] 通过
<link rel="preload">预加载首屏资源,延迟非关键脚本(如广告、分析SDK)。
• 服务端渲染与静态生成(SSG)
- [x] 使用Next.js/Nuxt.js在服务端生成完整HTML,减少客户端渲染耗时,直接输出可见内容。
2. 按需加载策略
• 懒加载非首屏资源
- [x] 图片/视频添加
loading="lazy"属性,仅当用户滚动到可视区域时加载。
3. 视觉稳定性保障
• 预定义尺寸占位
- [x] 为图片/视频设置
width/height属性,或使用CSS宽高比容器,避免布局抖动(CLS优化)。 - [x] 隐含优化项(图片中未明确,但属于CLS优化范畴)
三、跨阶段优化
目标:
贯穿加载和渲染阶段,提升整体性能
1. 浏览器缓存策略
- [x] 配置
Cache-Control和ETag,复用已缓存资源(如字体、JS库),减少重复请求。
2. 代码执行效率
• Tree Shaking与代码拆分
- [x] 移除未使用的代码(Webpack/Rollup),按路由拆分JS包,减少主线程阻塞时间(TBT优化)。
四、优化措施与性能指标关联表
优化措施 | 影响阶段 | 关联指标 | 具体收益案例 |
CDN加速 | 加载阶段 | TTFB、FCP | 图片加载时间从800ms降至300ms |
字体子集化 | 加载阶段 | FCP | 字体文件体积减少95% |
服务端渲染 | 渲染阶段 | LCP | LCP从3.2s优化至1.8s |
懒加载图片 | 渲染阶段 | LCP、CLS | CLS分数从0.25降至0.05 |
移除冗余库 | 加载阶段 | TTFB、FCP、TBT | JS体积减少40%,主线程阻塞减少50% |
预加载(优化策略)
一、预加载关键资源
原理
通过<link rel="preload">提前加载首屏必需资源(CSS、JS、字体),减少资源加载与渲染的阻塞时间,提升FCP(首次内容渲染)和LCP(最大内容渲染)指标。
代码示例
注意事项
as属性必须正确:告知浏览器资源类型(如style、script、font),否则可能重复下载。- 字体跨域问题:若字体托管在CDN,需添加
crossorigin属性。 - 兼容性:支持Chrome/Firefox/Edge,Safari部分支持。
优化效果验证
使用Chrome DevTools的 Network面板,观察资源加载优先级是否从Low提升至High。
二、嵌入关键CSS
原理
将首屏渲染所需CSS直接内联到HTML的<style>标签中,避免外链CSS文件请求阻塞渲染,直接优化FP(首次绘制)和FCP。
代码示例
最佳实践
- 提取关键CSS:使用工具(如Critical、Penthouse)自动提取首屏样式。
- 非关键CSS异步加载:通过
media="print"+onload切换媒体类型,避免阻塞。
优化效果验证
Lighthouse的 CSS Delivery Audit 会提示未内联的关键CSS文件。
三、异步加载JavaScript
原理
通过async或defer属性控制脚本加载与执行时机,减少JS阻塞主线程,优化LCP和TTI(可交互时间)。
代码示例
对比与选择
属性 | 执行时机 | 适用场景 |
| 下载完成后立即执行(无序) | 独立脚本(如统计代码) |
| DOM解析完成后顺序执行 | 依赖DOM或需要顺序执行的脚本 |
优化效果验证
Chrome DevTools的 Performance面板 查看主线程阻塞时间(Total Blocking Time)。
四、预加载字体与关键图片
原理
预加载首屏字体和图片,避免FOIT(字体未加载时的文本隐藏)和布局抖动,优化CLS(累积布局偏移)。
代码示例
注意事项
- 响应式图片优化:结合
imagesrcset适配不同分辨率。 - 字体加载兜底:使用
font-display: swap显示备用字体,避免FOIT。
优化效果验证
Web Vitals监控工具查看CLS分数变化,目标小于0.1。
五、HTTP/2 Server Push
原理
服务器在响应HTML请求时,主动推送关键资源(CSS、JS),减少往返请求次数,优化TTFB(首字节时间)和FCP。
配置示例(Nginx)
最佳实践
- 避免过度推送:仅推送首屏必需资源,防止带宽浪费。
- 缓存策略:推送资源需设置有效缓存头,避免重复传输。
优化效果验证
Chrome DevTools的 Network面板 检查资源是否通过h2协议推送(Size列显示Push)。
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_预加载_04](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc5ffc290742.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
预渲染(优化策略)
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_预加载_05](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc7d62965346.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
2.2 动画卡顿优化(最熟悉)
从浏览器底层原理简述
动画卡顿优化深度解析
动画流畅性是用户体验的核心指标之一,直接影响用户对产品“流畅度”的感知。本文基于图片中的优化措施,从原理、实践到工具验证进行全面拆解。
1. 减少主线程阻塞
原理
浏览器主线程负责执行 JavaScript、样式计算、布局(Layout)、绘制(Paint)等任务。若主线程被长任务(Long Tasks,>50ms)阻塞,会导致动画帧无法按时渲染,引发卡顿。
优化方法
• 拆分长任务
将复杂逻辑拆分为多个微任务(setTimeout或queueMicrotask),每段执行时间控制在5ms以内。
• Web Worker 异步处理
将耗时计算(如物理引擎、图像处理)移至 Worker 线程:
验证工具
• Chrome DevTools - Performance 面板:分析任务耗时和长任务分布。
• Long Tasks API:通过PerformanceObserver监听长任务。
2. GPU 加速
原理
现代浏览器通过合成层(Compositing Layer)优化渲染:将特定元素提升为独立层,由 GPU 直接处理变换(Transform)和透明度(Opacity),跳过重排(Reflow)和重绘(Repaint)。
优化方法
• 优先使用 GPU 友好属性
• 优化动画触发条件
• 对静态元素使用will-change: transform预提示浏览器。
• 避免在滚动时频繁修改非 GPU 属性(如width)。
注意事项
• 过度使用合成层会增加内存占用(每层约 4MB),需通过 Layers 面板监控层数量。
• 使用transform: translate3d()替代translate()强制开启 GPU 加速。
3. 维持 60 FPS 帧率
原理
浏览器默认以 60Hz 刷新率渲染(每帧 16.67ms),若单帧渲染时间超过此阈值,会导致帧率下降。
优化方法
• 使用 requestAnimationFrame
替代setTimeout/setInterval,确保动画与浏览器刷新率同步:
• 限制计算复杂度
• 避免在动画回调中执行 DOM 查询(如offsetWidth),触发强制同步布局(Forced Synchronous Layout)。
• 对复杂计算使用缓存或预计算。
验证工具
• Chrome DevTools - FPS Meter:实时监控帧率波动。
• console.time/console.timeEnd:测量单帧耗时。
4. 压缩动画帧渲染时间
原理
每帧的渲染流程包括:JavaScript → 样式计算 → 布局 → 绘制 → 合成。需减少各阶段耗时。
优化方法
• 简化样式计算
减少 CSS 选择器复杂度(如避免div:nth-child(3) > a:hover)。
• 减少布局抖动(Layout Thrashing)
• 使用 CSS 动画替代 JS 动画
CSS 动画由合成线程处理,不受主线程阻塞影响:
5. 节流(Throttle)与防抖(Debounce)
原理
高频事件(如滚动、窗口调整)频繁触发回调会导致性能问题。
• 节流:固定时间间隔内只执行一次(如每秒 10 次)。
• 防抖:事件停止触发后延迟执行(如输入框停止输入 300ms 后搜索)。
代码示例
总结与工具链
优化方向 | 关键工具 | 验证指标 |
主线程任务拆分 | Chrome Performance 面板 | Long Tasks < 50ms |
GPU 加速 | Layers 面板、CSS Triggers 网站 | 合成层数量 < 30 |
帧率稳定性 | FPS Meter、 | 60 FPS ±5% |
高频事件控制 |
| 回调执行频率 ≤ 屏幕刷新率 |
通过综合应用上述策略,可显著提升动画流畅性。建议结合 Web Vitals 和 Lighthouse 持续监控性能表现。
2.3 应用状态管理优化
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_CSS_06](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc4e24c13944.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
2.4 应用视图层更新优化
React 视图更新优化详解
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_CSS_07](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc6175098635.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
1. 使用 React.memo 防止不必要的重新渲染
原理React.memo 是一个高阶组件(HOC),用于包裹函数组件,通过浅层对比组件的 props 变化,仅在 props 发生变更时触发重新渲染。避免父组件状态更新导致子组件无意义的重绘。
适用场景
• 子组件依赖父组件传递的 props,且子组件渲染成本较高(如复杂计算或 DOM 操作)。
• 当父组件频繁更新但子组件的 props 未变化时。
代码示例
注意事项
• 若 props 包含对象或函数,需确保它们的引用稳定(结合 useMemo/useCallback)。
• 深比较场景需自定义对比函数:
2. 使用 useMemo 和 useCallback 缓存结果
原理
• useMemo:缓存复杂计算结果,仅在依赖项变化时重新计算。
• useCallback:缓存函数实例,避免因函数引用变化触发子组件重渲染。
适用场景
• 计算密集型操作(如数据转换、过滤)。
• 需要稳定函数引用的场景(如事件处理函数传递给子组件)。
代码示例
最佳实践
• 避免滥用:仅在计算成本高或引用稳定性关键时使用。
• 依赖项需明确,避免遗漏导致缓存失效。
3. 拆分组件
原理
将大型组件拆分为更小的独立组件,利用 React 的局部更新机制,仅重新渲染变更部分的子树。
适用场景
• 页面中存在独立功能区块(如导航栏、侧边栏、内容区)。
• 动态数据和静态数据混合的场景。
示例
优化效果
• 父组件状态变化时,未受影响的子组件不重新渲染。
• 结合 React.memo 效果更佳。
4. 虚拟滚动(Virtualized List)
原理
仅渲染可视区域内的列表项,动态加载和卸载元素,减少 DOM 节点数量和渲染压力。
适用场景
• 长列表(如 1000+ 项)的渲染性能优化。
• 移动端或低性能设备。
实现库
• react-virtualized:经典方案,支持多种布局。
• react-window:轻量级替代,更小的包体积。
代码示例(react-window)
核心参数
• itemCount:总项数
• itemSize:每项高度(固定或动态)
• overscanCount:预渲染项数(减少滚动白屏)
5. 批处理更新(Batching Updates)
原理
将多个状态更新合并为一次渲染,减少重复的渲染周期。React 18+ 默认在异步回调(如 Promise、setTimeout)中启用自动批处理。
适用场景
• 多个连续状态变更(如表单字段更新、批量数据加载)。
代码示例
优化效果
• 减少不必要的渲染次数,提升整体性能。
Vue 视图更新优化详解
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_加载_08](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc562a241777.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
1. 避免多余的响应式数据
原理
Vue 的响应式系统(reactive/ref)会追踪数据变化并触发更新。非响应式数据(如静态配置)若错误包裹为响应式,会增加内存和计算开销。
适用场景
• 静态配置、常量或无需追踪变化的临时变量。
代码示例
最佳实践
• 使用 Object.freeze() 冻结静态对象,避免误修改。
• 仅对需要动态更新的数据使用 ref 或 reactive。
2. 使用 v-once 和 v-memo
原理
• v-once:渲染元素一次,后续跳过更新。
• v-memo:根据依赖项缓存模板片段,仅当依赖变化时重新渲染。
适用场景
• v-once:静态内容(如页脚版权信息)。
• v-memo:高频更新但部分依赖稳定的组件。
代码示例
注意事项
• v-memo 需与 v-for 结合使用,依赖项需包含唯一标识(如 id)。
3. 拆分组件与 keep-alive 缓存
原理
• 拆分组件:将大型组件拆分为子组件,利用 Vue 的局部更新机制。
• keep-alive:缓存非活跃组件实例,避免重复渲染(如 Tab 切换)。
代码示例
优化效果
• 减少父组件更新对子组件的影响。
• keep-alive 避免重复执行生命周期钩子(如 mounted)。
4. 避免 watch 的过度使用
原理watch 监听数据变化并触发回调,过度使用会增加计算开销。
优化策略
• 精确监听必要依赖,避免监听整个对象。
• 使用 watchEffect 自动追踪依赖,简化代码。
代码示例
注意事项
• 避免在 watch 中执行高耗时操作。
• 使用 { immediate: true } 时需注意初始触发逻辑。
5. 虚拟滚动优化长列表
原理
与 React 类似,仅渲染可视区域内容,减少 DOM 节点数量。
实现库
• vue-virtual-scroller:Vue 生态主流方案。
• vue3-virtual-list:轻量级替代。
代码示例(vue-virtual-scroller)
核心参数
• items:数据源
• item-size:每项高度
• page-mode:启用滚动容器优化
总结
React 优化核心:利用
memo和缓存 Hook 减少渲染,拆分组件隔离变更,虚拟滚动解决长列表性能问题。Vue优化核心:精准控制响应式数据,通过指令缓存模板,合理使用组件缓存和虚拟滚动。
事件和渲染细节优化
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_CSS_09](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc31a0b79669.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
前端事件与渲染优化详解
从高频事件处理、DOM操作优化到资源加载策略,系统解析性能优化方法:
1. 节流(Throttle)与防抖(Debounce)
核心问题:高频事件(如滚动、输入)频繁触发回调,导致主线程阻塞、页面卡顿。
防抖(Debounce)
• 定义:事件停止触发后延迟执行回调(如输入框停止输入 300ms 后搜索)。
• 代码修正与注释:
节流(Throttle)
• 定义:固定时间间隔内只执行一次回调(如滚动事件每 100ms 触发一次)。
• 代码示例:
适用场景对比
策略 | 适用场景 | 典型案例 |
防抖 | 输入验证、搜索联想 | 输入框停止输入后触发搜索 |
节流 | 滚动加载、窗口调整 | 无限滚动列表的分批加载 |
2. 事件绑定优化
Vue 中的事件绑定
• .native 修饰符:用于监听组件根元素的原生 DOM 事件。
• 注意:Vue 3 已弃用 .native,改为 emits 显式声明事件。
React 中的事件绑定
• 避免过多回调传递:
• 问题:在深层子组件中传递回调函数,易导致不必要的重渲染。
• 优化:使用 Context API 或状态管理库(如 Redux)共享回调。
3. 避免不必要的 DOM 操作
问题根源
• DOM 操作成本高:浏览器重排(Reflow)和重绘(Repaint)消耗大量性能。
• 典型案例:循环中直接操作 DOM,导致多次渲染。
优化方法
- 批量更新:使用文档片段(DocumentFragment)合并多次操作。
- 虚拟 DOM 优势:React/Vue 通过 Diff 算法最小化真实 DOM 操作。
4. 异步加载与懒加载
资源懒加载
• 图片懒加载:仅加载可视区域内的图片。
路由组件懒加载
• React:使用 React.lazy + Suspense。
• Vue:动态导入组件。
5. 请求合并
网络请求优化
• 防抖处理:高频触发的请求合并为一次(如搜索联想)。
• 批量接口设计:后端提供批量处理接口,减少请求次数。
总结与工具推荐
优化方向 | 推荐工具/库 | 验证指标 |
防抖/节流 | Lodash 的 | 主线程阻塞时间(Performance 面板) |
懒加载 |
| LCP、FCP |
请求合并 | Axios 拦截器、GraphQL 批量查询 | 网络请求数量(Network 面板) |
通过综合应用上述策略,可显著提升页面响应速度与用户体验。建议结合 Lighthouse 和 Web Vitals 持续监控优化效果。
![在这里插入图片描述 [超详细,推荐!!!]前端性能优化策略详解_加载_03](https://s2.51cto.com/images/blog/202505/12210356_6821f1bc3213a55796.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184/format,webp)
3169

被折叠的 条评论
为什么被折叠?



