专栏首页九彩拼盘的叨叨叨耗时函数被短时间频繁调用时,防浏览器卡死的方法

耗时函数被短时间频繁调用时,防浏览器卡死的方法

耗时函数如果在短时间内被频繁调用,如果不做合适的处理,会导致浏览器卡死(无响应),严重影响用户体验。

那我们应该如何处理呢?对于不同的类型的耗时函数有不同的处理方式。我将耗时函数分为两类,一类是,函数被频繁触发时,只需要执行最近的那次;另一类是,函数被频繁触发时,每次都需要被执行。

对于第一类。一般是类似这样的场景:我们要做根据用户文字的输入,实时显示查询结果的功能。当用户频繁的修改输入内容,那边就会导致未执行的查询函数的堆积。我们只需要查询最近用户输入的,堆积的函数不需要被执行。

做法是,每次要执行查询方法时,将之前没执行的那个查询方法取消执行。取消执行的方式是用 setTimeoutclearTimeout 来做。具体实现如下

<input type="text" id="input">
<script src="../../asset/vendor/jquery-2.1.3.min.js"></script>
<script>
$(document).ready(function() {
    function throttle(fn, time) {
        time = time || 200;
        var runId = null;
        return function() {
            var args = arguments;
            clearTimeout(runId); // 把之前没执行的给去掉
            runId = setTimeout(function() {
                fn.apply(fn, args);
            }, time);
        }
    }

    var search = function  (val) {
        $.ajax({
            url: 'error'// 404的地址,为了让代码进fail方法
        }).fail(function () {
            console.log(val);
        });
    };

    search = throttle(search, 500);

    $('#input').keyup(function () {
        search($(this).val());
    });
});
</script>

如果使用 Underscore.js 或 lodash.js。可以使用其 throttle 方法。

其他使用场景还有:滚动条滚动的处理函数。

对于第二类,函数每次都要被执行。可能的场景是:要做活动的签到图片墙功能。在一个时间点,可能有一大堆人来签到,而显示每次签到时,会有一个动画,而显示的设备的性能比较差时,如果同时做很多个动画,会导致显示的卡顿。我们可以执行签到动画之间加一些时间间隔。

做法是,将要执行的动画放入一个队列,隔一段时间,执行一个。具体实现如下

    <script src="../../asset/vendor/jquery-2.1.3.min.js"></script>
    <script>
    $(document).ready(function() {
        function queueCall(fn, time) {
            time = time || 200;
            var argsArr = []; // 执行方法的参数队列
            setInterval(function  () {
                if(argsArr.length === 0){
                    return;
                }
                var args = argsArr.shift();
                fn.apply(fn, args);
            }, time);
            return function () {
                argsArr.push(arguments);
            };
        };

        var signIn = function  (name) {
            console.log('sign in. name: ' + name);
        };

        signIn = queueCall(signIn, 1000);

        ['joel', 'jack', 'tom', 'jerry', 'jim'].forEach(function (name) {
            signIn(name);
        });
    });
    </script>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 加些CSS,让网站变得面目全非,你会怎么做?

    Joel
  • 浏览器默认样式

    浏览器都拥有一套自己的默认样式。 浏览器之所以有默认样式表,是为了没有样式表的页面也能凑活着看。 不同浏览器;以及版本不同的浏览器的默认样式一般都是不同的。

    Joel
  • ES6 写法示例

    Joel
  • js中(function(){})()的写法用处

    后来查了下资料,js中(function(){…})()立即执行函数写法理解,终于了解了。

    帅的一麻皮
  • JavaScript立即调用的函数表达式

    主要参考知乎上这个问题:javascript 匿名函数有哪几种执行方式 长天之云的回答。

    meteoric
  • phpcms v9 常用函数

    常用函数 , 打开include/global.func.php,下面存放一些公共函数 view plaincopy to clipboardprint? fu...

    joshua317
  • 优雅异步编程方式

    对于并发处理的多个任务,如果任务与任务之间没有联系,那么这些任务是可以并行执行的,如果任务与任务之间有依赖,那么这些任务就需要串行执行了,因此对于并发的任务处理...

    张炳
  • es6之深入理解promise对象

    连小壮
  • 深入理解es6的promise

    我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?inv...

    连小壮
  • 性能优化三部曲之三——Node直出让你的网页秒开

    项目: 手Q群成员分布直出 原因: 为家校群业务直出做准备 群成员分布业务是小型业务,而且逻辑相当简单,方便做直出试验田 基本概念: 直出其实并不算是新概念。只...

    李成熙heyli

扫码关注云+社区

领取腾讯云代金券