博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于性能优化的那点事——函数节流
阅读量:7055 次
发布时间:2019-06-28

本文共 2514 字,大约阅读时间需要 8 分钟。

函数节流

背景

javascript中的函数大多数情况下都是由用户主动调用触发的, 除非是函数本身的实现不合理, 否则一般不会遇到跟性能相关的问题,但在少数情况下, 函数的触发不是由用户直接控制的. 在这些场景下, 函数可能被非常频繁调用, 而造成大的性能问题.

场景

window.onresize事件

mousemove事件
scroll滚动事件
共同的特征:高频触发事件函数, 若事件函数里附带DOM相关操作, 会造成非常大的性能消耗.

原理

将即将被执行的函数使用setTimeout延迟一段时间执行, 如果该次延迟执行还没有完成, 则忽略接下来调用该函数的请求.

实现

示例1

underscore.js的函数节流定义: _.throttle(fn, wait, [options]);

_.throttle接收三个参数, 第一次执行默认立刻执行一次fn@params fn: 需要进行函数节流的函数;@params wait: 函数执行的时间间隔, 单位是毫秒.@params options: options有两个选项, 分别是:        {leading: false}: 第一次调用不执行fn        {trailing: false}: 禁止最后一次延迟的调用_.throttle = function(fn, wait, options) {    var context,        args,        result,        timeout = null,        previous = 0;    if(!options) {        options = {};    }    var later = function() {        previous = options.leading === false ? 0 : _.now();        timeout = null;        result = fn.apply(context, args);        if(!timeout) {            context = args = null;        }    };    return function() {        var now = _.now();        if(!previous && options.leading === false) {            previous = now;        }        var remaining = wait - (now - previous);        context = this;        args = arguments;        if(remaining <= 0 || remaining > wait) {            if(timeout) {                clearTimeout(timeout);                timeout = null;            }            previous = now;            result = fn.apply(context, args);            if(!timeout) {                context = args = null;            } else if(!timeout && options.trailing !== false) {                timeout = setTimeout(later, remaining);            }            return result;        }    };};// demo:$(window).scroll(_.throttle(function() {    //相关处理}, 500));

示例2

《javascript设计模式与开发实战》中对函数节流示例:

throttle函数接收两个参数@params fn: 需要被延迟执行的函数;@params interval: 延迟执行的时间;var throttle = function(fn, interval) {    var _self = fn,            // 保存需要被延迟执行的函数引用        timer,                // 计时器        firstTime = true;    // 是否第一次调用    return function() {        var args = arguments,            _this = this;        if(firstTime) {        // 如果是第一次调用, 不需要延迟执行            _self.apply(_this, args);            return firstTime = false;        }        if(timer) {            // 如果定时器还在, 说明前一次延迟执行还未完成            return false;        }        timer = setTimeout(function() {            clearTimeout(timer);            timer = null;            _self.apply(_this, args);        }, interval || 500);    };};// demo:window.onresize = throttle(function() {    console.log(1);}, 500);

转载地址:http://cglol.baihongyu.com/

你可能感兴趣的文章
oom killer
查看>>
10.Django ModelForm
查看>>
MXNET:卷积神经网络基础
查看>>
UIPageViewController 翻页、新手引导--UIScrollView:pagingEnabled
查看>>
[五]基础数据类型之Short详解
查看>>
ILOG Gantt 3.0 注册机
查看>>
自己实现几个基本函数
查看>>
谨防沦为DLL后门木马及其变种的肉鸡
查看>>
C#构造函数的重载
查看>>
遍历json 对象的属性并且动态添加属性
查看>>
json解析2
查看>>
比最差的API(ETW)更差的API(LTTng)是如何炼成的, 谈如何写一个好的接口
查看>>
Spring的IOC原理 通俗解释
查看>>
Spark下的FP-Growth和Apriori
查看>>
redash docker 运行
查看>>
Repeater嵌套使用
查看>>
Silverlight4.0教程之轻松操作剪切板
查看>>
GIF, JPEG和PNG
查看>>
线控的原理
查看>>
Android : Must Override a Superclass Method
查看>>