前端性能優化

防抖(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)

相關文章
相關標籤/搜索