前端性能优化

防抖(debounce)

1、场景

1.input输入框。只需用户最后一次输入完,再发送请求
2.手机号、邮箱验证输入检测
3.window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

2、介绍

什么是防抖(连续的事件,只需触发一次回调)

函数防抖实际上是分为 “当即执行版” 和 “非当即执行版” 的,根据字面意思就能够发现他们的差异,所谓非当即执行版就是 触发事件后函数不会当即执行,而是在 n 秒后执行,若是在 n 秒内又触发了事件,则会从新计算函数执行时间。 而 “当即执行版” 指的是第一次触发事件后函数会当即执行,接下来的触发时进行防抖处理vue

3、编码建议

1.lodash库

安装配置node

npm i --save lodash

而后项目代码中引入使用npm

import _ from 'lodash'
_.debounce(func, [wait=0], [options={}])

/**
*func (Function): 要防抖动的函数。
*[wait=0] (number): 须要延迟的毫秒数。
*[options={}] (Object): 选项对象。
*[options.leading=false] (boolean): 指定在延迟开始前调用。
*[options.maxWait] (number): 设置 func 容许被延迟的最大值。
*[options.trailing=true] (boolean): 指定在延迟结束后调用。
**/

lodash官方文档浏览器

4、实例

1.js实现
debounce(fn,wait,ctx,immediate){
    let timer
    return function(...params){
        if(timer) clearTimeout(timer)
        if(immediate && !timer){
            fn.apply(ctx,params)
            timer=true
        }
        else{
            timer=setTimeout(()=>{
                fn.apply(ctx,params)
                timer=null
            },wait)
        }
    }
}
2.vue组件封装
<script>
export default {
    name: 'debounce',
    abstract: true,
    props: ['events', 'time', 'immediate'],
    created() {
        this.eventKeys = this.events && this.events.split(',');
    },
    methods: {
        debounce(func, wait, ctx, immediate) {
            let timer;
            let rtn = (...params) => {
                if(timer) clearTimeout(timer);
                if (immediate && !timer) {
                    func.apply(ctx, params);
                    timer=true
                } else {
                    timer = setTimeout(() => {
                        func.apply(ctx, params);
                        timer=null
                    }, wait);
                }
            };
            return rtn;
        }
    },
    render() {
        const vnode = this.$slots.default[0];
        // 若是默认没有传 events,则对全部绑定事件加上防抖
        if (!this.eventKeys) {
            this.eventKeys = Object.keys(vnode.data.on);
        }

        this.eventKeys.forEach(key => {
            vnode.data.on[key] = this.debounce(
                vnode.data.on[key],
                this.time,
                vnode,
                this.immediate
            );
        });
        return vnode;
    }
};
</script>
<debounce>
   <span 
       @click="changeTable('hahah')" 
       @touchmove="changePosition" 
       time="500" event="click"     
       :immedimate="true"
   ></span>
</debounce>

节流(throttle)

相关文章
相关标签/搜索