最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端監(jiān)測(cè)界面內(nèi)存泄漏詳細(xì)的代碼方案

 更新時(shí)間:2026年03月30日 09:29:50   作者:小小小小宇  
內(nèi)存泄漏是Web開發(fā)中常見但容易忽視的問(wèn)題,隨著項(xiàng)目體量增長(zhǎng)或長(zhǎng)時(shí)間運(yùn)行的單頁(yè)應(yīng)用增多,內(nèi)存泄漏所帶來(lái)的性能下降、頁(yè)面卡頓甚至崩潰問(wèn)題變得尤為突出,這篇文章主要介紹了前端監(jiān)測(cè)界面內(nèi)存泄漏詳細(xì)的代碼方案,需要的朋友可以參考下

前言

前端監(jiān)測(cè)界面內(nèi)存泄漏通常分為開發(fā)階段的排查(非代碼方案)自動(dòng)化/生產(chǎn)環(huán)境的監(jiān)控(代碼方案)。

以下是詳細(xì)的代碼方案和非代碼方案。

一、 非代碼方案(開發(fā)與調(diào)試階段)

主要依賴瀏覽器自帶的開發(fā)者工具(Chrome DevTools),這是最直觀、最常用的方法。

1. Performance 面板(宏觀監(jiān)測(cè))

用于觀察內(nèi)存隨時(shí)間變化的趨勢(shì)。

  • 操作步驟
    1. 打開 Chrome DevTools -> Performance 標(biāo)簽。
    2. 勾選 Memory 選項(xiàng)。
    3. 點(diǎn)擊錄制(Record),在頁(yè)面上執(zhí)行一系列操作(如:打開彈窗 -> 關(guān)閉彈窗,重復(fù)多次)。
    4. 停止錄制。
  • 分析
    • 查看 JS Heap 曲線。
    • 正常情況:內(nèi)存上升后,觸發(fā) GC(垃圾回收)會(huì)回落到基準(zhǔn)線(鋸齒狀)。
    • 泄漏跡象:內(nèi)存階梯式上升,每次 GC 后最低點(diǎn)都比上一次高,說(shuō)明有對(duì)象無(wú)法被回收。

2. Memory 面板 - Heap Snapshot(微觀定位)

用于精確定位是什么對(duì)象泄漏了。

  • 操作步驟
    1. 打開 Memory 標(biāo)簽。
    2. 選擇 Heap snapshot
    3. 在操作前拍一張快照(Snapshot 1)。
    4. 執(zhí)行操作(如組件加載再卸載)。
    5. 再拍一張快照(Snapshot 2)。
  • 分析
    • 在 Snapshot 2 中選擇 Comparison(對(duì)比)視圖,對(duì)比 Snapshot 1。
    • 重點(diǎn)關(guān)注 Detached DOM tree(分離的 DOM 樹)。這通常意味著 DOM 節(jié)點(diǎn)已從頁(yè)面移除,但 JS 中仍有引用(如未解綁的事件監(jiān)聽器),導(dǎo)致無(wú)法回收。

3. Task Manager(任務(wù)管理器)

  • 操作:Chrome 瀏覽器中按 Shift + Esc
  • 作用:查看當(dāng)前 Tab 頁(yè)面的總體內(nèi)存占用(Memory Footprint)。如果頁(yè)面靜止不動(dòng)但數(shù)值持續(xù)上漲,說(shuō)明存在泄漏。

二、 代碼方案(自動(dòng)化測(cè)試與線上監(jiān)控)

代碼方案主要用于 CI/CD 流程中的回歸測(cè)試,或生產(chǎn)環(huán)境的異常上報(bào)。

1. 使用 Puppeteer 編寫自動(dòng)化檢測(cè)腳本

這是目前最主流的自動(dòng)化檢測(cè)方案。通過(guò)模擬用戶操作,并在操作前后強(qiáng)制執(zhí)行垃圾回收,對(duì)比堆內(nèi)存大小。

