国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

項目性能優化實踐:深入FMP算法原理探索

開發 項目管理
通過這次深入分析,我對 FMP 有了更全面的認識。FMP 通過科學的算法設計,能夠準確反映用戶感知的頁面加載性能,是前端性能監控的重要指標。

一、前言

二、什么是FMP

三、FMP計算原理

    1. 核心思想

    2. FMP的三種計算方式

    3. 新算法vs傳統算法

    4. 關鍵算法

四、時間標記機制

    1. DOM變化監聽

    2. 時間標記

    3. 標記值獲取

五、資源加載考慮

    1. 資源類型識別

    2. 資源時間獲取

    3. 綜合時間計算

六、子頁面支持

    1. 時間偏移處理

    2. FMP值調整

七、FMP的核心優勢

    1. 用戶感知導向

    2. 多維度計算體系

    3. 高精度測量

八、FMP的實際應用場景

    1. 性能監控實踐

    2. 用戶體驗評估

    3. 優化指導價值

九、總結

一、前言

最近在項目中遇到了頁面加載速度優化的問題,為了提高秒開率等指標,我決定從eebi報表入手,分析一下當前項目的性能監控體系。

通過查看報表中的cost_time、is_first等字段,我開始了解項目的性能數據采集情況。為了更好地理解這些數據的含義,我深入研究了相關SDK的源碼實現。

在分析過程中,我發現采集到的cost_time參數實際上就是FMP(First Meaningful Paint)指標。于是我對FMP的算法實現進行了梳理,了解了它的計算邏輯。

本文將分享我在性能優化過程中的一些思考和發現,希望能對關注前端性能優化的同學有所幫助。

二、什么是FMP

FMP (First Meaningful Paint) 首次有意義繪制,是指頁面首次繪制有意義內容的時間點。與 FCP (First Contentful Paint) 不同,FMP 更關注的是對用戶有實際價值的內容,而不是任何內容的首次繪制。

三、FMP 計算原理

核心思想

FMP 的核心思想是:通過分析視口內重要 DOM 元素的渲染時間,找到對用戶最有意義的內容完成渲染的時間點。

FMP的三種計算方式

  • 新算法 FMP (specifiedValue)

a.基于用戶指定的 DOM 元素計算

b.通過fmpSelector配置指定元素

c.計算指定元素的完整加載時間

  • 傳統算法 FMP (value)

a.基于視口內重要元素計算

b.選擇權重最高的元素

c.取所有參考元素中最晚完成的時間

  • P80 算法 FMP (p80Value)

a.基于 P80 百分位計算

b.取排序后80%位置的時間

c.更穩定的性能指標

新算法vs傳統算法

傳統算法流程

  • 遍歷整個DOM樹
  • 計算每個元素的權重分數
  • 選擇多個重要元素
  • 計算所有元素的加載時間
  • 取最晚完成的時間作為FMP

新算法(指定元素算法)流程

核心思想:直接指定一個關鍵 DOM 元素,計算該元素的完整加載時間作為FMP。

傳統算法詳細步驟

第一步:DOM元素選擇

// 遞歸遍歷 DOM 樹,選擇重要元素
selectMostImportantDOMs(dom: HTMLElement = document.body): void {
  const score = this.getWeightScore(dom);


  if (score > BODY_WEIGHT) {
    // 權重大于 body 權重,作為參考元素
    this.referDoms.push(dom);
  } else if (score >= this.highestWeightScore) {
    // 權重大于等于最高分數,作為重要元素
    this.importantDOMs.push(dom);
  }


  // 遞歸處理子元素
  for (let i = 0, l = dom.children.length; i < l; i++) {
    this.selectMostImportantDOMs(dom.children[i] as HTMLElement);
  }
}

第二步:權重計算

// 計算元素權重分數
getWeightScore(dom: Element) {
  // 獲取元素在視口中的位置和大小
  const viewPortPos = dom.getBoundingClientRect();
  const screenHeight = this.getScreenHeight();


  // 計算元素在首屏中的可見面積
  const fpWidth = Math.min(viewPortPos.right, SCREEN_WIDTH) - Math.max(0, viewPortPos.left);
  const fpHeight = Math.min(viewPortPos.bottom, screenHeight) - Math.max(0, viewPortPos.top);


  // 權重 = 可見面積 × 元素類型權重
  return fpWidth * fpHeight * getDomWeight(dom);
}

