美團、餓了么外賣點菜界面聯動菜單性能優化


1. 業務邏輯描述

業務邏輯描述

2. 優化后的性能提升對比

相當明顯

性能分析對比

3. 常規處理邏輯

業務邏輯描述

把左側菜單的一項成為分類(category),
把右側每一項稱為(item)。

  1. DOM更新后,獲取整個content的高度(包裹所有item的盒子的高度);
  2. 獲取每個category在content上的高度,從而獲取跳轉y值區間數組jumpArr
  3. 在content上監聽滑動事件,判斷當前y值在jumpArr中的位置,更新左側category樣式。

這種方法處理的問題(性能上的)

每次觸發scroll事件后都會遍歷數組jumpArr來判斷此刻左側導航該有的樣式。scroll事件的觸發是相當密集的,也就是jumpArr的遍歷也是相當密集。對性能有很大的影響。特別是當應用越來越大時、設備比較老舊時。

4. 我的優化思路

  1. 標題2中的1、2步保持不變,通過相同的方法獲得jumpArr;
  2. 上面步驟3采用的是實時遍歷,現在拋棄這種做法。而是,生產一個跳轉函數,可以使用if...else也可以使用switch...case,這里選用后者,因為性能更加出眾。
    注:生成的jumpFunc是字符串,需要使用eval()來進行函數轉換。

5. 代碼示例(vue)

  1. 計算獲取jumpArr
getGoodsHeight() {
    //這兩項是用來獲取content總高的
    const specials = document.querySelector(".specials");
    const itemList = document.querySelectorAll(".group-item");
    //預賽了
    let heightList = [];
    heightList.push(specials.offsetHeight);
    itemList.forEach((element, index) => {
    const eleHeight = element.offsetHeight;
    const preheight = heightList[index];
    heightList.push(preheight + eleHeight);
    });
    this.heightList = heightList;
}
  1. 根據jumpArr得出用於邏輯處理的跳轉函數jumpFunc
getJumpFunc() {
    //這樣的寫法有助於性能,使用判斷而不是用循環
    let i = 0;
    let func = `(function () { return function (y, context) {`;
    const length = this.heightList.length;
    while (i < length) {
        const current = this.heightList[i - 1] || 0;
        const next = this.heightList[i];
        const lastIndex = length - 1;
        let partition = "";
        switch (i) {
            case 0:
            partition = `if(y > 0 && y< ${next}) { context.addNavStyle(${i}) }`;
            break;
            case lastIndex:
            partition = `else { context.addNavStyle(${i}) }};})();`;
            break;
            default:
            partition = `else if (y > ${current} && y <${next}) { context.addNavStyle(${i}) }`;
            break;
        }
        func += partition;
        i++;
    }
    return eval(func);
},
  1. 項目地址

美團項目


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM