性能优化相关总结
一、性能优化要从何入手
1. 让加载更快
2. 让渲染更快
下面看一下这两方面分别要怎么优化
二、加载方面的优化
想要页面加载更快,需要从资源体积、访问次数、网络入手
1、减少资源体积
-
- 压缩代码
2、减少访问次数
-
- 资源合并
- 多个js文件合并
- 多个css文件合并
- 多个小图标合并在一起生成一张图(也就是我们所说的雪碧图或者图片精灵)
- 服务端渲染(SSR):将网页和数据一起加载一起渲染
- 我们现在的前后端分离是非SSR,需要先加载网页,再加载数据,最后再渲染。早先的JSP、PHP就是SSR。现在的Vue、React也开始做服务端渲染(SSR)了
- 尽可能的使用缓存
- 静态资源加hash后缀,当资源不变并且路径不变的情况,则自动触发http缓存机制,服务器返回304
- 资源合并
3、使用更快的网络
-
- CDN
- 我们引用资源库时可以使用CDN
![]()
- 我们引用资源库时可以使用CDN
- CDN
三、渲染方面的优化
- css 放在head中,js放在body最下面
- 尽最早的执行js,用DOMContent触发
window.addEventListener('DOMContentLoaded',function(){ //DOM 渲染完成即可执行,此时图片和视频等资源可能还没有加载完成 }) - 图片懒加载
- 滚动加载图片的时候,可以采用图片懒加载。图片默认设置一个比较小的默认图,当图片露出屏幕了时再去设置设置图片的地址,伪代码如下:
<img id="img1" src="preview.png" data-realsrc='abc.png'> <script type="text/javascript"> let img1 = document.getElementById('img1') img1.src = img1.getAttribute('data-realsrc') </script>
- 滚动加载图片的时候,可以采用图片懒加载。图片默认设置一个比较小的默认图,当图片露出屏幕了时再去设置设置图片的地址,伪代码如下:
- 对DOM查询进行缓存
//不缓存 DOM 查询结果 for(let i = 0; i < document.getElementById('list').length;i++){ //每次循环都会计算length,频繁进行DOC 查询 } //缓存 DOM 查询结果 const pList = document.getElementById('list') const length = pList.length; for(let i = 0; i < length;i++){ //缓存length,只进行一次DOM 查询 }
- 频繁操作DOM,合并到一起插入DOM
const listNode = document.getElementById('list') // 创建一个文档片段,此时还没有查到DOM中 const frag = document.createDocumentFragment() for(let i=0;i< 10;i++){ const li = document.createElement('li') li.innerHTML = 'List item' + i frag.appendChild(li) } //都完成之后,再插入到DOM中 listNode.appendChild(frag) - 节流throttle和防抖debounce
- 防抖
- 什么是防抖:防抖,防止抖动。"你先抖动着,啥时候停了,再执行下一步"。是将多次执行变为最后一次执行
- 防抖 是 事件在触发后开始计时,n 秒后再执行该事件,在 n 秒内被重复触发,则重新计时
- 防抖关注“结果”
- 场景:
- 输入框搜索:用户输入框搜索时,不必每次输入都立即触发搜索操作,而是等待用户输入完毕一定时间后再执行搜索
- 窗口调整大:用户调整窗口大小时,频繁触发resize事件,只在调整结束后再执行相应的处理
- 按钮点击防重复:防止用户多次点击按钮而导致多次提交问题
- 实现:
<input id="search"> <script> //防抖简单实现 function debounce(fn,delay = 500){ //timer 是在闭包中 let timer = null return function(){ if(timer){ clearTimeout(timer) } timer = setTimeout(()=>{ fn.apply(this,arguments)// 透传 this 和参数 timer = null },delay) } } //用法: const input = document.getElementById('search') search.addEventListener('keyup',debounce(()=>{ console.log('发起搜索',search.value) },1000)) </script>
- 节流
- 定义:n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
- 节流关注“过程”
- 场景:
- 滚动事件:滚动页面,scroll事件会频繁触发(懒加载图片、滚动条位置计算等),所以需要定期执行。
- 窗口调整实时计算:用户需要窗口调整过程中立即看到反馈,采用节流可以限制操作频率并确保实时响应
- 游戏中帧的渲染循环:确定一个固定的时间间隔内更新游戏状态或渲染画面,避免过多渲染操作导致性能问题
- 实现:
<div id="drag" draggable="true">可拖拽</div> <script> //节流简单实现 function throttle(fn,delay){ //timer 在闭包里 let timer = null return function(){ if(!timer){ timer = setTimeout(()=>{ fn.apply(this,arguments) timer = null },delay) } } } // 使用: const drag = document.getElementById('drag') drag.addEventListener('drag',throttle((event)=>{ console.log(event.offsetX,event.offsetY) },1000)) </script>
- 定义:n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
- 防抖

浙公网安备 33010602011771号