记一次页面卡顿排查

记一次页面卡顿排查

前述

前段时候上线的一个挪动端的项目,因为开辟时候急急,一向被用户投诉页面卡顿。如今终究有时候来好好排查一下,看究竟是什么原因。营业代码都不是本身写的,这是很是头疼的题目。到了本身手上也只能勤奋的填坑了,伐高兴。

chrome Timeline剖析

起首固然是祭出开辟神器–chrome,来看看页面的fps和js实行时候都是什么模样的。
本文不是引见Timeline的学问,请还不相识的同砚自行进修。传送门:https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/timeline-tool

《记一次页面卡顿排查》

果真fps是锯齿状的,顶上伴随着红条(可以存在机能题目的处所)。从图中可以发明,涌现fps较低的处所,多数伴随着过量的script实行耗时(黄色部份)。接着我们拔取一段fps较低的时候段,来看下详细有哪些event。

《记一次页面卡顿排查》

从图中可以看出,这个函数实行了118ms(固然页面卡顿另有别的处所引发,我就不逐一形貌出来了),而要确保页面不卡顿的时候是16.7ms。这明显要致使卡顿。这个函数内发作了许多事宜。我发明了一个很蹩脚的事,强迫reflow,这但是前端机能的大忌了。而这个回流占用了大部份的函数实行时候。这个reflow是发作在“renderCommlist”函数内的,然后我点进这个函数看做了些什么操纵。代码以下:

function renderCommlist(data, $dom) {
    var prex = getMaidianPre();
    totalCount = data.cnt - 0;
    if (totalCount != 0) {
        $("#palmrobtimes").show();
        indexComm = fillCommListData(data, prex, indexComm);
        var render = template.compile(document.getElementById("tmpl_pro_item").innerHTML);
        var html = render(data);
        renderCommlistAsyc(html, $dom);
        $("#toTop").show()
    } else {
        commListEmpty($dom);
        $("#toTop").hide()
    }
    dataLoading = false
}

依据实行的递次我可以判断这个reflow发作对应的是“ $(“#toTop”).show()”这句。这就让我惊讶了,一个zepto的show()要领居然会致使这么严峻的结果。我是长姿态了。而“#toTop”对应的DOM是如许的:

《记一次页面卡顿排查》

“toTop”是被一个fixed的标签包裹起来的。依据我的所学一个离开文档流的dom不应该能形成这么严峻的reflow啊。所以我们要来zepto的show究竟做了一些什么事情。

接着我们来看Call Tree。看看show内里挪用了哪些函数。

《记一次页面卡顿排查》

我发明,show内里挪用了n,t.fn.animate,t.fn.anim等函数。重要发时候都斲丧在了t.fn.anim上了。从函数名上看,这应该是动画相干的函数。我只是想要个显现元素,居然挪用了动画函数,不知道为何。从“Layout”背面的链接点进去可以定位到触发“Layout”的,代码以下:

// trigger page reflow so new elements can animate
this.size() && this.get(0).clientLeft

如许我就邃晓了。就是这一句致使强迫reflow。而我是要显现个元素,不要动画,这明显是没必要的。我翻看了下源代码,这里居然另有解释。“为了新的元素可以实行动画,触发页面回流”。本来作者是有意的,不过明显低估了reflow的威力。实在也不是一切的场景会形成这么严峻的回流耗时,只是我的场景比较“荣幸”,在挪用的这个函数的同时,顺序往页面里append了DOM,放大了这个reflow。

对zepto的show函数的剖析

至于show函数是怎样挪用到animate的我照样比较猎奇。在源码里查看了下。在zepto的中心模块“zepto.js”里实在show是如许的:

show: function(){
  return this.each(function(){
    this.style.display == "none" && (this.style.display = '')
    if (getComputedStyle(this, '').getPropertyValue("display") == "none")
      this.style.display = defaultDisplay(this.nodeName)
  })
},

并没有去挪用anim的。所以我就全局搜刮了下“$.fn.show”发明这个函数是在“fx_methods.js”模块里的。

$.fn.show = function(speed, callback) {
    origShow.call(this)
    if (speed === undefined) speed = 0
    else this.css('opacity', 0)
    return anim(this, speed, 1, '1,1', callback)
}

如许就邃晓了,这个函数把上面的show给掩盖掉了,添加了动画。而anim又挪用了“fx.js”里的“$.fn.animate”,如许就看到了上面的实行结果。不够我照样以为动画没必要。实在“fx.js”和“fx_methods.js“,实际上是可以不必打包到zepto里的,zepto的默许模块里也没这两个。

总结

这只是页面卡顿的一个点,固然另有许多,我们的页面卡顿就是由如许一个一个的点形成的。所以本身今后一样平常多多注重页面的机能。多用chrome dev来剖析页面存在的机能题目。然后不要迷信开源框架,也是有缺点的。

    原文作者:tinybear
    原文地址: https://segmentfault.com/a/1190000005681230
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