溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

瀏覽內(nèi)核CPU不收斂問題定位和分析

發(fā)布時(shí)間:2020-07-11 07:46:50 來(lái)源:網(wǎng)絡(luò) 閱讀:1206 作者:百度MTC 欄目:軟件技術(shù)


  問題發(fā)現(xiàn)

     瀏覽內(nèi)核CPU 占用問題是影響用戶使用的關(guān)鍵因素,會(huì)引起操作卡頓、手機(jī)耗電以及應(yīng)用

崩潰等問題。CPU 占用由于受到頁(yè)面、機(jī)型、應(yīng)用框架的影響,較難進(jìn)行定位和優(yōu)化。在瀏覽內(nèi)核性能測(cè)試中發(fā)現(xiàn)CPU 占用高于之前版本,通過分析CPU 曲線,發(fā)現(xiàn)可能是部分場(chǎng)景CPU 沒有收斂導(dǎo)致的,因此對(duì)CPU 收斂做了專項(xiàng)測(cè)試。

老測(cè)試方案——內(nèi)核之前針對(duì)CPU 收斂的測(cè)試是通過加載用戶訪問Top 100 的頁(yè)面,應(yīng)用放后臺(tái)通過TOP 命令觀察CPU 收斂情況。

缺點(diǎn): 1.測(cè)試工作量非常大;2.Top頁(yè)面結(jié)構(gòu)復(fù)雜很難分析是頁(yè)面中的那個(gè)元素引起的不收斂現(xiàn)象;3.頁(yè)面經(jīng)常變化,收斂狀態(tài)難以穩(wěn)定復(fù)現(xiàn);

新測(cè)試方案——通過對(duì)頁(yè)面的整理分析和與RD 的溝通,引起CPU 不收斂的問題主要是頁(yè)面中的動(dòng)態(tài)元素,如CSS動(dòng)畫、 視頻播放、 Timer 定時(shí)器、 js 加載、 gif動(dòng)圖等,并由QA自己開發(fā)動(dòng)態(tài)元素的測(cè)試頁(yè)面進(jìn)行測(cè)試,在測(cè)試場(chǎng)景上選擇了應(yīng)用切后臺(tái)和頁(yè)面切換至不可見窗口兩種。

優(yōu)點(diǎn):1.測(cè)試工作量小,針對(duì)性強(qiáng);2.頁(yè)面固定、元素簡(jiǎn)單,易于復(fù)現(xiàn);3. 場(chǎng)景更加貼近用戶使用;

測(cè)試結(jié)果:

     使用新測(cè)試方案完成測(cè)試后,發(fā)現(xiàn)如下幾個(gè)問題:

問題一   頁(yè)面切換至不可見窗口場(chǎng)景:測(cè)試中心、CSS、H5GIF 等多個(gè)頁(yè)面不收斂;

問題二   APP 切后臺(tái)場(chǎng)景:測(cè)試中心頁(yè)面不收斂;

  初步分析

問題一通過對(duì)測(cè)試結(jié)果的分析,當(dāng)用戶創(chuàng)建空白頁(yè)面,使測(cè)試頁(yè)面切換至不可見窗口的場(chǎng)景時(shí),包含GIF 圖、CSS 動(dòng)態(tài)元素的頁(yè)面CPU 仍然有波動(dòng),而沒有收斂至0 這里可以猜測(cè)出可能當(dāng)頁(yè)面不可見時(shí),頁(yè)面的繪制沒有進(jìn)行pause,內(nèi)核判斷頁(yè)面動(dòng)態(tài)元素有更新,因此還在不斷的進(jìn)行繪制,導(dǎo)致CPU 不為0。

問題二測(cè)試中心頁(yè)面不收斂,該頁(yè)面是測(cè)試平臺(tái)的導(dǎo)航頁(yè)面,本身沒有動(dòng)態(tài)元素,但是仍有不收斂現(xiàn)象。QA通過繪制工具systrace分析頁(yè)面加載過程的數(shù)據(jù),發(fā)現(xiàn)切換切換后臺(tái)后,內(nèi)核的main(scheduler)/thread_proxy(cc)在工作,還在繪制內(nèi)容。推測(cè)有兩個(gè)可能:1.APP切后臺(tái),沒有pause當(dāng)前的webview2.測(cè)試中心首頁(yè)的某些邏輯導(dǎo)致內(nèi)核沒被pause。

  業(yè)務(wù)和代碼分析