關(guān)鍵點(diǎn):?jiǎn)?dòng) Chrome 時(shí)需要開啟 --js-flags="--expose-gc" 以便在代碼中手動(dòng)觸發(fā) GC。

// monitor-leak.js
const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch({
    headless: false, // 方便調(diào)試觀察
    args: ['--js-flags="--expose-gc"'] // 關(guān)鍵:允許手動(dòng)觸發(fā)垃圾回收
  });
  const page = await browser.newPage();
  await page.goto('http://localhost:8080/target-page');
  // 1. 獲取基準(zhǔn)內(nèi)存
  await page.evaluate(() => window.gc()); // 強(qiáng)制 GC
  const initialMemory = await page.metrics();
  console.log(`初始 JSHeapSize: ${initialMemory.JSHeapUsedSize / 1024 / 1024} MB`);
  // 2. 模擬用戶操作(重復(fù)多次以放大泄漏效果)
  for (let i = 0; i < 10; i++) {
    await page.click('#open-dialog-btn');
    await page.waitForSelector('.dialog');
    await page.click('#close-dialog-btn');
    await page.waitForSelector('.dialog', { hidden: true });
  }
  // 3. 再次強(qiáng)制 GC 并檢測(cè)
  await page.evaluate(() => window.gc());
  const finalMemory = await page.metrics();
  console.log(`操作后 JSHeapSize: ${finalMemory.JSHeapUsedSize / 1024 / 1024} MB`);
  const diff = finalMemory.JSHeapUsedSize - initialMemory.JSHeapUsedSize;
  // 4. 設(shè)置閾值判斷(例如增長(zhǎng)超過(guò) 1MB 視為泄漏)
  if (diff > 1024 * 1024) {
    console.error(`檢測(cè)到內(nèi)存泄漏! 增長(zhǎng)量: ${diff / 1024} KB`);
  } else {
    console.log('內(nèi)存使用正常');
  }
  await browser.close();
})();

2. 生產(chǎn)環(huán)境運(yùn)行時(shí)監(jiān)控 (performance.memory)

雖然 performance.memory 是非標(biāo)準(zhǔn) API(主要 Chrome 支持),但它是線上獲取內(nèi)存數(shù)據(jù)的唯一低成本途徑。

可以將其封裝為 Hook 或工具函數(shù),定期上報(bào)。

/**
 * 簡(jiǎn)單的內(nèi)存監(jiān)控上報(bào)函數(shù)
 * 建議在頁(yè)面空閑時(shí)或定期執(zhí)行
 */
function reportMemoryUsage() {
  // 僅 Chrome/Edge 支持
  if (performance && performance.memory) {
    const {
      jsHeapSizeLimit, // 內(nèi)存大小限制
      totalJSHeapSize, // 可使用的內(nèi)存
      usedJSHeapSize   // 實(shí)際使用的內(nèi)存
    } = performance.memory;
    const usedMB = usedJSHeapSize / 1024 / 1024;
    console.log(`當(dāng)前內(nèi)存使用: ${usedMB.toFixed(2)} MB`);
    // 設(shè)置報(bào)警閾值,例如超過(guò) 50MB 或 占比過(guò)高時(shí)上報(bào)
    // 注意:這里的數(shù)值包含未回收的垃圾,僅作趨勢(shì)參考
    if (usedMB > 50) {
      // sendToAnalytics({ type: 'memory_warning', value: usedMB });
    }
  }
}
// 示例:每 10 秒采樣一次
setInterval(reportMemoryUsage, 10000);

3. 使用 Meta 的 MemLab

MemLab 是 Meta (Facebook) 開源的專門用于查找 JavaScript 內(nèi)存泄漏的框架,它基于 Puppeteer,但封裝了更完善的分析邏輯(自動(dòng)識(shí)別 Detached DOM)。

工作流程

  1. 導(dǎo)航到頁(yè)面。
  2. 執(zhí)行操作。
  3. 返回初始狀態(tài)。
  4. MemLab 自動(dòng)分析快照差異,尋找未釋放的對(duì)象。

