前端页面优化方法:
1、减少http请求
过多的http请求会影响页面的加载时间,合并css和javascript文件,可以有效地较少http请求次数。例如:将多个样式表合并为一个文件,将多个脚本合并为一个文件,这样浏览器只需一次请求就能获取所有的资源。通过合并css和JavaScript文件、使用css+sprites技术、以及利用图片懒加载等方法,可以有效减少页面加载时的http请求次数,从而提升页面加载速度。
2、使用CDN加速
将静态资源(如图片、css、JavaScript文件)部署到内容分发网络(CDN)上,可以利用CDN的分布式节点加速资源加载,减少用户访问时的延迟
3、压缩资源文件
对css、JavaScript和html文件进行压缩,移除不必要的空格、注释和换行符,可以显著减少文件大小,加快传输速度。常用的工具由Gzip、Brotli等
4、优化图片
使用适当的图片格式(如WebP)和压缩工具(如TinyPNG)来减小图片文件大小。在响应式网页设计中,建议针对不同终端屏幕匹配对应分辨率的图片资源,以防止高分辨率图片在移动端造成性能浪费。为优化网络请求效率,可将不超过2kb的为小型图片元素(如UI图标)通过Base64编码转换为文本格式直接写入css样式表,这种方式能有效合并http请求数量。但需注意该技术存在双重性影响;虽然减少了网络交互次数,却会显著怎加样式文件体积,因此仅推荐极小尺寸图片场景下使用。同事从搜索引擎优化角度考虑,需控制关键文档(html css)的字节大小,避免因文件体积膨胀导致爬虫抓取效率降低。
5、CSS+Sprites技术
对于小图标或背景图片,可以使用CSS+Sprites技术。通过多个小图合并成一张大图,并利用css的background-position属性来显示特定的部分,可以大大减少图片请求的数量,从而加快页面加载速度。CSS+Sprites不仅可以减少http请求,还能减少服务器带宽的使用,因为传输一个较大的图像文件比多次传输多个小文件更有效率。不过,在设计CSS+Sprites时要注意图像的布局和尺寸,避免造成不必要的空白空间浪费,同时也要考虑到不同分辨率屏幕下啊的显示效果,确保图像清晰度不受影响。
6、懒加载
懒加载是一种延迟加载图片的技术,即只有当图片进入视口时才开始加载。着可以显著减少初次加载页面时的数据传输量,提高首屏加载速度。html5以及元素支持懒加载, 只需在<img>标签中添加loading="lazy"属性即可。除了HTML5自带的支持外,还有更多第三方库可以实现更加复杂的懒加载逻辑,如Intersection+Observer+API可以让开发者精确控制何时触发图片加载,以及如何处理图片预加载等问题,对于大型项目,还可以结合服务端渲染(SSR)技术,提前计算出哪些图片将在用户滚动过程中进入视口,预先加载这些图片,进一步优化用户体验。
7、使用浏览器缓存
8、合理设置HTTP缓存头(如Cache-Control、Expires),使得浏览器能够缓存静态资源,减少重复请求,提升页面加载速度。
9、减少重绘和回流
通过优化css选择器、避免频繁操作DOM、使用transform和opacity等属性来减少页面重绘和回流,提升页面渲染性能。
10、使用Web+Workers
将负责的计算任务放到Web+Workers中执行,避免阻塞主线程,保持页面的响应性。
11、代码优化
避免使用全局变量、减少DOM操作、优化循环和条件判断等,可以提升JavaScrript代码的执行效率。
12、监控和分析
使用性能监控工具(如Lighthouse、WebPageTest)定期分析页面性能,找出瓶颈并进行针对性优化
动画卡顿优化
动画流畅性是用户体验的核心指标之一,直接影响用户对产品"流畅度"的感知。
1、 减少主线程阻塞
原理:浏览器主线程负责执行JavaScript、样式计算、布局(Layout)、绘制(Paint)等任务。若主线程被长任务(Long Tasks,>50ms)阻塞,会导致动画帧无法按时渲染,引发卡顿。
优化方法:
(1)拆封长任务将复杂逻辑拆分为多个微任务,每段执行时间控制在5ms以内
js任务分为宏任务(setTimeout)和微任务(queueMicrotask),微任务会在当前宏任务执行完毕后立即执行,且会在下一个宏任务开始之前全部执行完毕,因此微任务具有比宏任务更高的优先级
setTimeout(fn, 0) 将函数放入事件循环的任务队列中,等待当前调用栈清空后再执行。这可以让高优先级的UI渲染、DOM更新等任务先执行,避免界面卡顿或竞态条件
queueMicrotask :使用async/await或MutationObserver等产生的微任务,可以在当前宏任务结束后立即执行,不会阻塞主线程,适合处理异步操作和DOM更新
(2)Web Worker 异步处理将耗时计算(如物理引擎、图像处理)移至Worker线程
Worker 线程与主线程(负责 UI 渲染和事件处理)并行执行
1、创建 Worker:通过 new Worker(url) 创建 Worker 实例,其中 url 是 Worker 脚本的路径(需与主线程同源)。
2、通信机制:
主线程通过 worker.postMessage() 发送消息或数据给 Worker;
Worker 通过 self.onmessage 处理接收的消息,并通过 self.postMessage() 回复结果。
3、终止 Worker:可通过 worker.terminate() 或 self.close() 结束线程
2、GPU加速
原理:现代浏览器通过合成层(Compositing Layer)优化渲染:将特定元素提升为独立层,由GPU直接处理变换(Transform)和透明度(Opacity),跳过重排(Reflow)和重绘(Repaint)。
分层渲染的优势
- 减少重绘范围 :当合成层中的元素发生变化时,只需重新渲染该合成层,而不影响其他层,从而减少重绘和回流的范围。
- 提升动画性能 :对于涉及复杂动画的元素,提升为合成层后,GPU 可以高效处理动画中的大量计算,确保动画流畅。
优化方法:
(1)优先使用GPU友好属性
传统浏览器渲染依赖 CPU 处理 DOM 解析、样式计算和布局,但 CPU 的串行处理模式在处理大规模图形数据(如复杂动画、3D 变换、高清图像)时易成为性能瓶颈。GPU 加速通过硬件并行计算能力显著提升图形处理效率,解决了这一核心矛盾
流处理器核心并行计算 :GPU 拥有数千个小型核心,可同时处理大量像素数据 ,例如同时对元素的所有像素执行旋转变换,transform: rotateY(45deg),而 CPU 需逐像素串行处理。
高内存带宽优势 :GPU 的显存带宽远高于 CPU,能快速加载和传输图像数据,尤其适用于解码和渲染 4K 图像或高清视频。
合成层 是浏览器将特定元素分离为独立图层,并交由 GPU 单独处理的机制。其核心目的是减少重绘范围,通过分层渲染避免全页面刷新
GPU友好属性 :transform、opacity<1和mix-blend-mode、filter、position、transition、keyframes
(2)优化动画触发条件
对静态元素使用will-change:transform预提示浏览器。
使用 transform 或 opacity 的动画自动触发合成层
CSS 滤镜(如 blur、brightness)
透明度与混合模式
CSS 3D 变换
避免在滚动时频繁修改非GPU属性(如width)
注意事项:
过度使用合成层会增加内存占用(每层约4MB),需通过Layers面板监控层数量。
使用transform:translate3d()替代translate()强制开启GPU加速
3、 维持60FPS帧率
原理:浏览器默认以60HZ刷新率渲染(每帧16.67ms),若单帧渲染时间超过此阈值,会导致帧率下降。
优化方法:
(1)使用requestAnimationFrame替代setTimeout/setInterval,确保动画与浏览器刷新率同步
requestAnimationFrame用法与setTimeout差不多,它自动匹配设备帧率来展示动画,解决了定时器做动画时间间隔不稳定的问题 , 能够更好地与浏览器的刷新频率同步
cancelAnimationFrame()关闭动画。
(2)限制计算复杂度 避免在动画回调中执行DOM查询(如offsetWidth),触发强制同步布局(Forced Synchronous Layout)。对复杂计算使用缓存或预计算。
4、 压缩动画帧渲染时间
原理:每帧的渲染流程包括:JavaScript->样式计算->布局->绘制->合成。需减少各阶段耗时
优化方法:
(1)简化样式计算 减少CSS选择器复杂度(如避免div:nth-child(3) >a:hover)。减少布局抖动(Layout Thrashing)。
(2)使用CSS动画替代JS动画 。CSS动画由合成线程处理,不受主线程阻塞影响
5、 节流(Throttle)与防抖(Debounce)
原理:高频事件(如滚动、窗口调整)频繁触发回调会导致性能问题。
(1)节流:固定时间间隔内只执行一次(如每秒10次)。
(2)防抖:事件停止触发后延迟执行(如输入框停止输入30ms后搜索)
代码分割基础和原理
为什么需要代码分割?
在传统的单页应用开发中,如果不进行任何优化,打包工具会将所有JavaScript代码合并成一个巨大的bundle文件。这种方式存在以下问题:
1、初始加载时间过长:及时用户只需访问应用的一个小部分,也必须下载整个应用的代码
2、资源浪费:很多代码可能永远不会被执行
3、缓存效率低下:任何微笑的代码变更都会使整个bundle失效,需要重新下载
代码分隔正是为解决这些问题而生的技术,它允许我们:
将应用拆分成多个较小的chunks(代码块)
按需加载这些chunks,而不是一次性加载全部代码
实现更细粒度的缓存控制
显著改善应用的初始加载性能
代码分割的核心原理
代码分割的本质是将代码库分解成更小的、可独立请求的代码块,这些代码块可以在需要时动态加载。其工作原理可以概率为:
1、静态分析:打包工具在构建过程中分析模块依赖图
2、分隔点识别:根据配置或特定语法(如动态import)确定分割点
3、生成多个chunks:将代码库根据分割点拆分成多个独立的chunks
4、运行时加载:应用运行时,根据需要动态加载这些chunks
代码分隔主要由两种实现方式:
静态代码分隔:在构建时就确定分割点,通常通过配置实现
动态代码分隔:使用动态import()语法,在运行时确定分割点
图片加载优化方案:
预加载:
隐藏css元素触发图片加载,但不渲染到页面上
基于Promise的图片预加载
懒加载(延迟加载、按需加载):
当图片出现在浏览器的可视区域内,让图片显示出来
img标签设置loading="lazy"、IntersectionObserver、Scroll 事件监听
图片压缩:减少加载时间
降低图片体积/分辨率
图片缓存
由模糊变清晰