【问题标题】:Does caching a jQuery object in this case give better results performance-wise?在这种情况下缓存 jQuery 对象是否会在性能方面提供更好的结果?
【发布时间】:2018-06-29 16:09:56
【问题描述】:

我偶然发现了朋友的这段代码,根据我对 JS,尤其是 jQuery 的知识和测试,这个缓存是没有必要的:

   jQuery('.loggedin.bookmark, .loggedin.bookmarked').on('click', function(e) {
        e.preventDefault();
        var $this = jQuery(this),
            id = $this.data('id');
        if($this.hasClass('bookmarked') ) {
            //remove bookmark
            jQuery.post(MyAjax.ajaxurl, {
                action : 'bookmark-remove',
                post_id : id
            },
            function() {
                //we sent the data, now we update the button bg color and tooltip
                $this.tooltip("destroy");
                $this.data('title', 'BOOKMARK');
                $this.removeClass('bookmarked');
                $this.addClass('bookmark');
            });
        }
        else {
            //add bookmark
            jQuery.post(MyAjax.ajaxurl, {
                action : 'bookmark-submit',
                post_id : id
            },
            function() {
                //we sent the data, now we update the button bg color and tooltip
                $this.tooltip("destroy");
                $this.data('title', 'BOOKMARKED');
                $this.removeClass('bookmark');
                $this.addClass('bookmarked');
            });
        }
    });

当您执行jQuery('.selector-here).on('click', function(e) { 时,this 上下文就是元素本身。因此,我之前运行测试的意见是没有必要用var $this = jQuery(this); 缓存它,因为它已经被函数的“参数”缓存了。

我的测试也显示性能没有提高,并且倾向于使用非 $this 方法更快地工作,显然,这仅适用于一行代码:

<html>
<head>
</head>
<body>

<div id="basic-thing">
    <p class="click-me"> Hey there!</p>
</div>

<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script type="text/javascript" src="scripts.js"></script>
</body>
</html>

第一次测试:

$(document).ready(function(){
    $('.click-me').on("click", function( e ) {
        e.preventDefault();
        console.log(performance.now());
        var context = $(this);
        console.log(context);
        console.log(performance.now());
        console.log("---------------");
    });
});

结果:

scripts.js:4 3268.7400000000002
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 3272.0600000000004
scripts.js:8 ---------------
scripts.js:4 3604.9350000000004
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 3605.7050000000004
scripts.js:8 ---------------
scripts.js:4 3772.32
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 3772.905
scripts.js:8 ---------------
scripts.js:4 3929.1400000000003
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 3929.715
scripts.js:8 ---------------
scripts.js:4 4089.645
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 4090.3450000000003
scripts.js:8 ---------------
scripts.js:4 4248.81
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 4249.450000000001
scripts.js:8 ---------------
scripts.js:4 4437.070000000001
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 4437.635
scripts.js:8 ---------------
scripts.js:4 4557.56
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 4558.215
scripts.js:8 ---------------
scripts.js:4 4730.045
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 4730.795
scripts.js:8 ---------------
scripts.js:4 4879.95
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 4880.530000000001
scripts.js:8 ---------------
scripts.js:4 5021.1
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 5023.305
scripts.js:8 ---------------
scripts.js:4 5175.945000000001
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 5176.505000000001
scripts.js:8 ---------------
scripts.js:4 5329.89
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 5330.455000000001
scripts.js:8 ---------------
scripts.js:4 5492.42
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 5492.9400000000005
scripts.js:8 ---------------
scripts.js:4 5638.72
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 5639.375
scripts.js:8 ---------------
scripts.js:4 5783.885
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 5784.525000000001
scripts.js:8 ---------------
scripts.js:4 5943.805
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 5944.455000000001
scripts.js:8 ---------------
scripts.js:4 6086.06
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 6086.665000000001
scripts.js:8 ---------------
scripts.js:4 6241.115000000001
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 6241.64
scripts.js:8 ---------------
scripts.js:4 6378.925
scripts.js:6 r.fn.init [p.click-me]
scripts.js:7 6379.5650000000005
scripts.js:8 ---------------

第二次测试:

$(document).ready(function(){
    $('.click-me').on("click", function( e ) {
        e.preventDefault();
        console.log(performance.now());
        var context = (this);
        console.log(context);
        console.log(performance.now());
        console.log("---------------");
    });
});

结果:

1814.5900000000001
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 1816.8200000000002
scripts.js:8 ---------------
scripts.js:4 1969.2
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 1969.5600000000002
scripts.js:8 ---------------
scripts.js:4 2271.8550000000005
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 2272.1050000000005
scripts.js:8 ---------------
scripts.js:4 2655.715
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 2655.9700000000003
scripts.js:8 ---------------
scripts.js:4 2826.9100000000003
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 2827.2350000000006
scripts.js:8 ---------------
scripts.js:4 3018.3250000000003
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 3018.5850000000005
scripts.js:8 ---------------
scripts.js:4 3496.3650000000002
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 3496.6250000000005
scripts.js:8 ---------------
scripts.js:4 3689.8100000000004
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 3690.09
scripts.js:8 ---------------
scripts.js:4 3853.8250000000007
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 3854.1300000000006
scripts.js:8 ---------------
scripts.js:4 4011.66
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 4011.9550000000004
scripts.js:8 ---------------
scripts.js:4 4175.7300000000005
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 4176.01
scripts.js:8 ---------------
scripts.js:4 4373.255
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 4373.52
scripts.js:8 ---------------
scripts.js:4 4546.89
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 4547.165000000001
scripts.js:8 ---------------
scripts.js:4 4711.555
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 4711.83
scripts.js:8 ---------------
scripts.js:4 4898.745000000001
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 4899.01
scripts.js:8 ---------------
scripts.js:4 5165.515
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 5165.81
scripts.js:8 ---------------
scripts.js:4 5523.6900000000005
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 5523.985000000001
scripts.js:8 ---------------
scripts.js:4 5895.43
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 5895.705000000001
scripts.js:8 ---------------
scripts.js:4 6094.78
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 6095.040000000001
scripts.js:8 ---------------
scripts.js:4 6502.720000000001
scripts.js:6 <p class=​"click-me">​ Hey there!​</p>​
scripts.js:7 6502.975
scripts.js:8 ---------------

我在选择器上测试了最流行的 jQuery 方法,它们都可以工作。

他是一位比我更有经验的开发人员,他说他这样做是为了优化。我错过了什么?

【问题讨论】:

  • "...this 上下文是选择器本身" 它是元素,而不是“选择器”。选择器是用于选择元素的字符串。
  • 每次提到$(this) 都是一个函数调用。对于大多数代码,隐藏$(this) 的值几乎没有实际的性能差异,但它是 jQuery 的常见编码模式。
  • 另一个考虑是在回调内部this 会有所不同。阅读How to access the correct this inside a callback
  • @Pointy 正是我的想法。差异是如此微不足道,似乎无关紧要!如果您认为值得,您是否有机会提出详细的答案?

标签: javascript jquery caching


【解决方案1】:

在几乎所有情况下,在事件处理程序中保存一些函数调用不会对现代(2018 年)JavaScript 环境(甚至手机)中的页面性能产生任何显着影响。也就是说,将$(this) 存储在一个变量中是一个由来已久的 jQuery 传统。

如果我要这样做,我个人会使用更有意义的变量名:

$("div.content-box").each(function() {
  var contentBox = this, $contentBox = $(contentBox);
  // ...
});

现在变量名意味着一些东西,在 jQuery 代码中,在 DOM 中进行大量“爬取”(通过.parent().closest().find())可以帮助避免混淆。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    • 2021-10-04
    • 2012-04-20
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    相关资源
    最近更新 更多