配置文件示例 (memlab-scenario.js):

module.exports = {
  // 初始訪問(wèn)地址
  url: () => 'http://localhost:3000',
  // 交互操作:通常是觸發(fā)泄漏的操作
  action: async (page) => {
    await page.click('button#trigger-action');
    // 等待操作完成
    await new Promise(r => setTimeout(r, 500));
  },
  // 回退操作:試圖讓頁(yè)面回到初始狀態(tài)
  back: async (page) => {
    await page.click('button#reset-state');
    // 等待狀態(tài)恢復(fù)
    await new Promise(r => setTimeout(r, 500));
  },
  // 過(guò)濾規(guī)則:只關(guān)注特定的泄漏對(duì)象(可選)
  leakFilter: (node, snapshot, leakerRoots) => {
    // 例如只關(guān)注分離的 DOM 元素
    return node.type === 'native' && node.name.startsWith(' Detached'); 
  },
};

運(yùn)行命令: memlab run --scenario memlab-scenario.js

4. 使用FinalizationRegistry(現(xiàn)代瀏覽器 API)

用于在開發(fā)階段通過(guò)代碼精確監(jiān)聽某個(gè)對(duì)象是否被回收。如果對(duì)象應(yīng)該被銷毀但長(zhǎng)時(shí)間未收到回調(diào),可能存在泄漏。

// 調(diào)試工具類:用于監(jiān)測(cè)組件或?qū)ο笫欠癖换厥?
const registry = new FinalizationRegistry((heldValue) => {
  console.log(`? 對(duì)象 [${heldValue}] 已被垃圾回收`);
});
export function observeObject(obj, name) {
  registry.register(obj, name);
}
// 使用示例(例如在 Vue/React 組件中)
// mounted / useEffect:
// let heavyObject = { data: new Array(10000) };
// observeObject(heavyObject, 'MyHeavyData');
// heavyObject = null; // 解除引用,理論上應(yīng)該觸發(fā)上面的回調(diào)

總結(jié)建議

  1. 日常開發(fā):遇到頁(yè)面卡頓或 Crash,首選 Chrome DevTools Memory 面板 抓快照對(duì)比,重點(diǎn)查 Detached DOM
  2. 持續(xù)集成:引入 MemLab 或編寫 Puppeteer 腳本,針對(duì)關(guān)鍵核心鏈路(如長(zhǎng)時(shí)間駐留的單頁(yè)應(yīng)用路由切換)進(jìn)行回歸測(cè)試。
  3. 線上監(jiān)控:利用 performance.memory 進(jìn)行粗粒度的趨勢(shì)監(jiān)控,結(jié)合錯(cuò)誤監(jiān)控平臺(tái)(如 Sentry)排查 OOM(Out of Memory)崩潰。

