资讯专栏INFORMATION COLUMN

记一次页面卡顿排查

Lin_YT / 2745人阅读

摘要:记一次页面卡顿排查前述前段时间上线的一个移动端的项目,由于开发时间仓促,一直被用户投诉页面卡顿。这显然要导致卡顿。总结这只是页面卡顿的一个点,当然还有很多,我们的页面卡顿就是由这样一个一个的点造成的。

记一次页面卡顿排查 前述

前段时间上线的一个移动端的项目,由于开发时间仓促,一直被用户投诉页面卡顿。现在终于有时间来好好排查一下,看到底是什么原因。业务代码都不是自己写的,这是颇为头疼的问题。到了自己手上也只能努力的填坑了,伐开心。

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来分析页面存在的性能问题。然后不要迷信开源框架,也是有缺陷的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86343.html

相关文章

  • 一次惊心动魄的前端性能优化之旅

    摘要:方案未引起重视,并没有做出相应处理。页面中元素的布局是相对的,因此一个元素的布局发生变化,会联动地引发其他元素的布局发生变化。这里可以使用的和来分析的性能。写在最后性能优化是一门做减法的艺术。 欢迎一起交流 欢迎关注我的个人公众号,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文从这里开始...

    Bryan 评论0 收藏0
  • 一次惊心动魄的前端性能优化之旅

    摘要:方案未引起重视,并没有做出相应处理。页面中元素的布局是相对的,因此一个元素的布局发生变化,会联动地引发其他元素的布局发生变化。这里可以使用的和来分析的性能。写在最后性能优化是一门做减法的艺术。 欢迎一起交流 欢迎关注我的个人公众号,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文从这里开始...

    leejan97 评论0 收藏0
  • 一次惊心动魄的前端性能优化之旅

    摘要:方案未引起重视,并没有做出相应处理。页面中元素的布局是相对的,因此一个元素的布局发生变化,会联动地引发其他元素的布局发生变化。这里可以使用的和来分析的性能。写在最后性能优化是一门做减法的艺术。 欢迎一起交流 欢迎关注我的个人公众号,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文从这里开始...

    Anshiii 评论0 收藏0
  • 一次MongoDB高负载的性能优化

    摘要:年月日本文是关于记录某次游戏服务端的性能优化此处涉及的技术包括引擎随着游戏导入人数逐渐增加单个集合的文档数已经超过经常有玩家反馈说卡特别是在服务器迁移后从核降到核卡顿更严重了遂开始排查问题确认服务器压力首先使用命令查看总体情况此时占用不高 Last-Modified: 2019年6月13日11:08:19 本文是关于记录某次游戏服务端的性能优化, 此处涉及的技术包括: MongoDB...

    huhud 评论0 收藏0

发表评论

0条评论

Lin_YT

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<