摘要:記一次頁面卡頓排查前述前段時間上線的一個移動端的項目,由于開發時間倉促,一直被用戶投訴頁面卡頓。這顯然要導致卡頓。總結這只是頁面卡頓的一個點,當然還有很多,我們的頁面卡頓就是由這樣一個一個的點造成的。
記一次頁面卡頓排查 前述
前段時間上線的一個移動端的項目,由于開發時間倉促,一直被用戶投訴頁面卡頓。現在終于有時間來好好排查一下,看到底是什么原因。業務代碼都不是自己寫的,這是頗為頭疼的問題。到了自己手上也只能努力的填坑了,伐開心。
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來分析頁面存在的性能問題。然后不要迷信開源框架,也是有缺陷的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86343.html
摘要:方案未引起重視,并沒有做出相應處理。頁面中元素的布局是相對的,因此一個元素的布局發生變化,會聯動地引發其他元素的布局發生變化。這里可以使用的和來分析的性能。寫在最后性能優化是一門做減法的藝術。 歡迎一起交流 歡迎關注我的個人公眾號,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文從這里開始...
摘要:方案未引起重視,并沒有做出相應處理。頁面中元素的布局是相對的,因此一個元素的布局發生變化,會聯動地引發其他元素的布局發生變化。這里可以使用的和來分析的性能。寫在最后性能優化是一門做減法的藝術。 歡迎一起交流 歡迎關注我的個人公眾號,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文從這里開始...
摘要:方案未引起重視,并沒有做出相應處理。頁面中元素的布局是相對的,因此一個元素的布局發生變化,會聯動地引發其他元素的布局發生變化。這里可以使用的和來分析的性能。寫在最后性能優化是一門做減法的藝術。 歡迎一起交流 歡迎關注我的個人公眾號,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文從這里開始...
摘要:年月日本文是關于記錄某次游戲服務端的性能優化此處涉及的技術包括引擎隨著游戲導入人數逐漸增加單個集合的文檔數已經超過經常有玩家反饋說卡特別是在服務器遷移后從核降到核卡頓更嚴重了遂開始排查問題確認服務器壓力首先使用命令查看總體情況此時占用不高 Last-Modified: 2019年6月13日11:08:19 本文是關于記錄某次游戲服務端的性能優化, 此處涉及的技術包括: MongoDB...
閱讀 1383·2023-04-25 16:45
閱讀 1923·2021-11-17 09:33
閱讀 2312·2021-09-27 14:04
閱讀 919·2019-08-30 15:44
閱讀 2638·2019-08-30 14:24
閱讀 3420·2019-08-30 13:59
閱讀 1695·2019-08-29 17:00
閱讀 894·2019-08-29 15:33