欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

【性能優(yōu)化實戰(zhàn)】百度小程序FMP優(yōu)化實錄 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關(guān) >

【性能優(yōu)化實戰(zhàn)】百度小程序FMP優(yōu)化實錄

發(fā)表時間:2021-1-6

發(fā)布人:葵宇科技

瀏覽次數(shù):102

背景

小程序從首次發(fā)布至今,經(jīng)過了幾十個版本的迭代。隨著業(yè)務發(fā)展,頁面功能內(nèi)容的不斷增多,相關(guān)性能數(shù)據(jù)不斷變差,核心性能數(shù)據(jù) FMP 長期處在 2000ms 以上。

在該項目之前,我們團隊也對小程序做了一定的性能調(diào)優(yōu)工作,內(nèi)容包括:

  1. 包體積優(yōu)化,去除了不少引用在項目中的圖片素材文件,將包體積優(yōu)化至 500kb 以下;
  2. 聯(lián)合后端對耗時較高的業(yè)務接口做優(yōu)化,單個接口返回速度需要控制在 100ms 左右;
  3. 優(yōu)化了部分業(yè)務邏輯,小程序啟動時減少了一些不必要的操作邏輯;
  4. 使用了小程序框架提供的最新生命周期 onInit ,可提前 100ms 左右發(fā)起業(yè)務網(wǎng)絡請求;
  5. 使用 prelink 預連接網(wǎng)絡,提升數(shù)據(jù)接口的請求效率。

經(jīng)過上述手段之后,F(xiàn)MP 降到了 1900ms 左右,后續(xù)再也無法產(chǎn)生優(yōu)化效果。

以上優(yōu)化手段,基本排除了網(wǎng)絡連接,包體積優(yōu)化不到位引起的性能不佳。那么我們就只有一個問題需要仔細排查 —— 內(nèi)容的渲染效率。

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

目前從小程序的最大入口頁面為問答頁,整體 pv 占比超過 6 成,那么我們優(yōu)先優(yōu)化這個頁面,便可以帶來性能收益的最大化。

通讀問答頁代碼,按顯示順序從上到下,整個頁面的功能點依次為:

  1. 直播信息橫條
  2. 問題區(qū)
  3. 回答區(qū)
  4. 廣告組件區(qū)
  5. 為你推薦 feedlist

需要展現(xiàn)的內(nèi)容類別很多,內(nèi)容信息量較為龐大。部分內(nèi)容需要單獨接口獲取,外加上引入的廣告組件,展現(xiàn)效率完全無法優(yōu)化。

因為以上業(yè)務內(nèi)容的展現(xiàn)需要,在加載時,使用 setData 觸發(fā)內(nèi)容渲染,會造成較大問題,比如:

  1. 加載期間調(diào)用 setData 的頻次過多,onLoad 時會 set 、onShow 時會 set ,不同階段發(fā)起的異步數(shù)據(jù)加載后也會 set 。當前線程內(nèi)同時的多次 setData ,極易造成小程序渲染線程擁塞,影響內(nèi)容渲染效率。
  2. 單次 setData 數(shù)據(jù)量過多,接口數(shù)據(jù)返回后,所有頁面內(nèi)需要的數(shù)據(jù)都一次性被提交到渲染線程中渲染,導致線程等待時間長,影響了有效內(nèi)容的最終展現(xiàn)。雖然減少 setData 調(diào)用次數(shù)是官方提倡的,但是單次提交過多數(shù)據(jù)渲染,也并不是最優(yōu)的策略。

以上兩條 setData 的使用問題,在配置較好的手機設備上,并不會體現(xiàn)出問題,但是對于中低配置的手機設備,因為操作擁塞或大量數(shù)據(jù)渲染操作帶來的渲染延遲,造成的用戶體驗損失還是很大的。

優(yōu)化前的問答頁數(shù)據(jù)渲染示意圖