到此這篇關(guān)于前端監(jiān)測(cè)界面內(nèi)存泄漏詳細(xì)的文章就介紹到這了,更多相關(guān)前端監(jiān)測(cè)界面內(nèi)存泄漏內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 小程序ios音頻播放沒(méi)聲音問(wèn)題的解決

    小程序ios音頻播放沒(méi)聲音問(wèn)題的解決

    這篇文章主要介紹了小程序ios音頻播放沒(méi)聲音問(wèn)題的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • JavaScript中雙嘆號(hào)(!!)作用示例介紹

    JavaScript中雙嘆號(hào)(!!)作用示例介紹

    這篇文章主要介紹了JavaScript中雙嘆號(hào)(!!)的作用,需要的朋友可以參考下
    2014-04-04
  • 超級(jí)簡(jiǎn)單實(shí)現(xiàn)JavaScript MVC 樣式框架

    超級(jí)簡(jiǎn)單實(shí)現(xiàn)JavaScript MVC 樣式框架

    本文給大家分享的是一則翻譯過(guò)來(lái)的,由國(guó)外友人寫的如何簡(jiǎn)單有效的實(shí)現(xiàn)javascript MVC樣式框架,算是一個(gè)MVC的入門教程,希望大家能夠喜歡。
    2015-03-03
  • Javascript循環(huán)刪除數(shù)組中元素的幾種方法示例

    Javascript循環(huán)刪除數(shù)組中元素的幾種方法示例

    這篇文章主要給大家介紹了關(guān)于Javascript循環(huán)刪除數(shù)組中元素的幾種方法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-05-05
  • JavaScript原生對(duì)象之Number對(duì)象的屬性和方法詳解

    JavaScript原生對(duì)象之Number對(duì)象的屬性和方法詳解

    這篇文章主要介紹了JavaScript原生對(duì)象之Number對(duì)象的屬性和方法詳解,本文講解了創(chuàng)建 Number 對(duì)象的語(yǔ)法、MAX_VALUE、MIN_VALUE、NaN等屬性或方法,需要的朋友可以參考下
    2015-03-03
  • javascript中callee與caller的區(qū)別分析

    javascript中callee與caller的區(qū)別分析

    有些小伙伴可能會(huì)問(wèn)caller,callee 是什么?在javascript 中有什么樣的作用?那么本篇會(huì)對(duì)于此做一些基本介紹。希望能夠?qū)Υ蠹依斫鈐avascript中的callee與caller有所幫助。
    2015-04-04
  • JavaScript實(shí)現(xiàn)返回到上一頁(yè)的三種方法

    JavaScript實(shí)現(xiàn)返回到上一頁(yè)的三種方法

    在網(wǎng)頁(yè)開發(fā)中,實(shí)現(xiàn)返回上一頁(yè)功能非常常見,JavaScript 提供了多種方式來(lái)實(shí)現(xiàn),下面詳細(xì)介紹三種最常用且可靠的方法,并附帶優(yōu)缺點(diǎn)對(duì)比和使用場(chǎng)景,需要的朋友可以參考下
    2026-01-01
  • 關(guān)于js new Date() 出現(xiàn)NaN 的分析

    關(guān)于js new Date() 出現(xiàn)NaN 的分析

    在一個(gè)項(xiàng)目中需要進(jìn)行日期的格式化,后臺(tái)傳到前端是時(shí)間的整數(shù)(Date.getTime),當(dāng)后臺(tái)數(shù)據(jù)返回字符串時(shí),發(fā)現(xiàn)轉(zhuǎn)換日期時(shí)在ie下變成NaN,但是真的是這樣嗎?接下來(lái)我們慢慢分析
    2012-10-10
  • 小程序?qū)崿F(xiàn)訂單評(píng)價(jià)和商家評(píng)價(jià)

    小程序?qū)崿F(xiàn)訂單評(píng)價(jià)和商家評(píng)價(jià)

    這篇文章主要為大家詳細(xì)介紹了小程序?qū)崿F(xiàn)訂單評(píng)價(jià)和商家評(píng)價(jià)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • JS分頁(yè)的實(shí)現(xiàn)(同步與異步)

    JS分頁(yè)的實(shí)現(xiàn)(同步與異步)

    這篇文章主要介紹了JS分頁(yè)的實(shí)現(xiàn)(同步與異步),需要的朋友可以參考下
    2017-09-09

最新評(píng)論

常州市| 安溪县| 乌什县| 东海县| 大理市| 息烽县| 泗水县| 中宁县| 郑州市| 萝北县| 綦江县| 阿鲁科尔沁旗| 天长市| 红桥区| 中牟县| 安龙县| 沿河| 长沙市| 神木县| 乌拉特后旗| 全椒县| 安福县| 苏尼特左旗| 襄垣县| 嘉荫县| 岚皋县| 雷波县| 四会市| 汕尾市| 磐安县| 镇赉县| 黎城县| 濮阳县| 新昌县| 开原市| 华蓥市| 松滋市| 且末县| 米易县| 慈溪市| 金阳县|