內(nèi)核加載過程——瀏覽內(nèi)核加載頁(yè)面的網(wǎng)絡(luò)部分向網(wǎng)絡(luò)發(fā)起請(qǐng)求并把網(wǎng)頁(yè)資源下載給Loader,之后 HTML Parser HTML Script 解析成 DOM 樹,再結(jié)合 CSS 層疊樣式表生成對(duì)應(yīng)的 Render 樹。Render 樹上就包含了每個(gè)元素的各種屬性字體、顏色、屏幕上面的坐標(biāo)、長(zhǎng)、寬等。Render 樹進(jìn)一步生成 Graphics Context 交給平臺(tái)相關(guān)的圖形庫(kù)把頁(yè)面展示在屏幕上。大體過程是如下圖這樣,實(shí)際上內(nèi)核是邊加載邊繪制的。

瀏覽內(nèi)核CPU不收斂問題定位和分析              

內(nèi)核繪制過程——瀏覽內(nèi)核為了減少不必要的繪制,保證頁(yè)面的繪制速度和頁(yè)面滑動(dòng)的流暢度,對(duì)Render Tree 進(jìn)行了分層,可以更方便的進(jìn)行頁(yè)面的局部更新。有更新的layer 將更新數(shù)據(jù)經(jīng)過合成composite階段,將真正的需要繪制區(qū)域數(shù)據(jù)給GL 進(jìn)行draw,最終完成圖像的顯示。整個(gè)過程是多線程的,通過消息來(lái)驅(qū)動(dòng)這個(gè)流程。

 瀏覽內(nèi)核CPU不收斂問題定位和分析

     動(dòng)態(tài)元素由于更新頻率高,通常會(huì)劃分為單獨(dú)的layer,如果這個(gè)layer 的更新消息沒有暫停,就會(huì)導(dǎo)致這個(gè)消息驅(qū)動(dòng)layer 的合成,進(jìn)行更新區(qū)域的計(jì)算,調(diào)用drawGL 進(jìn)行圖像的draw。因此CPU 會(huì)一直被占用。

真相大白

問題一

     頁(yè)面動(dòng)態(tài)元素不收斂,通過將頁(yè)面中動(dòng)態(tài)元素刪除后,測(cè)試結(jié)果為收斂,由此可以證明確實(shí)是動(dòng)態(tài)元素導(dǎo)致。動(dòng)態(tài)元素有頻繁的更新消息,使得不斷對(duì)包含動(dòng)態(tài)元素的layer 進(jìn)行合成和繪制,導(dǎo)致CPU 不收斂。首先需要查看該webview 是否是否被pause,webview 被切換至不可見狀態(tài)時(shí),策略上應(yīng)該暫停一切頁(yè)面的處理,節(jié)約更多的CPU和內(nèi)存資源保證當(dāng)前活動(dòng)窗口的處理。

 //  webview onPause 的處理
public void onPause() {
        if (mIsPaused || mNativeAwContents == 0) return;
        mIsPaused = true;
        nativeSetIsPaused(mNativeAwContents, mIsPaused);
}

 內(nèi)核沒有對(duì)文檔解析、js 加載、動(dòng)圖進(jìn)行暫停。

解決方案:

// 網(wǎng)絡(luò)加載暫停
void ContentViewCoreImpl::SetIsPaused(JNIEnv* env,
     jobject obj,
     bool paused) {
  GetWebContents()->Send(new ViewMsg_SetIsPaused(
      GetWebContents()->GetRoutingID(), paused));
}
// 繪制暫停
void RenderViewImpl::OnSetIsPaused(bool paused) {
  if (!webview())
    return;
  webview()->setIsPaused(paused);
}
// 文檔解析暫停
void WebViewImpl::setIsPaused(bool paused) {
    Document* document = page()->mainFrame()->document();
    if (!document)
        return;
    if (paused)
        document->suspendScheduledTasks();
    else
        document->resumeScheduledTasks();
}

