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

1. 業務邏輯描述

業務邏輯描述

2. 優化後的性能提高對比

至關明顯vue

性能分析對比

3. 常規處理邏輯

業務邏輯描述

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

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

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

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

4. 個人優化思路

  1. 標題2中的一、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. 項目地址

美團項目數組

相關文章
相關標籤/搜索