優(yōu)化之前,頁面加載完數(shù)據(jù)之后的首次渲染,會一次提交問題區(qū)、回答區(qū)、廣告組件區(qū)三個部分的渲染任務,由于這三個區(qū)域涉及的內(nèi)容量比較大,基本都會超過一屏,甚至兩屏以上,另外各個區(qū)域也都包含一些圖文內(nèi)容,加上本身耗時較高的廣告組件。整體頁面內(nèi)容渲染速度很差。并且,因為存在直播信息橫條等單獨異步請求加載的數(shù)據(jù)內(nèi)容渲染,也容易造成 setData 操作在小程序渲染線程中擁塞現(xiàn)象的發(fā)生。

所以,從小程序 FMP 的統(tǒng)計規(guī)則來看,目前的數(shù)據(jù)渲染邏輯,顯然并不是最優(yōu)的。

既然 FMP 主要統(tǒng)計的是用戶第一眼可以看到的首屏位置內(nèi)容,那么我們是不是可以換個思路來完成我們的內(nèi)容渲染工作。

在確保數(shù)據(jù)接口性能已經(jīng)符合常規(guī)標準的情況下,我們可以使用更聰明的渲染策略。

優(yōu)化方案

為了解決上述問題,我們構(gòu)思了一套分屏式內(nèi)容渲染策略,意在讓用戶能最快速度的先看到一部分關(guān)鍵內(nèi)容,再分階段渲染剩下需要被渲染的數(shù)據(jù),而那些不需要被自動渲染的數(shù)據(jù),可以改成由用戶某種行為(比如滑動頁面)觸發(fā)加載和渲染。

優(yōu)化后的問答頁渲染示意圖

PS:廣告組件本身為異步組件,第二次 setData 會觸發(fā)廣告組件渲染,而廣告組件內(nèi)部自行發(fā)起異步內(nèi)容的加載。

優(yōu)化后的問答頁渲染邏輯,整體上被拆分為四個階段:

  1. 核心內(nèi)容快速渲染階段。該階段為 FMP 主要檢測的數(shù)據(jù)渲染時長,所以在這個階段,我們需要讓頁面的內(nèi)容和元素,足夠裝滿一屏。
  2. 核心內(nèi)容補全渲染階段。該階段將核心內(nèi)容中存在的耗時內(nèi)容,比如圖片、視頻以及小程序 native 組件等內(nèi)容渲染上屏(注:關(guān)于渲染比較耗時的組件,目前已知視頻 video 、所有小程序 native 組件,都不適宜放在第一階段直接渲染,圖片 image 如果條件允許,也盡量不放在第一屏)。
  3. 后續(xù)內(nèi)容渲染階段。該階段將本次接口返回的需要渲染的數(shù)據(jù)全部上屏。
  4. 其他非主要異步數(shù)據(jù)渲染階段(圖例中的直播信息橫條)。將另外一個接口的數(shù)據(jù)渲染上屏。

PS:如果存在核心內(nèi)容渲染完成后依舊無法撐滿一屏的情況,可以考慮設置整體頁面 min-height:100vh ,或者頁面下方放置占位元素,來達到撐滿一屏的效果。

優(yōu)化成果

該優(yōu)化版于2020年8月4日上午11點左右全量上線,在手百中逐步放量。 FMP 指標在8月5日和6日兩天快速下降,7日逐步穩(wěn)定??傆媰?yōu)化 FMP 指標 540ms 。

從數(shù)據(jù)表現(xiàn)來看,優(yōu)化效果非常明顯。

并且,問答頁作為小程序 pv 最大的落地頁,占據(jù)總 pv 的 60% 左右,另外還有 40% 的其他頁面需要我們持續(xù)優(yōu)化,未來數(shù)據(jù)表現(xiàn)還有不小的優(yōu)化空間。

工具建設

工欲善其事必先利其器。后續(xù)我們還需要優(yōu)化其他入口頁面的性能,以及為后續(xù)開發(fā)高性能頁面做持續(xù)的技術(shù)儲備,所以我們將開發(fā)中遇到的和性能有關(guān)的問題做了一些抽象,通過打造基礎(chǔ)操作的工具類庫,從底層上來解決或者規(guī)避問題。

上文中有提到,同時發(fā)起多個 setData 操作,極易造成小程序渲染線程的擁塞,導致渲染效率受到影響,降低小程序內(nèi)容上屏的效率。實際開發(fā)中,我們?nèi)绻苊馔瑫r發(fā)起多個 setData ,必然會帶來額外的邏輯思考成本和代碼結(jié)構(gòu)調(diào)整的成本,也容易因為調(diào)整,降低代碼的可讀性和可維護性。為了兼顧渲染性能的需要和代碼結(jié)構(gòu)的可讀性,以及代碼觀感,我們專門設計了一個內(nèi)容渲染任務管理器。

DataSetter

DataSetter 目前已經(jīng)集成在團隊內(nèi)部的小程序工程腳手架中,通過 AdvancedPage 創(chuàng)建的小程序 Page 實例,即可支持通過該管理器開放的 api 接口,向小程序的渲染線程提交數(shù)據(jù)渲染任務。

DataSetter 將小程序 setData 操作封裝為一個隊列式的渲染任務管理器,使用 DataSetter 進行 set 數(shù)據(jù)操作,可以使得單位時間內(nèi)只有一個 setData 操作被執(zhí)行,而其他被同時 set 的數(shù)據(jù),將在隊列中排隊依次執(zhí)行。

圖例:優(yōu)化前同時 setData ,會導致小程序渲染線程的擁塞

圖例:優(yōu)化后同時 set ,DataSetter 會整體管理數(shù)據(jù)渲染任務,不會造成渲染線程擁塞

為了支持分屏式渲染策略的編寫,DataSetter 的 API 被設計為鏈式調(diào)用式設計??梢砸苑乔短椎姆绞骄帉慛階段內(nèi)容渲染邏輯,代碼行文清晰易懂。

this.$dataSetter.set({
    // 第一階段渲染數(shù)據(jù)
    status:'success',
    aaa:111
}).done(e => {
    // 第一階段渲染完成
    console.log('第一階段渲染完成');
}).set({
    // 第二階段渲染數(shù)據(jù)
    bbb:222
}).set({
    // 第三階段渲染數(shù)據(jù)
    ccc:333
}).done(e => {
   // 第三階段渲染完成
   console.log('第三階段渲染完成‘);
});
復制代碼

DataSetter 源碼

/**
* @name DataSetter
* @description setData語法增強,支持鏈式調(diào)用和隊列式set數(shù)據(jù),一次setData成功之后才開始下一次setData
*/
class DataSetter {
    queue = [];  
    context = null;  
    index = 0;  
    constructor(context) {
        this.context = context;
    }  
    set(dataset = {}) {
        this.queue.push({dataset, callback: null});
        if (this.queue.length === 1) {
            this.exec();
        }
        return this;
     }  
     done(callback) {
         this.queue[this.queue.length - 1].callback = callback;
         return this;
     }  
     exec() {
         let task = this.queue[this.index];
         if (!task) {
             // console.log('all task done!');
             this.refresh();
             return;
         }  
        const next = () => {
            // console.log(set data ${this.index} ok!);
            task.callback && task.callback();
            this.index++;
            this.exec();
        };
        // 如果當前任務dataset為空,則不調(diào)用原生setData,直接執(zhí)行回調(diào)
        if (!task.dataset || Object.keys(task.dataset).length < 1) {
            next();
            return;
         }
        // console.log(set data ${this.index});
        this.context.setData(task.dataset, next);
     }  
     refresh() {
         this.queue = [];
         this.index = 0;
     }
}  
// Page Demo  
Page({
    $dataSetter: null,
    onLoad() {
        this.$dataSetter = new DataSetter(this);
    }
});
復制代碼

后記

造成小程序性能不理想的情況有很多,而渲染問題的解決和優(yōu)化是可以帶來最大收益的,并且如果能根據(jù)實際的業(yè)務場景,來靈活設計視圖的渲染策略,往往可以帶來奇效。渲染問題優(yōu)化是一件非常精細的事情,尤其是面對逐漸復雜的業(yè)務代碼,敢于去改造嘗試,才是最終成功的起點。

文章轉(zhuǎn)載自:https://segmentfault.com/a/1190000023754391

作者:百度小程序技術(shù)

相關(guān)案例查看更多