您的位置:首页 > Web前端

前端性能优化(防抖、节流)

2020-02-13 21:46 351 查看

1. 性能优化原则

  • 多使用内存、缓存或其他方法
  • 减少CPU计算量,减少网络加载耗时
  • (适用于所有编程的性能优化——空间换时间)

2. 从何入手

(1)让加载更快
  • 减少资源体积,压缩代码
  • 减少访问次数:合并代码,SSR服务器端渲染,缓存
  • 使用更快的网络:CDN
(2)让渲染更快
  • CSS放在head,JS放在body最下面
  • 尽早开始执行JS,用DOMContentLoaded触发
  • 懒加载(图片懒加载,上滑加载更多)
  • 对DOM查询进行缓存
  • 频繁DOM操作,合并到一起插入DOM结构
  • 节流throttle,防抖debounce(体验性优化,让渲染更加流畅)

3. 缓存

  • 静态资源加hash后缀,根据文件内容计算hash
  • 文件内容不变,则hash不变,则url不变
  • url和文件不变,则会自动触发http缓存机制,返回304

4. SSR(Server Side Render)

  • 服务器端渲染:将网页和数据一起加载,一起渲染
  • 非SSR(前后端分离):先加载网页,再加载数据,再渲染数据
  • 早先的JSP、ASP、PHP都是SSR,现在的Vue、React用node做SSR

5. 懒加载

<img id="img1" src="preview.png" data-realsrc="abc.png" />
<script type="text/javascript">
var img1 = document.getElementById('img1')
img1.src = img1.getAttribute('data-realsrc')
</script>

6. 防抖 debounce

例如:监听一个输入框,文字变化后触发onchange事件,如果直接用keyup事件,则会频繁触发onchange事件。
防抖:用户输入结束或暂停时,才会触发change事件

html代码:

<input id="input1" />

javascript代码:

const input1 = document.getElementById('input1')
let timer = null

input1.addEventListener('keyup', funtion(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
// 模拟触发change事件
console.log(input1.value)

// 清空定时器
timer = null
}, 500)
})

封装:

function debounce(fn, delay = 500){
// timer在闭包中
let timer = null

return function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}

input1.addEventListener('keyup', debounce(() => {
console.log(input1.value)
}), 600)

7. 防抖 throttle

例如:拖拽一个元素时,要随时拿到该元素被拖拽的位置,如果直接用drag事件,则会频繁地触发,很容易导致卡顿。
节流:无论拖拽速度多快,都会每隔100ms触发一次

html代码:

<div id="div1" draggable="true">可拖拽</div>
<style>
#div1{
border:1px solid #ccc;
width:200px;
height:200px;
}
</style>

javascript代码:

const div1 = document.getElemengById('div1')
let timer

div1.addEventListener('drag', function(e){
if(timer){
return
}
timer = setTimeout(() => {
console.log(e.offsetX, e.offsetY)
timer = null
}, 100)
})

封装:

function throttle(fn, delay = 100){
let timer = null

return function(){
if(timer){
return
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}

div1.addEventListener('drag', throttle((e) => {
console.log(e.offsetX, e.offsetY)
}), 200)
  • 点赞
  • 收藏
  • 分享
  • 文章举报
前端小兔子 发布了22 篇原创文章 · 获赞 0 · 访问量 431 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: