之前写过一篇文章《js中scroll事件的优化》,缘由是在手机视图下,有卡顿现象。

但其实我之前有一个疑惑,在电脑上用控制台测试时,为啥同样的代码在电脑尺寸下和手机尺寸下cpu占比差距如此之大呢?手机占比是电脑尺寸占比的2倍。跟巧合的是正好在宽度为1000px后开始突变。

经查,1000px正是我通过css改变页面布局的标准,1000px以下,隐藏右侧导航栏,及就是在css中触发display: none;对比激活的两种状态,发现:

不要问我为啥CPU占用都超过100%了,Linux下Chrome的显示问题,不过也正因为这,我才对性能判断更加敏感的。

测试代码如下:

function a() {
function t() {
  a || (requestAnimationFrame(e), a = !0);
}
function e() {
  var t = $(".navbar-brand"), n = $(window).scrollTop(), e = $(".entry-title").text();
  0 != e.length && n > 320 ? t.text(e) : t.text("新觉小屋");

  if ( i >= 1e3 && 0 != $("#sidebar-2").length && $("#main").height() > 
  $("#widget-area").height()) {
    var o = $("#sidebar-2"), r = $("#sidebar-1");
    o.hasClass("fix") ? r.offset().top + r.height() > n + 45 && o.removeClass("fix") : 
    o.offset().top < n + 66 && o.addClass("fix");
  };
  a = !1;
}

var i = 1999, a = !1;
window.addEventListener("scroll", t , !1);
}

其实关键就是

$("#main").height() > $("#widget-area").height()

这个用法是jQuery的height函数,#widget-area元素正是我设置display: none;的元素id。当我删除这句话,一切正常。

然后我突然想到如果用原生js写会不会出现这样的问题呢?

测试代码如下:

if ( i >= 1e3 && 0 != $("#sidebar-2").length && document.getElementById("main").clientHeight > document.getElementById("widget-area").clientHeight) {
  var oo = document.getElementById("sidebar-2"), rr = document.getElementById("sidebar-1"),o = $("#sidebar-2"), r = $("#sidebar-1");
  o.hasClass("fix") ? rr.getBoundingClientRect().top + rr.clientHeight > n + 45 &&
  o.removeClass("fix") : oo.getBoundingClientRect().top < n + 66 && o.addClass("fix");
}

当我改变需要获取height值元素的display时,没有导致CPU暴增的现象。

至此,如果你有对获取会改变display css值的元素height的需要,建议使用原生的方式。

PS:
在元素不可见时(display:none)

document.getElementById("widget-area").clientHeight
0
$("#widget-area").height()
865.391

原生的clientHeight显然更智能一些。
如果可见:

$("#widget-area").height()
893.391
document.getElementById("widget-area").clientHeight
893

显然原生更加“节能”,直接就是整形量,而jQuery则很精确,看你取舍了...

更新于:2018-01-05