問題二

     測(cè)試中心頁(yè)面不能收斂,此頁(yè)面并沒有動(dòng)態(tài)元素,因此用上面的方法分析是不奏效的,需要找其他的方法。百度瀏覽內(nèi)核是基于Blink 35版本再次開發(fā)的版本,因此想要驗(yàn)證下原生內(nèi)核是否有問題,于是驗(yàn)證了Blink 35、36都是不收斂,blink 37 版本可以收斂,因此可以斷定是Blink 內(nèi)核自己的bug,通過對(duì)繪制過程相關(guān)代碼的查找,發(fā)現(xiàn)google 工程師對(duì)此問題的一個(gè)注釋。

if (RenderView* view = renderView()) {
        ASSERT(!view->needsLayout());
        view->compositor()->updateCompositingLayers();
 
        // FIXME: we should not have any dirty bits left at this point. Unfortunately, this is not yet the case because
        // the code in updateCompositingLayers sometimes creates new dirty bits when updating direct compositing reasons.
        // See crbug.com/354100.
        view->compositor()->scheduleAnimationIfNeeded();
}

     通過上面的注釋可以看出,在layer 有更新進(jìn)行合成過程中,會(huì)引入臟數(shù)據(jù)導(dǎo)致layer 一直更新,并進(jìn)行后面的數(shù)據(jù)處理和繪制,導(dǎo)致CPU 不收斂,通過增加打印Log 也可以證明,不收斂的頁(yè)面確實(shí)在不斷進(jìn)行該函數(shù)的調(diào)用。

      通過對(duì)Blink 37 修復(fù)的patch 進(jìn)行研究,內(nèi)核對(duì)判斷Layer 更新的狀態(tài)進(jìn)行了修改,調(diào)整了更新判斷的結(jié)構(gòu),刪除了scheduleAnimationIfNeeded 方法,通過其他狀態(tài)判斷是否需要更新layer,并進(jìn)行數(shù)據(jù)的合成進(jìn)行繪制,通過將37 patch 合入測(cè)試發(fā)現(xiàn)可以有效解決不收斂問題。

解決方案:

     增加了CompositingReasonFinder::requiresCompositingForPosition 方法判斷是否需要進(jìn)行合成。

臟數(shù)據(jù)的問題還是沒有根本解決,只是增加了判斷,不會(huì)出現(xiàn)之前的循環(huán)處理。

void RenderLayerCompositor::assertNoUnresolvedDirtyBits()
{
    ASSERT(!compositingLayersNeedRebuild());
    ASSERT(!m_needsUpdateCompositingRequirementsState);
    ASSERT(m_pendingUpdateType == CompositingUpdateNone);
    ASSERT(!m_rootShouldAlwaysCompositeDirty);
ASSERT(!m_needsToRecomputeCompositingRequirements);
}

總結(jié)

CPU 收斂在CPU 性能測(cè)試中是一個(gè)非常重要的項(xiàng)目,對(duì)于用戶體驗(yàn)的影響也是非常大。這個(gè)案例首先在CPU 收斂的測(cè)試方案上有很大的突破,通過較小的成本發(fā)現(xiàn)了不收斂的場(chǎng)景;其次,通過測(cè)試頁(yè)面和弱網(wǎng)環(huán)境穩(wěn)定復(fù)現(xiàn)bug,幫助RD定位問題,最后通過查閱blink 內(nèi)核的官方文檔、代碼記錄和bug 系統(tǒng),最終找到了解決方案, 提升了整體產(chǎn)品的體驗(yàn)。


百度MTC是業(yè)界領(lǐng)先的移動(dòng)應(yīng)用測(cè)試服務(wù)平臺(tái),為廣大開發(fā)者在移動(dòng)應(yīng)用測(cè)試中面臨的成本、技術(shù)和效率問題提供解決方案。同時(shí)分享行業(yè)領(lǐng)先的百度技術(shù),作者來(lái)自百度員工和業(yè)界領(lǐng)袖等。

>>如有問題,歡迎與我溝通

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI