前端性能优化及节流和防抖

性能优化原则

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

优化方式

  • 让加载更快

    • 减少资源体积:压缩代码
    • 减少访问次数:合并代码,SSR服务器端渲染,缓存
    • 使用更快的网络:CDN(根据区域匹配服务器,更快链接网络)
  • 让渲染更快

    • CSS 放在 head,JS 放在body 末尾
    • 尽早开始执行JS,用 DOMContentLoaded 触发
    • 懒加载(图片懒加载,上划加载更多)
    • 对 DOM 查询进行缓存
    • 频繁 DOM 操作,合并到一起插入 DOM结构
    • 节流 throttle 和 防抖 debounce

示例

资源合并

缓存

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

 CDN

  • CDN是根据地域进行网络请求的
  • 静态服务一般都是用 CDN 来做的
  • CDN 也完全符合304缓存机制

 SSR

  • 服务器端渲染:将网页和数据一起加载,一起渲染
  • 非SSR(前后端分离):先加载网页,在加载数据,在渲染数据
  • 早先的JSP ASP PHP,现在的(借助npm)vue React SSR

节流 throttle

场景示例

  • 拖拽一个元素时,要随时拿到该元素被拖拽的位置
  • 直接用 drag 事件,则会频繁触发,很容易导致卡顿
  • 节流:无论拖拽速度多快,都会每隔100ms 触发一次
<body>
    <button id="btn1"></button>
    <div id="div1" draggable="true">可拖拽</div>
    <script src="./js/throttle.js"></script>
</body>
const div1 = document.getElementById('div1')
function throttle(fn, delay = 1000) {
    let timer = null
    return function(){
        if(timer) {
            return 
        }
        timer = setTimeout(()=> {
            // 这里用apply()方法,是因为fn()会传入参数,若不改变this指向,参数e就只会被传到function()里,而不是fn()  
            // 例如
            // div1.addEventListener('drag',function(event) {
            //     //event是被传送到return的functio()
            // })
            fn.apply(this, arguments)
            // 在这里置空而不是外面,因为drag事件在不停触发时,要保证每隔一个delay才返回结果,所以在这里执行完fn()之后,timer=null,就不会一直触发if(timer)
            timer = null;
        },delay)  
    }   
}

div1.addEventListener('drag',throttle(function(e) {
    console.log(e.offsetX,e.offsetY);
}))

防抖 debounce

  • 监听一个输入框,文字变化后就会触发 change 事件
  • 直接用 keyup 事件,则会频繁触发 change 事件
  • 防抖:用户输入结束或暂停时,才会触发 change 事件
<body>
    <input type="text" id="input1" >
    <script src="./js/debounce.js"></script>
</body>
function debounce(fn,delay = 500) {
    // timer 是闭包中的
    let timer = null

    return function() {
        if(timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(()=> {
            fn(this, arguments)
            timer = null
        },delay)
    }
}
const input1 = document.getElementById('input1')
input1.addEventListener('keyup',debounce(function() {
    console.log(input1.value);
}))

/**
 * 监听的是keyup事件,即按键松开后触发
 * 当上次 keyup 事件触发后都是时间小于delay,按键重新输入,此时timer就应该被清空,重新触发setTimeout(), setTimeout()执行完成,timer置空
 */ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值