權重計算公式:

權重分數 = 可見面積 × 元素類型權重

元素類型權重:

  • OBJECT, EMBED, VIDEO: 最高權重
  • SVG, IMG, CANVAS: 高權重
  • 其他元素: 權重為 1

第三步:加載時間計算

getLoadingTime(dom: HTMLElement, resourceLoadingMap: Record<string, any>): number {
  // 獲取 DOM 標記時間
  const baseTime = getMarkValueByDom(dom);


  // 獲取資源加載時間
  let resourceTime = 0;
  if (RESOURCE_TAG_SET.indexOf(tagType) >= 0) {
    // 處理圖片、視頻等資源
    const resourceTiming = resourceLoadingMap[resourceName];
    resourceTime = resourceTiming ? resourceTiming.responseEnd : 0;
  }


  // 返回較大值(DOM 時間 vs 資源時間)
  return Math.max(resourceTime, baseTime);
}

第四步:FMP值計算

calcValue(resourceLoadingMap: Record<string, any>, isSubPage: boolean = false): void {
  // 構建參考元素列表(至少 3 個元素)
  const referDoms = this.referDoms.length >= 3 
    ? this.referDoms 
    : [...this.referDoms, ...this.importantDOMs.slice(this.referDoms.length - 3)];


  // 計算每個元素的加載時間
  const timings = referDoms.map(dom => this.getLoadingTime(dom, resourceLoadingMap));


  // 排序時間數組
  const sortedTimings = timings.sort((t1, t2) => t1 - t2);


  // 計算最終值
  const info = getMetricNumber(sortedTimings);
  this.value = info.value;        // 最后一個元素的時間(最晚完成)
  this.p80Value = info.p80Value;  // P80 百分位時間
}

新算法詳細步驟

第一步:配置指定元素

// 通過全局配置指定 FMP 目標元素
const { fmpSelector = "" } = SingleGlobal?.getOptions?.();

配置示例:

// 初始化時配置
init({
  fmpSelector: '.main-content',  // 指定主要內容區域
  // 或者
  fmpSelector: '#hero-section',  // 指定首屏區域
  // 或者
  fmpSelector: '.product-list'   // 指定產品列表
});

第二步:查找指定元素

if (fmpSelector) {
  // 使用 querySelector 查找指定的 DOM 元素
  const $specifiedEl = document.querySelector(fmpSelector);


  if ($specifiedEl && $specifiedEl instanceof HTMLElement) {
    // 找到指定元素,進行后續計算
    this.specifiedDom = $specifiedEl;
  }
}

查找邏輯:

  • 使用document.querySelector()查找元素
  • 驗證元素存在且為 HTMLElement 類型
  • 保存元素引用到specifiedDom

第三步:計算指定元素的加載時間

// 計算指定元素的完整加載時間
this.specifiedValue = this.getLoadingTime(
  $specifiedEl,
  resourceLoadingMap
);

加載時間計算包含:

  • DOM 標記時間
// 獲取 DOM 元素的基礎標記時間
const baseTime = getMarkValueByDom(dom);
  • 資源加載時間
let resourceTime = 0;
// 處理直接資源(img, video, embed 等)
const tagType = dom.tagName.toUpperCase();
if (RESOURCE_TAG_SET.indexOf(tagType) >= 0) {
  const resourceName = normalizeResourceName((dom as any).src);
  const resourceTiming = resourceLoadingMap[resourceName];
  resourceTime = resourceTiming ? resourceTiming.responseEnd : 0;
}
// 處理背景圖片
const bgImgUrl = getDomBgImg(dom);
if (isImageUrl(bgImgUrl)) {
  const resourceName = normalizeResourceName(bgImgUrl);
  const resourceTiming = resourceLoadingMap[resourceName];
  resourceTime = resourceTiming ? resourceTiming.responseEnd : 0;
}
  • 綜合時間計算
// 返回 DOM 時間和資源時間的較大值
return Math.max(resourceTime, baseTime);

第四步:FMP值確定

// 根據是否有指定值來決定使用哪個 FMP 值
if (specifiedValue === 0) {
  // 如果沒有指定值,回退到傳統算法
  fmp = isSubPage ? value - diffTime : value;
} else {
  // 如果有指定值,使用指定值
  fmp = isSubPage ? specifiedValue - diffTime : specifiedValue;
}

決策邏輯:

  • 如果 specifiedValue > 0:使用指定元素的加載時間
  • 如果 specifiedValue === 0:回退到傳統算法

第五步:子頁面時間調整

// 子頁面的 FMP 值需要減去時間偏移
if (isSubPage) {
  fmp = specifiedValue - diffTime;
  // diffTime = startSubTime - initTime
}

新算法的優勢

精確性更高

  • 直接針對業務關鍵元素
  • 避免權重計算的誤差
  • 更貼近業務需求

可控性強

  • 開發者可以指定關鍵元素
  • 可以根據業務場景調整
  • 避免算法自動選擇的偏差

計算簡單

  • 只需要計算一個元素
  • 不需要復雜的權重計算
  • 性能開銷更小

業務導向

  • 直接反映業務關鍵內容的加載時間
  • 更符合用戶體驗評估需求
  • 便于性能優化指導

關鍵算法

P80 百分位計算

export function getMetricNumber(sortedTimings: number[]) {
  const value = sortedTimings[sortedTimings.length - 1];  // 最后一個(最晚)
  const p80Value = sortedTimings[Math.floor((sortedTimings.length - 1) * 0.8)];  // P80
  return { value, p80Value };
}

元素類型權重

const IMPORTANT_ELEMENT_WEIGHT_MAP = {
  SVG: IElementWeight.High,      // 高權重
  IMG: IElementWeight.High,      // 高權重
  CANVAS: IElementWeight.High,   // 高權重
  OBJECT: IElementWeight.Highest, // 最高權重
  EMBED: IElementWeight.Highest, // 最高權重
  VIDEO: IElementWeight.Highest   // 最高權重
};

四、時間標記機制

DOM變化監聽

// MutationObserver 監聽 DOM 變化
private observer = new MutationObserver((mutations = []) => {
  const now = Date.now();
  this.handleChange(mutations, now);
});

時間標記

// 為每個 DOM 變化創建性能標記
mark(count);  // 創建 performance.mark(`mutation_pc_${count}`)
// 為 DOM 元素設置標記
setDataAttr(elem, TAG_KEY, `${mutationCount}`);

標記值獲取

// 根據 DOM 元素獲取標記時間
getMarkValueByDom(dom: HTMLElement) {
  const markValue = getDataAttr(dom, TAG_KEY);
  return getMarkValue(parseInt(markValue));
}

五、資源加載考慮

資源類型識別

圖片資源: <img> 標簽的 src屬性

視頻資源: <video> 標簽的 src屬性

背景圖片: CSS background-image屬性

嵌入資源: <embed>, <object>標簽

資源時間獲取

// 從 Performance API 獲取資源加載時間
const resourceTiming = resourceLoadingMap[resourceName];
const resourceTime = resourceTiming ? resourceTiming.responseEnd : 0;

綜合時間計算

// DOM 時間和資源時間的較大值
return Math.max(resourceTime, baseTime);

六、子頁面支持

時間偏移處理

// 子頁面從調用 send 方法開始計時
const diffTime = this.startSubTime - this.initTime;
// 子頁面只統計開始時間之后的資源
if (!isSubPage || resource.startTime > diffTime) {
  resourceLoadingMap[resourceName] = resource;
}

FMP值調整

// 子頁面的 FMP 值需要減去時間偏移
fmp = isSubPage ? value - diffTime : value;

七、FMP的核心優勢

用戶感知導向

FMP 最大的優勢在于它真正關注用戶的實際體驗:

  • 內容價值優先:只計算對用戶有意義的內容渲染時間
  • 智能權重評估:根據元素的重要性和可見性進行差異化計算
  • 真實體驗映射:更貼近用戶的實際感知,而非技術層面的指標

多維度計算體系

FMP 采用了更加全面的計算方式:

  • 元素權重分析:綜合考慮元素類型和渲染面積的影響
  • 資源加載關聯:將靜態資源加載時間納入計算范圍
  • 算法對比驗證:支持多種算法并行計算,確保結果準確性

高精度測量

FMP 在測量精度方面表現突出:

  • DOM 變化追蹤:基于實際 DOM 結構變化的時間點
  • API 數據融合:結合 Performance API 提供的詳細數據
  • 統計分析支持:支持 P80 百分位等多種統計指標,便于性能分析

八、FMP的實際應用場景

性能監控實踐

FMP 在性能監控中發揮著重要作用:

  • 關鍵指標追蹤:實時監控頁面首次有意義內容的渲染時間
  • 瓶頸識別:快速定位性能瓶頸和潛在的優化點
  • 趨勢分析:通過歷史數據了解性能變化趨勢

用戶體驗評估

FMP 為產品團隊提供了用戶視角的性能評估:

  • 真實感知測量:評估用戶實際感受到的頁面加載速度
  • 競品對比分析:對比不同頁面或產品的性能表現
  • 用戶滿意度關聯:將技術指標與用戶滿意度建立關聯

優化指導價值

FMP 數據為性能優化提供了明確的方向:

  • 資源優化策略:指導靜態資源加載順序和方式的優化
  • 渲染路徑優化:幫助優化關鍵渲染路徑,提升首屏體驗
  • 量化效果評估:為優化效果提供可量化的評估標準

九、總結

通過這次深入分析,我對 FMP 有了更全面的認識。FMP 通過科學的算法設計,能夠準確反映用戶感知的頁面加載性能,是前端性能監控的重要指標。

它不僅幫助我們更好地理解頁面加載過程,更重要的是為性能優化提供了科學的依據。在實際項目中,合理運用 FMP 指標,能夠有效提升用戶體驗,實現真正的"秒開"效果。

希望這篇文章能對正在關注前端性能優化的同學有所幫助,也歡迎大家分享自己的實踐經驗。

責任編輯:武曉燕 來源: 得物技術
相關推薦

2020-07-17 19:55:50

Vue前端性能優化

2023-10-31 12:50:35

智能優化探索

2024-03-27 10:14:48

2023-10-11 08:36:42

復合查詢腳本查詢

2020-02-18 16:14:33

RedisRDBAOF

2020-03-23 15:15:57

MySQL性能優化數據庫

2024-01-03 16:29:01

Agent性能優化

2010-07-06 09:07:09

2020-10-07 14:20:41

Tomcat深入解析

2024-01-02 07:44:27

廣告召回算法多路召回

2019-08-02 11:28:45

HadoopYARN調度系統

2021-09-24 14:02:53

性能優化實踐

2011-07-11 15:26:49

性能優化算法

2025-04-03 03:55:00

2022-10-28 13:41:51

字節SDK監控

2017-09-11 16:34:00

2023-09-06 08:14:34

性能優化模式

2022-06-07 15:33:51

Android優化實踐

2024-12-12 09:00:28

點贊
收藏

51CTO技術棧公眾號

天天做天天躁天天躁| 国产主播福利| 国产在线日韩精品| 日韩中文理论片| 国产网红女主播精品视频| 欧美日韩一卡二卡三卡 | 91精品国产综合久久福利软件 | 九九久久精品| 亚洲女厕所小便bbb| 欧美高清视频免费观看| 国产69精品久久久久久久| 国产精品va视频| 日韩欧美一区在线观看| 成人精品aaaa网站| 日韩在线观看一区二区三区| 亚洲人成亚洲人成在线观看| v天堂福利视频在线观看| 免费亚洲婷婷| 国产亚洲精品美女久久久m| 久久国产成人精品| 日韩av成人在线观看| 51亚洲精品| 国外成人在线视频| 午夜精品福利影院| 国产精品成人一区| 久久亚洲国产| 99在线视频播放| 激情综合电影网| 欧美激情导航| 久久精品国产99| 大片在线观看网站免费收看| 国产99久久久久| 中文字幕无码精品亚洲35| 成人中文字幕电影| 久久久精品在线视频| 日本一区二区成人在线| 嫩草影院2018| 欧美日韩专区在线| a天堂资源在线| 中日韩美女免费视频网站在线观看| 朝桐光一区二区| 欧美日韩国产91| 神马影视一区二区| 成人3d动漫一区二区三区91| 日韩成人dvd| 久草视频国产在线| 亚洲免费观看高清| 欧美成人二区| 深夜福利91大全| 亚洲精华一区二区三区| 成人在线中文字幕| 日韩av一区二| 久久久999免费视频| 国产精品美女久久久久高潮| 在线国产三级| 精品国精品自拍自在线| 精品欧美视频| 成人久久久久久| 久久精品二区亚洲w码| 国产欧美高清在线| 精品久久久精品| 色是在线视频| 欧美综合激情网| 国产精品美女久久久浪潮软件| 欧美视频在线观看视频| 亚洲免费在线电影| 影音先锋男人在线资源| 欧美国产日韩在线| 亚洲精一区二区三区| 精品一卡二卡三卡| 欧美日韩二区三区| 成人动漫视频在线观看| 日韩av在线高清| 在线视频亚洲欧美中文| 97超碰资源| 成人app下载| 青青久在线视频免费观看| 亚洲欧美在线磁力| 五月精品视频| 俄罗斯av网站| 欧美精选一区二区| 日本久久久久| 黑人中文字幕一区二区三区| 成人综合婷婷国产精品久久蜜臀| 轻轻色免费在线视频| 亚洲人成伊人成综合网久久久| 成人影视亚洲图片在线| 国产欧美日韩网站| 欧美一区午夜精品| 成人女性视频| www黄色av| 亚洲国产精品成人va在线观看| 精品视频99| 欧美二区在线视频| 欧美一区二区三区免费视频| 大陆精大陆国产国语精品| 日韩成人av网站| 欧美日韩激情小视频| 亚洲精品a区| 中文字幕综合在线观看| 一本色道久久综合亚洲91| 韩国女主播一区二区三区| 一级黄色录像免费看| 欧美日韩一区三区| 久久婷婷蜜乳一本欲蜜臀| 天堂在线资源视频| 一区二区三区国产在线观看| 久久久久久久高潮| 国产在线视频网址| 国产免费一区二区三区香蕉精| 91麻豆蜜桃一区二区三区| 大香伊人久久| 国产综合 伊人色| 欧美日韩在线影院| 亚洲国产最新| 五月婷婷六月丁香激情| 综合激情国产一区| 久久99精品久久久久| 自由的xxxx在线视频| 97久久人人超碰caoprom欧美| 亚洲国产精品高清| 欧美日韩va| 日本福利视频一区| 一区二区三区日韩在线| 韩国理伦片一区二区三区在线播放 | aⅴ在线视频男人的天堂| 欧美综合在线第二页| 国产亚洲精品久| 一区二区三区| 久久精品.com| 欧美大片va欧美在线播放| 国产99久久久国产精品潘金网站| 欧美人体一区二区三区| www插插插无码免费视频网站| 亚洲人成网站在线播| 国产91精品入口| av一级久久| 色爱综合网站| 国产精品av电影| 亚洲成av人片在www色猫咪| 久久国产精品亚洲人一区二区三区 | 色综合视频网站| 久久美女高清视频| 99热这里只有精品首页| 成人毛片高清视频观看| 国产成人亚洲综合91| 五月天欧美精品| 黄色成人在线网站| 欧美xxxx做受欧美88bbw| 一区二区三区四区欧美日韩| 亚洲区一区二区| 国产欧美一区二区精品性 | 欧美大片在线看| 亚洲日本中文字幕区| 欧美va久久久噜噜噜久久| 777电影在线观看| 视频一区三区| 日日摸夜夜添一区| 亚洲欧美另类久久久精品2019| 欧美一区二区| 国产精品13p| 天堂网在线免费观看| 成人乱色短篇合集| 欧美va在线播放| 91浏览器在线视频| 国产欧美日韩| 免费高清在线观看| 日韩av在线播放不卡| 国外成人在线视频| 欧美在线影院一区二区| 久久国产精品露脸对白| 精品精品视频| 免费在线超碰| 91免费网站视频| 国内精品久久久久伊人av| 日韩欧美中文第一页| 国产毛片一区| 高清一区二区| 内衣办公室在线| 日本老太婆做爰视频| 欧美一级在线播放| 日韩欧美一级二级三级久久久| 久久久精品综合| 国产精品www.| 豆花视频一区| 高清av在线| 久久美女福利视频| 91亚洲精华国产精华| 精品一区二区三区四区在线| 国产精品免费视频一区| 亚洲伊人观看| 国产图片一区| 久久免费电影| 无限国产资源| 神马影院一区二区| 欧美中在线观看| 亚洲精品色婷婷福利天堂| 精品久久中文字幕久久av| av亚洲精华国产精华精华| 国产精品啊v在线|