[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fperformance":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fperformance":2713,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fperformance":2739},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":2709,"stem":2710,"id":2711,"extension":2712},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fperformance","性能优化","防抖\u002F节流、渲染与内存、资源预加载及引擎行为是前端性能的主要抓手。相关 CSS 见 视觉效果、Head 资源提示。","技能小册",[12,13],"javascript","performance","2025-07-04",false,{"type":17,"value":18,"toc":2689},"minimark",[19,22,37,42,47,52,55,375,379,382,997,1001,1160,1164,1184,1190,1243,1368,1372,1384,1511,1536,1636,1640,1644,1713,1724,1728,1765,1769,1772,1790,1995,1998,2010,2087,2095,2212,2216,2219,2223,2226,2294,2297,2311,2315,2318,2321,2329,2453,2456,2460,2463,2466,2497,2499,2517,2520,2614,2617,2620,2623,2686],[20,21,8],"h1",{"id":8},[23,24,25,26,31,32,36],"p",{},"防抖\u002F节流、渲染与内存、资源预加载及引擎行为是前端性能的主要抓手。相关 CSS 见 ",[27,28,30],"a",{"href":29},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fcss\u002Fvisual-effects","视觉效果","、",[27,33,35],{"href":34},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fhtml\u002Fhead","Head 资源提示","。",[38,39,41],"h2",{"id":40},"一代码层面优化","一、代码层面优化",[43,44,46],"h3",{"id":45},"_1-防抖debounce与节流throttle实现","1. 防抖（Debounce）与节流（Throttle）实现",[48,49,51],"h4",{"id":50},"防抖-延迟执行连续触发只执行最后一次","防抖 – 延迟执行，连续触发只执行最后一次",[23,53,54],{},"应用场景：搜索输入、窗口resize、表单验证。",[56,57,62],"pre",{"className":58,"code":59,"language":60,"meta":61,"style":61},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","function debounce(fn, delay) {\n  let timer = null;\n  return function (...args) {\n    clearTimeout(timer);\n    timer = setTimeout(() => fn.apply(this, args), delay);\n  };\n}\n\u002F\u002F 立即执行版（首次立即执行，后续防抖）\nfunction debounceImmediate(fn, delay) {\n  let timer = null;\n  return function (...args) {\n    if (timer === null) fn.apply(this, args);\n    clearTimeout(timer);\n    timer = setTimeout(() => {\n      timer = null;\n    }, delay);\n  };\n}\n","js","",[63,64,65,98,119,142,158,206,212,218,225,245,258,275,311,324,341,353,365,370],"code",{"__ignoreMap":61},[66,67,70,74,78,82,86,89,92,95],"span",{"class":68,"line":69},"line",1,[66,71,73],{"class":72},"sbsja","function",[66,75,77],{"class":76},"sGLFI"," debounce",[66,79,81],{"class":80},"sP7_E","(",[66,83,85],{"class":84},"s99_P","fn",[66,87,88],{"class":80},",",[66,90,91],{"class":84}," delay",[66,93,94],{"class":80},")",[66,96,97],{"class":80}," {\n",[66,99,101,104,108,112,116],{"class":68,"line":100},2,[66,102,103],{"class":72},"  let",[66,105,107],{"class":106},"su5hD"," timer",[66,109,111],{"class":110},"smGrS"," =",[66,113,115],{"class":114},"s39Yj"," null",[66,117,118],{"class":80},";\n",[66,120,122,126,129,132,135,138,140],{"class":68,"line":121},3,[66,123,125],{"class":124},"sVHd0","  return",[66,127,128],{"class":72}," function",[66,130,131],{"class":80}," (",[66,133,134],{"class":110},"...",[66,136,137],{"class":84},"args",[66,139,94],{"class":80},[66,141,97],{"class":80},[66,143,145,148,151,154,156],{"class":68,"line":144},4,[66,146,147],{"class":76},"    clearTimeout",[66,149,81],{"class":150},"skxfh",[66,152,153],{"class":106},"timer",[66,155,94],{"class":150},[66,157,118],{"class":80},[66,159,161,164,166,169,171,174,177,180,183,186,188,191,193,196,198,200,202,204],{"class":68,"line":160},5,[66,162,163],{"class":106},"    timer",[66,165,111],{"class":110},[66,167,168],{"class":76}," setTimeout",[66,170,81],{"class":150},[66,172,173],{"class":80},"()",[66,175,176],{"class":72}," =>",[66,178,179],{"class":106}," fn",[66,181,182],{"class":80},".",[66,184,185],{"class":76},"apply",[66,187,81],{"class":150},[66,189,190],{"class":114},"this",[66,192,88],{"class":80},[66,194,195],{"class":106}," args",[66,197,94],{"class":150},[66,199,88],{"class":80},[66,201,91],{"class":106},[66,203,94],{"class":150},[66,205,118],{"class":80},[66,207,209],{"class":68,"line":208},6,[66,210,211],{"class":80},"  };\n",[66,213,215],{"class":68,"line":214},7,[66,216,217],{"class":80},"}\n",[66,219,221],{"class":68,"line":220},8,[66,222,224],{"class":223},"sutJx","\u002F\u002F 立即执行版（首次立即执行，后续防抖）\n",[66,226,228,230,233,235,237,239,241,243],{"class":68,"line":227},9,[66,229,73],{"class":72},[66,231,232],{"class":76}," debounceImmediate",[66,234,81],{"class":80},[66,236,85],{"class":84},[66,238,88],{"class":80},[66,240,91],{"class":84},[66,242,94],{"class":80},[66,244,97],{"class":80},[66,246,248,250,252,254,256],{"class":68,"line":247},10,[66,249,103],{"class":72},[66,251,107],{"class":106},[66,253,111],{"class":110},[66,255,115],{"class":114},[66,257,118],{"class":80},[66,259,261,263,265,267,269,271,273],{"class":68,"line":260},11,[66,262,125],{"class":124},[66,264,128],{"class":72},[66,266,131],{"class":80},[66,268,134],{"class":110},[66,270,137],{"class":84},[66,272,94],{"class":80},[66,274,97],{"class":80},[66,276,278,281,283,285,288,290,293,295,297,299,301,303,305,307,309],{"class":68,"line":277},12,[66,279,280],{"class":124},"    if",[66,282,131],{"class":150},[66,284,153],{"class":106},[66,286,287],{"class":110}," ===",[66,289,115],{"class":114},[66,291,292],{"class":150},") ",[66,294,85],{"class":106},[66,296,182],{"class":80},[66,298,185],{"class":76},[66,300,81],{"class":150},[66,302,190],{"class":114},[66,304,88],{"class":80},[66,306,195],{"class":106},[66,308,94],{"class":150},[66,310,118],{"class":80},[66,312,314,316,318,320,322],{"class":68,"line":313},13,[66,315,147],{"class":76},[66,317,81],{"class":150},[66,319,153],{"class":106},[66,321,94],{"class":150},[66,323,118],{"class":80},[66,325,327,329,331,333,335,337,339],{"class":68,"line":326},14,[66,328,163],{"class":106},[66,330,111],{"class":110},[66,332,168],{"class":76},[66,334,81],{"class":150},[66,336,173],{"class":80},[66,338,176],{"class":72},[66,340,97],{"class":80},[66,342,344,347,349,351],{"class":68,"line":343},15,[66,345,346],{"class":106},"      timer",[66,348,111],{"class":110},[66,350,115],{"class":114},[66,352,118],{"class":80},[66,354,356,359,361,363],{"class":68,"line":355},16,[66,357,358],{"class":80},"    },",[66,360,91],{"class":106},[66,362,94],{"class":150},[66,364,118],{"class":80},[66,366,368],{"class":68,"line":367},17,[66,369,211],{"class":80},[66,371,373],{"class":68,"line":372},18,[66,374,217],{"class":80},[48,376,378],{"id":377},"节流-固定频率执行","节流 – 固定频率执行",[23,380,381],{},"应用场景：滚动事件、鼠标移动、射击游戏。",[56,383,385],{"className":58,"code":384,"language":60,"meta":61,"style":61},"\u002F\u002F 时间戳版（立即执行，停止后不执行最后一次）\nfunction throttle(fn, interval) {\n  let last = 0;\n  return function (...args) {\n    const now = Date.now();\n    if (now - last >= interval) {\n      fn.apply(this, args);\n      last = now;\n    }\n  };\n}\n\u002F\u002F 定时器版（延时执行，停止后会再执行一次）\nfunction throttleTimer(fn, interval) {\n  let timer = null;\n  return function (...args) {\n    if (timer) return;\n    timer = setTimeout(() => {\n      fn.apply(this, args);\n      timer = null;\n    }, interval);\n  };\n}\n\u002F\u002F 融合版：保证结束时还执行一次（常用）\nfunction throttleMerge(fn, interval) {\n  let last = 0,\n    timer = null;\n  return function (...args) {\n    const now = Date.now();\n    const remaining = interval - (now - last);\n    if (remaining \u003C= 0) {\n      if (timer) {\n        clearTimeout(timer);\n        timer = null;\n      }\n      fn.apply(this, args);\n      last = now;\n    } else if (!timer) {\n      timer = setTimeout(() => {\n        fn.apply(this, args);\n        last = Date.now();\n        timer = null;\n      }, remaining);\n    }\n  };\n}\n",[63,386,387,392,412,427,443,466,489,510,521,526,530,534,539,558,570,586,601,617,637,648,659,664,669,675,695,709,720,737,756,782,801,815,829,841,847,868,879,902,919,941,959,970,982,987,992],{"__ignoreMap":61},[66,388,389],{"class":68,"line":69},[66,390,391],{"class":223},"\u002F\u002F 时间戳版（立即执行，停止后不执行最后一次）\n",[66,393,394,396,399,401,403,405,408,410],{"class":68,"line":100},[66,395,73],{"class":72},[66,397,398],{"class":76}," throttle",[66,400,81],{"class":80},[66,402,85],{"class":84},[66,404,88],{"class":80},[66,406,407],{"class":84}," interval",[66,409,94],{"class":80},[66,411,97],{"class":80},[66,413,414,416,419,421,425],{"class":68,"line":121},[66,415,103],{"class":72},[66,417,418],{"class":106}," last",[66,420,111],{"class":110},[66,422,424],{"class":423},"srdBf"," 0",[66,426,118],{"class":80},[66,428,429,431,433,435,437,439,441],{"class":68,"line":144},[66,430,125],{"class":124},[66,432,128],{"class":72},[66,434,131],{"class":80},[66,436,134],{"class":110},[66,438,137],{"class":84},[66,440,94],{"class":80},[66,442,97],{"class":80},[66,444,445,448,452,454,457,459,462,464],{"class":68,"line":160},[66,446,447],{"class":72},"    const",[66,449,451],{"class":450},"s_hVV"," now",[66,453,111],{"class":110},[66,455,456],{"class":106}," Date",[66,458,182],{"class":80},[66,460,461],{"class":76},"now",[66,463,173],{"class":150},[66,465,118],{"class":80},[66,467,468,470,472,474,477,479,482,484,486],{"class":68,"line":208},[66,469,280],{"class":124},[66,471,131],{"class":150},[66,473,461],{"class":106},[66,475,476],{"class":110}," -",[66,478,418],{"class":106},[66,480,481],{"class":110}," >=",[66,483,407],{"class":106},[66,485,292],{"class":150},[66,487,488],{"class":80},"{\n",[66,490,491,494,496,498,500,502,504,506,508],{"class":68,"line":214},[66,492,493],{"class":106},"      fn",[66,495,182],{"class":80},[66,497,185],{"class":76},[66,499,81],{"class":150},[66,501,190],{"class":114},[66,503,88],{"class":80},[66,505,195],{"class":106},[66,507,94],{"class":150},[66,509,118],{"class":80},[66,511,512,515,517,519],{"class":68,"line":220},[66,513,514],{"class":106},"      last",[66,516,111],{"class":110},[66,518,451],{"class":106},[66,520,118],{"class":80},[66,522,523],{"class":68,"line":227},[66,524,525],{"class":80},"    }\n",[66,527,528],{"class":68,"line":247},[66,529,211],{"class":80},[66,531,532],{"class":68,"line":260},[66,533,217],{"class":80},[66,535,536],{"class":68,"line":277},[66,537,538],{"class":223},"\u002F\u002F 定时器版（延时执行，停止后会再执行一次）\n",[66,540,541,543,546,548,550,552,554,556],{"class":68,"line":313},[66,542,73],{"class":72},[66,544,545],{"class":76}," throttleTimer",[66,547,81],{"class":80},[66,549,85],{"class":84},[66,551,88],{"class":80},[66,553,407],{"class":84},[66,555,94],{"class":80},[66,557,97],{"class":80},[66,559,560,562,564,566,568],{"class":68,"line":326},[66,561,103],{"class":72},[66,563,107],{"class":106},[66,565,111],{"class":110},[66,567,115],{"class":114},[66,569,118],{"class":80},[66,571,572,574,576,578,580,582,584],{"class":68,"line":343},[66,573,125],{"class":124},[66,575,128],{"class":72},[66,577,131],{"class":80},[66,579,134],{"class":110},[66,581,137],{"class":84},[66,583,94],{"class":80},[66,585,97],{"class":80},[66,587,588,590,592,594,596,599],{"class":68,"line":355},[66,589,280],{"class":124},[66,591,131],{"class":150},[66,593,153],{"class":106},[66,595,292],{"class":150},[66,597,598],{"class":124},"return",[66,600,118],{"class":80},[66,602,603,605,607,609,611,613,615],{"class":68,"line":367},[66,604,163],{"class":106},[66,606,111],{"class":110},[66,608,168],{"class":76},[66,610,81],{"class":150},[66,612,173],{"class":80},[66,614,176],{"class":72},[66,616,97],{"class":80},[66,618,619,621,623,625,627,629,631,633,635],{"class":68,"line":372},[66,620,493],{"class":106},[66,622,182],{"class":80},[66,624,185],{"class":76},[66,626,81],{"class":150},[66,628,190],{"class":114},[66,630,88],{"class":80},[66,632,195],{"class":106},[66,634,94],{"class":150},[66,636,118],{"class":80},[66,638,640,642,644,646],{"class":68,"line":639},19,[66,641,346],{"class":106},[66,643,111],{"class":110},[66,645,115],{"class":114},[66,647,118],{"class":80},[66,649,651,653,655,657],{"class":68,"line":650},20,[66,652,358],{"class":80},[66,654,407],{"class":106},[66,656,94],{"class":150},[66,658,118],{"class":80},[66,660,662],{"class":68,"line":661},21,[66,663,211],{"class":80},[66,665,667],{"class":68,"line":666},22,[66,668,217],{"class":80},[66,670,672],{"class":68,"line":671},23,[66,673,674],{"class":223},"\u002F\u002F 融合版：保证结束时还执行一次（常用）\n",[66,676,678,680,683,685,687,689,691,693],{"class":68,"line":677},24,[66,679,73],{"class":72},[66,681,682],{"class":76}," throttleMerge",[66,684,81],{"class":80},[66,686,85],{"class":84},[66,688,88],{"class":80},[66,690,407],{"class":84},[66,692,94],{"class":80},[66,694,97],{"class":80},[66,696,698,700,702,704,706],{"class":68,"line":697},25,[66,699,103],{"class":72},[66,701,418],{"class":106},[66,703,111],{"class":110},[66,705,424],{"class":423},[66,707,708],{"class":80},",\n",[66,710,712,714,716,718],{"class":68,"line":711},26,[66,713,163],{"class":106},[66,715,111],{"class":110},[66,717,115],{"class":114},[66,719,118],{"class":80},[66,721,723,725,727,729,731,733,735],{"class":68,"line":722},27,[66,724,125],{"class":124},[66,726,128],{"class":72},[66,728,131],{"class":80},[66,730,134],{"class":110},[66,732,137],{"class":84},[66,734,94],{"class":80},[66,736,97],{"class":80},[66,738,740,742,744,746,748,750,752,754],{"class":68,"line":739},28,[66,741,447],{"class":72},[66,743,451],{"class":450},[66,745,111],{"class":110},[66,747,456],{"class":106},[66,749,182],{"class":80},[66,751,461],{"class":76},[66,753,173],{"class":150},[66,755,118],{"class":80},[66,757,759,761,764,766,768,770,772,774,776,778,780],{"class":68,"line":758},29,[66,760,447],{"class":72},[66,762,763],{"class":450}," remaining",[66,765,111],{"class":110},[66,767,407],{"class":106},[66,769,476],{"class":110},[66,771,131],{"class":150},[66,773,461],{"class":106},[66,775,476],{"class":110},[66,777,418],{"class":106},[66,779,94],{"class":150},[66,781,118],{"class":80},[66,783,785,787,789,792,795,797,799],{"class":68,"line":784},30,[66,786,280],{"class":124},[66,788,131],{"class":150},[66,790,791],{"class":106},"remaining",[66,793,794],{"class":110}," \u003C=",[66,796,424],{"class":423},[66,798,292],{"class":150},[66,800,488],{"class":80},[66,802,804,807,809,811,813],{"class":68,"line":803},31,[66,805,806],{"class":124},"      if",[66,808,131],{"class":150},[66,810,153],{"class":106},[66,812,292],{"class":150},[66,814,488],{"class":80},[66,816,818,821,823,825,827],{"class":68,"line":817},32,[66,819,820],{"class":76},"        clearTimeout",[66,822,81],{"class":150},[66,824,153],{"class":106},[66,826,94],{"class":150},[66,828,118],{"class":80},[66,830,832,835,837,839],{"class":68,"line":831},33,[66,833,834],{"class":106},"        timer",[66,836,111],{"class":110},[66,838,115],{"class":114},[66,840,118],{"class":80},[66,842,844],{"class":68,"line":843},34,[66,845,846],{"class":80},"      }\n",[66,848,850,852,854,856,858,860,862,864,866],{"class":68,"line":849},35,[66,851,493],{"class":106},[66,853,182],{"class":80},[66,855,185],{"class":76},[66,857,81],{"class":150},[66,859,190],{"class":114},[66,861,88],{"class":80},[66,863,195],{"class":106},[66,865,94],{"class":150},[66,867,118],{"class":80},[66,869,871,873,875,877],{"class":68,"line":870},36,[66,872,514],{"class":106},[66,874,111],{"class":110},[66,876,451],{"class":106},[66,878,118],{"class":80},[66,880,882,885,888,891,893,896,898,900],{"class":68,"line":881},37,[66,883,884],{"class":80},"    }",[66,886,887],{"class":124}," else",[66,889,890],{"class":124}," if",[66,892,131],{"class":150},[66,894,895],{"class":110},"!",[66,897,153],{"class":106},[66,899,292],{"class":150},[66,901,488],{"class":80},[66,903,905,907,909,911,913,915,917],{"class":68,"line":904},38,[66,906,346],{"class":106},[66,908,111],{"class":110},[66,910,168],{"class":76},[66,912,81],{"class":150},[66,914,173],{"class":80},[66,916,176],{"class":72},[66,918,97],{"class":80},[66,920,922,925,927,929,931,933,935,937,939],{"class":68,"line":921},39,[66,923,924],{"class":106},"        fn",[66,926,182],{"class":80},[66,928,185],{"class":76},[66,930,81],{"class":150},[66,932,190],{"class":114},[66,934,88],{"class":80},[66,936,195],{"class":106},[66,938,94],{"class":150},[66,940,118],{"class":80},[66,942,944,947,949,951,953,955,957],{"class":68,"line":943},40,[66,945,946],{"class":106},"        last",[66,948,111],{"class":110},[66,950,456],{"class":106},[66,952,182],{"class":80},[66,954,461],{"class":76},[66,956,173],{"class":150},[66,958,118],{"class":80},[66,960,962,964,966,968],{"class":68,"line":961},41,[66,963,834],{"class":106},[66,965,111],{"class":110},[66,967,115],{"class":114},[66,969,118],{"class":80},[66,971,973,976,978,980],{"class":68,"line":972},42,[66,974,975],{"class":80},"      },",[66,977,763],{"class":106},[66,979,94],{"class":150},[66,981,118],{"class":80},[66,983,985],{"class":68,"line":984},43,[66,986,525],{"class":80},[66,988,990],{"class":68,"line":989},44,[66,991,211],{"class":80},[66,993,995],{"class":68,"line":994},45,[66,996,217],{"class":80},[43,998,1000],{"id":999},"_2-避免内存泄漏","2. 避免内存泄漏",[1002,1003,1004,1020],"table",{},[1005,1006,1007],"thead",{},[1008,1009,1010,1014,1017],"tr",{},[1011,1012,1013],"th",{},"常见泄漏源",[1011,1015,1016],{},"示例",[1011,1018,1019],{},"解决方案",[1021,1022,1023,1047,1066,1085,1102,1117,1136],"tbody",{},[1008,1024,1025,1032,1037],{},[1026,1027,1028],"td",{},[1029,1030,1031],"strong",{},"意外的全局变量",[1026,1033,1034],{},[63,1035,1036],{},"function foo() { a = 1; }",[1026,1038,1039,1040,1043,1044],{},"使用 ",[63,1041,1042],{},"'use strict'","，始终声明变量 ",[63,1045,1046],{},"let\u002Fconst\u002Fvar",[1008,1048,1049,1054,1060],{},[1026,1050,1051],{},[1029,1052,1053],{},"未清理的定时器",[1026,1055,1056,1059],{},[63,1057,1058],{},"setInterval(() => {...}, 1000)"," 未清除",[1026,1061,1062,1063],{},"在组件卸载或不需要时 ",[63,1064,1065],{},"clearInterval\u002FclearTimeout",[1008,1067,1068,1073,1078],{},[1026,1069,1070],{},[1029,1071,1072],{},"未移除的事件监听",[1026,1074,1075],{},[63,1076,1077],{},"window.addEventListener('resize', handler)",[1026,1079,1080,1081,1084],{},"提供对应的 ",[63,1082,1083],{},"removeEventListener","，尤其在 SPA 路由切换时",[1008,1086,1087,1092,1095],{},[1026,1088,1089],{},[1029,1090,1091],{},"闭包引用过大",[1026,1093,1094],{},"闭包持有大数组或 DOM 元素",[1026,1096,1097,1098,1101],{},"将不需要的变量设为 ",[63,1099,1100],{},"null","，避免长期持有",[1008,1103,1104,1109,1112],{},[1026,1105,1106],{},[1029,1107,1108],{},"DOM 引用未清",[1026,1110,1111],{},"在 JS 中保存已删除 DOM 节点的引用",[1026,1113,1114,1115],{},"删除节点前先置引用为 ",[63,1116,1100],{},[1008,1118,1119,1124,1130],{},[1026,1120,1121],{},[1029,1122,1123],{},"脱离 DOM 树但被 JS 引用",[1026,1125,1126,1129],{},[63,1127,1128],{},"let elem = document.getElementById('btn'); elem.remove();"," 但变量仍存在",[1026,1131,1132,1133],{},"主动 ",[63,1134,1135],{},"elem = null",[1008,1137,1138,1143,1150],{},[1026,1139,1140],{},[1029,1141,1142],{},"Map\u002FSet 未清除",[1026,1144,1145,1146,1149],{},"使用普通 ",[63,1147,1148],{},"Map"," 存储 DOM 节点，节点删除后 Map 仍持有",[1026,1151,1039,1152,1155,1156,1159],{},[63,1153,1154],{},"WeakMap"," \u002F ",[63,1157,1158],{},"WeakSet"," 自动弱引用",[43,1161,1163],{"id":1162},"_3-重排reflow与重绘repaint的触发与优化","3. 重排（Reflow）与重绘（Repaint）的触发与优化",[1165,1166,1167,1178],"ul",{},[1168,1169,1170,1173,1174,1177],"li",{},[1029,1171,1172],{},"重排（reflow）","：布局几何属性变化（宽高、边距、位置、字体、添加\u002F删除 DOM、窗口 resize、获取 ",[63,1175,1176],{},"offsetWidth"," 等）→ 重新计算布局树。",[1168,1179,1180,1183],{},[1029,1181,1182],{},"重绘（repaint）","：视觉样式变化（背景色、颜色、可见性）但不影响布局 → 仅重新绘制。",[23,1185,1186,1189],{},[1029,1187,1188],{},"优化原则","：",[1165,1191,1192,1202,1213,1220,1230,1236],{},[1168,1193,1194,1195,1198,1199,36],{},"避免逐条修改样式，使用 ",[63,1196,1197],{},"class"," 或 ",[63,1200,1201],{},"cssText",[1168,1203,1204,1205,1208,1209,1212],{},"使元素脱离文档流（",[63,1206,1207],{},"position: absolute\u002Ffixed","，",[63,1210,1211],{},"display: none","）进行批量 DOM 操作。",[1168,1214,1215,1216,1219],{},"避免频繁读取布局属性（如 ",[63,1217,1218],{},"offsetTop","），改用变量缓存。",[1168,1221,1222,1223,31,1226,1229],{},"复杂动画使用 ",[63,1224,1225],{},"transform",[63,1227,1228],{},"opacity","（只触发合成，不触发重排\u002F重绘）。",[1168,1231,1039,1232,1235],{},[63,1233,1234],{},"documentFragment"," 批量更新 DOM。",[1168,1237,1238,1239,1242],{},"将动画效果应用到 ",[63,1240,1241],{},"position: fixed\u002Fabsolute"," 元素上。",[56,1244,1246],{"className":58,"code":1245,"language":60,"meta":61,"style":61},"\u002F\u002F 坏\nfor (let i = 0; i \u003C 1000; i++) {\n  element.style.left = i + \"px\"; \u002F\u002F 每次触发重排\n}\n\u002F\u002F 好 - 使用 transform\nelement.style.transform = `translateX(1000px)`;\n",[63,1247,1248,1253,1294,1332,1336,1341],{"__ignoreMap":61},[66,1249,1250],{"class":68,"line":69},[66,1251,1252],{"class":223},"\u002F\u002F 坏\n",[66,1254,1255,1258,1260,1263,1266,1269,1271,1274,1276,1279,1282,1284,1287,1290,1292],{"class":68,"line":100},[66,1256,1257],{"class":124},"for",[66,1259,131],{"class":106},[66,1261,1262],{"class":72},"let",[66,1264,1265],{"class":106}," i ",[66,1267,1268],{"class":110},"=",[66,1270,424],{"class":423},[66,1272,1273],{"class":80},";",[66,1275,1265],{"class":106},[66,1277,1278],{"class":110},"\u003C",[66,1280,1281],{"class":423}," 1000",[66,1283,1273],{"class":80},[66,1285,1286],{"class":106}," i",[66,1288,1289],{"class":110},"++",[66,1291,292],{"class":106},[66,1293,488],{"class":80},[66,1295,1296,1299,1301,1304,1306,1309,1311,1313,1316,1320,1324,1327,1329],{"class":68,"line":121},[66,1297,1298],{"class":106},"  element",[66,1300,182],{"class":80},[66,1302,1303],{"class":106},"style",[66,1305,182],{"class":80},[66,1307,1308],{"class":106},"left",[66,1310,111],{"class":110},[66,1312,1286],{"class":106},[66,1314,1315],{"class":110}," +",[66,1317,1319],{"class":1318},"sjJ54"," \"",[66,1321,1323],{"class":1322},"s_sjI","px",[66,1325,1326],{"class":1318},"\"",[66,1328,1273],{"class":80},[66,1330,1331],{"class":223}," \u002F\u002F 每次触发重排\n",[66,1333,1334],{"class":68,"line":144},[66,1335,217],{"class":80},[66,1337,1338],{"class":68,"line":160},[66,1339,1340],{"class":223},"\u002F\u002F 好 - 使用 transform\n",[66,1342,1343,1346,1348,1350,1352,1355,1357,1360,1363,1366],{"class":68,"line":208},[66,1344,1345],{"class":106},"element",[66,1347,182],{"class":80},[66,1349,1303],{"class":106},[66,1351,182],{"class":80},[66,1353,1354],{"class":106},"transform ",[66,1356,1268],{"class":110},[66,1358,1359],{"class":1318}," `",[66,1361,1362],{"class":1322},"translateX(1000px)",[66,1364,1365],{"class":1318},"`",[66,1367,118],{"class":80},[43,1369,1371],{"id":1370},"_4-函数节流防抖-requestanimationframe-动画最佳实践","4. 函数节流\u002F防抖 + requestAnimationFrame 动画最佳实践",[1165,1373,1374],{},[1168,1375,1376,1379,1380,1383],{},[1029,1377,1378],{},"滚动事件","：用 ",[63,1381,1382],{},"requestAnimationFrame"," 合并样式修改，避免过度触发。",[56,1385,1387],{"className":58,"code":1386,"language":60,"meta":61,"style":61},"let ticking = false;\nwindow.addEventListener(\"scroll\", () => {\n  if (!ticking) {\n    requestAnimationFrame(() => {\n      \u002F\u002F 更新样式或处理\n      ticking = false;\n    });\n    ticking = true;\n  }\n});\n",[63,1388,1389,1404,1432,1448,1461,1466,1477,1485,1497,1502],{"__ignoreMap":61},[66,1390,1391,1393,1396,1398,1402],{"class":68,"line":69},[66,1392,1262],{"class":72},[66,1394,1395],{"class":106}," ticking ",[66,1397,1268],{"class":110},[66,1399,1401],{"class":1400},"syTEX"," false",[66,1403,118],{"class":80},[66,1405,1406,1409,1411,1414,1416,1418,1421,1423,1425,1428,1430],{"class":68,"line":100},[66,1407,1408],{"class":106},"window",[66,1410,182],{"class":80},[66,1412,1413],{"class":76},"addEventListener",[66,1415,81],{"class":106},[66,1417,1326],{"class":1318},[66,1419,1420],{"class":1322},"scroll",[66,1422,1326],{"class":1318},[66,1424,88],{"class":80},[66,1426,1427],{"class":80}," ()",[66,1429,176],{"class":72},[66,1431,97],{"class":80},[66,1433,1434,1437,1439,1441,1444,1446],{"class":68,"line":121},[66,1435,1436],{"class":124},"  if",[66,1438,131],{"class":150},[66,1440,895],{"class":110},[66,1442,1443],{"class":106},"ticking",[66,1445,292],{"class":150},[66,1447,488],{"class":80},[66,1449,1450,1453,1455,1457,1459],{"class":68,"line":144},[66,1451,1452],{"class":76},"    requestAnimationFrame",[66,1454,81],{"class":150},[66,1456,173],{"class":80},[66,1458,176],{"class":72},[66,1460,97],{"class":80},[66,1462,1463],{"class":68,"line":160},[66,1464,1465],{"class":223},"      \u002F\u002F 更新样式或处理\n",[66,1467,1468,1471,1473,1475],{"class":68,"line":208},[66,1469,1470],{"class":106},"      ticking",[66,1472,111],{"class":110},[66,1474,1401],{"class":1400},[66,1476,118],{"class":80},[66,1478,1479,1481,1483],{"class":68,"line":214},[66,1480,884],{"class":80},[66,1482,94],{"class":150},[66,1484,118],{"class":80},[66,1486,1487,1490,1492,1495],{"class":68,"line":220},[66,1488,1489],{"class":106},"    ticking",[66,1491,111],{"class":110},[66,1493,1494],{"class":1400}," true",[66,1496,118],{"class":80},[66,1498,1499],{"class":68,"line":227},[66,1500,1501],{"class":80},"  }\n",[66,1503,1504,1507,1509],{"class":68,"line":247},[66,1505,1506],{"class":80},"}",[66,1508,94],{"class":106},[66,1510,118],{"class":80},[1165,1512,1513,1526],{},[1168,1514,1515,1518,1519,1521,1522,1525],{},[1029,1516,1517],{},"动画循环","：始终使用 ",[63,1520,1382],{}," 而非 ",[63,1523,1524],{},"setInterval","，它匹配屏幕刷新率，且在页面不可见时停止，节省资源。",[1168,1527,1528,1531,1532,1535],{},[1029,1529,1530],{},"配合节流","：限制高频率事件（如 ",[63,1533,1534],{},"mousemove","）的回调中执行复杂操作，但动画更新本身仍用 rAF。",[56,1537,1539],{"className":58,"code":1538,"language":60,"meta":61,"style":61},"let lastTimestamp = 0;\nfunction onMouseMove(e) {\n  throttle(() => {\n    requestAnimationFrame(() => updatePosition(e.clientX, e.clientY));\n  }, 16);\n}\n",[63,1540,1541,1554,1570,1583,1620,1632],{"__ignoreMap":61},[66,1542,1543,1545,1548,1550,1552],{"class":68,"line":69},[66,1544,1262],{"class":72},[66,1546,1547],{"class":106}," lastTimestamp ",[66,1549,1268],{"class":110},[66,1551,424],{"class":423},[66,1553,118],{"class":80},[66,1555,1556,1558,1561,1563,1566,1568],{"class":68,"line":100},[66,1557,73],{"class":72},[66,1559,1560],{"class":76}," onMouseMove",[66,1562,81],{"class":80},[66,1564,1565],{"class":84},"e",[66,1567,94],{"class":80},[66,1569,97],{"class":80},[66,1571,1572,1575,1577,1579,1581],{"class":68,"line":121},[66,1573,1574],{"class":76},"  throttle",[66,1576,81],{"class":150},[66,1578,173],{"class":80},[66,1580,176],{"class":72},[66,1582,97],{"class":80},[66,1584,1585,1587,1589,1591,1593,1596,1598,1600,1602,1605,1607,1610,1612,1615,1618],{"class":68,"line":144},[66,1586,1452],{"class":76},[66,1588,81],{"class":150},[66,1590,173],{"class":80},[66,1592,176],{"class":72},[66,1594,1595],{"class":76}," updatePosition",[66,1597,81],{"class":150},[66,1599,1565],{"class":106},[66,1601,182],{"class":80},[66,1603,1604],{"class":106},"clientX",[66,1606,88],{"class":80},[66,1608,1609],{"class":106}," e",[66,1611,182],{"class":80},[66,1613,1614],{"class":106},"clientY",[66,1616,1617],{"class":150},"))",[66,1619,118],{"class":80},[66,1621,1622,1625,1628,1630],{"class":68,"line":160},[66,1623,1624],{"class":80},"  },",[66,1626,1627],{"class":423}," 16",[66,1629,94],{"class":150},[66,1631,118],{"class":80},[66,1633,1634],{"class":68,"line":208},[66,1635,217],{"class":80},[38,1637,1639],{"id":1638},"二网络优化","二、网络优化",[43,1641,1643],{"id":1642},"_1-资源预加载指令","1. 资源预加载指令",[1002,1645,1646,1659],{},[1005,1647,1648],{},[1008,1649,1650,1653,1656],{},[1011,1651,1652],{},"指令",[1011,1654,1655],{},"作用",[1011,1657,1658],{},"典型场景",[1021,1660,1661,1674,1687,1700],{},[1008,1662,1663,1668,1671],{},[1026,1664,1665],{},[63,1666,1667],{},"\u003Clink rel=\"preload\" href=\"...\" as=\"...\">",[1026,1669,1670],{},"提前加载当前页面必需资源（高优先级）",[1026,1672,1673],{},"字体、关键 CSS\u002FJS、大图",[1008,1675,1676,1681,1684],{},[1026,1677,1678],{},[63,1679,1680],{},"\u003Clink rel=\"prefetch\" href=\"...\">",[1026,1682,1683],{},"预取下一页资源（低优先级，空闲时加载）",[1026,1685,1686],{},"路由懒加载的下一屏模块",[1008,1688,1689,1694,1697],{},[1026,1690,1691],{},[63,1692,1693],{},"\u003Clink rel=\"preconnect\" href=\"https:\u002F\u002F...\">",[1026,1695,1696],{},"提前建立 TCP+TLS 连接",[1026,1698,1699],{},"跨域 API 域名、CDN",[1008,1701,1702,1707,1710],{},[1026,1703,1704],{},[63,1705,1706],{},"\u003Clink rel=\"dns-prefetch\" href=\"...\">",[1026,1708,1709],{},"提前做 DNS 解析",[1026,1711,1712],{},"第三方资源域名",[23,1714,1715,1716,1719,1720,1723],{},"注意：",[63,1717,1718],{},"preload"," 要配合 ",[63,1721,1722],{},"as"," 属性正确设置，否则可能二次加载。",[43,1725,1727],{"id":1726},"_2-http2-多路复用与压缩","2. HTTP\u002F2 多路复用与压缩",[1165,1729,1730,1736],{},[1168,1731,1732,1735],{},[1029,1733,1734],{},"HTTP\u002F2 多路复用","：单一连接上并发传输多个请求和响应，消除队头阻塞（应用层）。提升复用 TCP 连接效率，配合服务器推送可主动发送资源。",[1168,1737,1738,1741,1742],{},[1029,1739,1740],{},"压缩算法","：\n",[1165,1743,1744,1750,1756],{},[1168,1745,1746,1749],{},[1029,1747,1748],{},"Gzip","：广泛支持，压缩比中等。",[1168,1751,1752,1755],{},[1029,1753,1754],{},"Brotli","：压缩比更高，尤其文本资源（JS\u002FCSS\u002FHTML），比 gzip 小 20%~30%。现代浏览器和服务器（Nginx、CDN）均支持。",[1168,1757,1758,1759,1198,1762,36],{},"启用方法：",[63,1760,1761],{},"Content-Encoding: br",[63,1763,1764],{},"gzip",[43,1766,1768],{"id":1767},"_3-图片懒加载与响应式图片","3. 图片懒加载与响应式图片",[48,1770,1771],{"id":1771},"懒加载",[1165,1773,1774,1783],{},[1168,1775,1039,1776,1779,1780,36],{},[63,1777,1778],{},"IntersectionObserver"," 监听图片进入视口，替换 ",[63,1781,1782],{},"src",[1168,1784,1785,1786,1789],{},"原生懒加载：",[63,1787,1788],{},"\u003Cimg loading=\"lazy\">","（兼容性好，但精细控制可用 JS）。",[56,1791,1793],{"className":58,"code":1792,"language":60,"meta":61,"style":61},"const imgObserver = new IntersectionObserver((entries) => {\n  entries.forEach((entry) => {\n    if (entry.isIntersecting) {\n      const img = entry.target;\n      img.src = img.dataset.src;\n      imgObserver.unobserve(img);\n    }\n  });\n});\ndocument.querySelectorAll(\"img[data-src]\").forEach((img) => imgObserver.observe(img));\n",[63,1794,1795,1824,1847,1864,1884,1908,1927,1931,1940,1948],{"__ignoreMap":61},[66,1796,1797,1800,1803,1805,1808,1811,1813,1815,1818,1820,1822],{"class":68,"line":69},[66,1798,1799],{"class":72},"const",[66,1801,1802],{"class":450}," imgObserver",[66,1804,111],{"class":110},[66,1806,1807],{"class":110}," new",[66,1809,1810],{"class":76}," IntersectionObserver",[66,1812,81],{"class":106},[66,1814,81],{"class":80},[66,1816,1817],{"class":84},"entries",[66,1819,94],{"class":80},[66,1821,176],{"class":72},[66,1823,97],{"class":80},[66,1825,1826,1829,1831,1834,1836,1838,1841,1843,1845],{"class":68,"line":100},[66,1827,1828],{"class":106},"  entries",[66,1830,182],{"class":80},[66,1832,1833],{"class":76},"forEach",[66,1835,81],{"class":150},[66,1837,81],{"class":80},[66,1839,1840],{"class":84},"entry",[66,1842,94],{"class":80},[66,1844,176],{"class":72},[66,1846,97],{"class":80},[66,1848,1849,1851,1853,1855,1857,1860,1862],{"class":68,"line":121},[66,1850,280],{"class":124},[66,1852,131],{"class":150},[66,1854,1840],{"class":106},[66,1856,182],{"class":80},[66,1858,1859],{"class":106},"isIntersecting",[66,1861,292],{"class":150},[66,1863,488],{"class":80},[66,1865,1866,1869,1872,1874,1877,1879,1882],{"class":68,"line":144},[66,1867,1868],{"class":72},"      const",[66,1870,1871],{"class":450}," img",[66,1873,111],{"class":110},[66,1875,1876],{"class":106}," entry",[66,1878,182],{"class":80},[66,1880,1881],{"class":106},"target",[66,1883,118],{"class":80},[66,1885,1886,1889,1891,1893,1895,1897,1899,1902,1904,1906],{"class":68,"line":160},[66,1887,1888],{"class":106},"      img",[66,1890,182],{"class":80},[66,1892,1782],{"class":106},[66,1894,111],{"class":110},[66,1896,1871],{"class":106},[66,1898,182],{"class":80},[66,1900,1901],{"class":106},"dataset",[66,1903,182],{"class":80},[66,1905,1782],{"class":106},[66,1907,118],{"class":80},[66,1909,1910,1913,1915,1918,1920,1923,1925],{"class":68,"line":208},[66,1911,1912],{"class":106},"      imgObserver",[66,1914,182],{"class":80},[66,1916,1917],{"class":76},"unobserve",[66,1919,81],{"class":150},[66,1921,1922],{"class":106},"img",[66,1924,94],{"class":150},[66,1926,118],{"class":80},[66,1928,1929],{"class":68,"line":214},[66,1930,525],{"class":80},[66,1932,1933,1936,1938],{"class":68,"line":220},[66,1934,1935],{"class":80},"  }",[66,1937,94],{"class":150},[66,1939,118],{"class":80},[66,1941,1942,1944,1946],{"class":68,"line":227},[66,1943,1506],{"class":80},[66,1945,94],{"class":106},[66,1947,118],{"class":80},[66,1949,1950,1953,1955,1958,1960,1962,1965,1967,1969,1971,1973,1975,1977,1979,1981,1983,1985,1987,1990,1993],{"class":68,"line":247},[66,1951,1952],{"class":106},"document",[66,1954,182],{"class":80},[66,1956,1957],{"class":76},"querySelectorAll",[66,1959,81],{"class":106},[66,1961,1326],{"class":1318},[66,1963,1964],{"class":1322},"img[data-src]",[66,1966,1326],{"class":1318},[66,1968,94],{"class":106},[66,1970,182],{"class":80},[66,1972,1833],{"class":76},[66,1974,81],{"class":106},[66,1976,81],{"class":80},[66,1978,1922],{"class":84},[66,1980,94],{"class":80},[66,1982,176],{"class":72},[66,1984,1802],{"class":106},[66,1986,182],{"class":80},[66,1988,1989],{"class":76},"observe",[66,1991,1992],{"class":106},"(img))",[66,1994,118],{"class":80},[48,1996,1997],{"id":1997},"响应式图片",[1165,1999,2000],{},[1168,2001,2002,2005,2006,2009],{},[63,2003,2004],{},"srcset"," + ",[63,2007,2008],{},"sizes","：根据屏幕宽度选择不同尺寸。",[56,2011,2015],{"className":2012,"code":2013,"language":2014,"meta":61,"style":61},"language-html shiki shiki-themes material-theme-lighter github-light github-dark","\u003Cimg\n  srcset=\"small.jpg 480w, medium.jpg 800w, large.jpg 1200w\"\n  sizes=\"(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px\"\n  src=\"fallback.jpg\"\n  alt=\"...\"\n\u002F>\n","html",[63,2016,2017,2025,2041,2055,2069,2082],{"__ignoreMap":61},[66,2018,2019,2021],{"class":68,"line":69},[66,2020,1278],{"class":80},[66,2022,2024],{"class":2023},"sQzsp","img\n",[66,2026,2027,2031,2033,2035,2038],{"class":68,"line":100},[66,2028,2030],{"class":2029},"s9AJx","  srcset",[66,2032,1268],{"class":80},[66,2034,1326],{"class":1318},[66,2036,2037],{"class":1322},"small.jpg 480w, medium.jpg 800w, large.jpg 1200w",[66,2039,2040],{"class":1318},"\"\n",[66,2042,2043,2046,2048,2050,2053],{"class":68,"line":121},[66,2044,2045],{"class":2029},"  sizes",[66,2047,1268],{"class":80},[66,2049,1326],{"class":1318},[66,2051,2052],{"class":1322},"(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px",[66,2054,2040],{"class":1318},[66,2056,2057,2060,2062,2064,2067],{"class":68,"line":144},[66,2058,2059],{"class":2029},"  src",[66,2061,1268],{"class":80},[66,2063,1326],{"class":1318},[66,2065,2066],{"class":1322},"fallback.jpg",[66,2068,2040],{"class":1318},[66,2070,2071,2074,2076,2078,2080],{"class":68,"line":160},[66,2072,2073],{"class":2029},"  alt",[66,2075,1268],{"class":80},[66,2077,1326],{"class":1318},[66,2079,134],{"class":1322},[66,2081,2040],{"class":1318},[66,2083,2084],{"class":68,"line":208},[66,2085,2086],{"class":80},"\u002F>\n",[1165,2088,2089],{},[1168,2090,2091,2094],{},[63,2092,2093],{},"\u003Cpicture>"," 元素：根据媒体查询或格式支持选择（如 WebP\u002FAVIF）。",[56,2096,2098],{"className":2012,"code":2097,"language":2014,"meta":61,"style":61},"\u003Cpicture>\n  \u003Csource srcset=\"image.avif\" type=\"image\u002Favif\" \u002F>\n  \u003Csource srcset=\"image.webp\" type=\"image\u002Fwebp\" \u002F>\n  \u003Cimg src=\"image.jpg\" alt=\"\" \u002F>\n\u003C\u002Fpicture>\n",[63,2099,2100,2110,2145,2175,2203],{"__ignoreMap":61},[66,2101,2102,2104,2107],{"class":68,"line":69},[66,2103,1278],{"class":80},[66,2105,2106],{"class":2023},"picture",[66,2108,2109],{"class":80},">\n",[66,2111,2112,2115,2118,2121,2123,2125,2128,2130,2133,2135,2137,2140,2142],{"class":68,"line":100},[66,2113,2114],{"class":80},"  \u003C",[66,2116,2117],{"class":2023},"source",[66,2119,2120],{"class":2029}," srcset",[66,2122,1268],{"class":80},[66,2124,1326],{"class":1318},[66,2126,2127],{"class":1322},"image.avif",[66,2129,1326],{"class":1318},[66,2131,2132],{"class":2029}," type",[66,2134,1268],{"class":80},[66,2136,1326],{"class":1318},[66,2138,2139],{"class":1322},"image\u002Favif",[66,2141,1326],{"class":1318},[66,2143,2144],{"class":80}," \u002F>\n",[66,2146,2147,2149,2151,2153,2155,2157,2160,2162,2164,2166,2168,2171,2173],{"class":68,"line":121},[66,2148,2114],{"class":80},[66,2150,2117],{"class":2023},[66,2152,2120],{"class":2029},[66,2154,1268],{"class":80},[66,2156,1326],{"class":1318},[66,2158,2159],{"class":1322},"image.webp",[66,2161,1326],{"class":1318},[66,2163,2132],{"class":2029},[66,2165,1268],{"class":80},[66,2167,1326],{"class":1318},[66,2169,2170],{"class":1322},"image\u002Fwebp",[66,2172,1326],{"class":1318},[66,2174,2144],{"class":80},[66,2176,2177,2179,2181,2184,2186,2188,2191,2193,2196,2198,2201],{"class":68,"line":144},[66,2178,2114],{"class":80},[66,2180,1922],{"class":2023},[66,2182,2183],{"class":2029}," src",[66,2185,1268],{"class":80},[66,2187,1326],{"class":1318},[66,2189,2190],{"class":1322},"image.jpg",[66,2192,1326],{"class":1318},[66,2194,2195],{"class":2029}," alt",[66,2197,1268],{"class":80},[66,2199,2200],{"class":1318},"\"\"",[66,2202,2144],{"class":80},[66,2204,2205,2208,2210],{"class":68,"line":160},[66,2206,2207],{"class":80},"\u003C\u002F",[66,2209,2106],{"class":2023},[66,2211,2109],{"class":80},[38,2213,2215],{"id":2214},"三运行时优化v8-引擎原理","三、运行时优化：V8 引擎原理",[23,2217,2218],{},"V8 是 Chrome 和 Node.js 中的 JavaScript 引擎，理解其内部机制有助于写出高性能代码。",[43,2220,2222],{"id":2221},"_1-隐式类型转换","1. 隐式类型转换",[23,2224,2225],{},"在需要类型时，JS 会自动转换，但会降低性能并可能导致意外。",[56,2227,2229],{"className":58,"code":2228,"language":60,"meta":61,"style":61},"\u002F\u002F 坏：触发类型转换，且可能无法优化\nconst total = 100 + \"100\"; \u002F\u002F \"100100\"\n\u002F\u002F 好：保持类型一致\nconst total = 100 + Number(\"100\");\n",[63,2230,2231,2236,2262,2267],{"__ignoreMap":61},[66,2232,2233],{"class":68,"line":69},[66,2234,2235],{"class":223},"\u002F\u002F 坏：触发类型转换，且可能无法优化\n",[66,2237,2238,2240,2243,2245,2248,2250,2252,2255,2257,2259],{"class":68,"line":100},[66,2239,1799],{"class":72},[66,2241,2242],{"class":450}," total",[66,2244,111],{"class":110},[66,2246,2247],{"class":423}," 100",[66,2249,1315],{"class":110},[66,2251,1319],{"class":1318},[66,2253,2254],{"class":1322},"100",[66,2256,1326],{"class":1318},[66,2258,1273],{"class":80},[66,2260,2261],{"class":223}," \u002F\u002F \"100100\"\n",[66,2263,2264],{"class":68,"line":121},[66,2265,2266],{"class":223},"\u002F\u002F 好：保持类型一致\n",[66,2268,2269,2271,2273,2275,2277,2279,2282,2284,2286,2288,2290,2292],{"class":68,"line":144},[66,2270,1799],{"class":72},[66,2272,2242],{"class":450},[66,2274,111],{"class":110},[66,2276,2247],{"class":423},[66,2278,1315],{"class":110},[66,2280,2281],{"class":76}," Number",[66,2283,81],{"class":106},[66,2285,1326],{"class":1318},[66,2287,2254],{"class":1322},[66,2289,1326],{"class":1318},[66,2291,94],{"class":106},[66,2293,118],{"class":80},[23,2295,2296],{},"优化建议：",[1165,2298,2299,2308],{},[1168,2300,1039,2301,1521,2304,2307],{},[63,2302,2303],{},"===",[63,2305,2306],{},"==","（避免类型猜测）。",[1168,2309,2310],{},"避免在热函数中改变变量类型（会改变隐藏类）。",[43,2312,2314],{"id":2313},"_2-隐藏类hidden-classes","2. 隐藏类（Hidden Classes）",[23,2316,2317],{},"V8 将对象结构（属性名、顺序）编码为隐藏类。如果两个对象具有相同的属性名和顺序，它们共享同一个隐藏类，从而加速属性访问。",[23,2319,2320],{},"导致隐藏类退化的操作：",[1165,2322,2323,2326],{},[1168,2324,2325],{},"动态添加\u002F删除属性。",[1168,2327,2328],{},"属性赋值顺序不同。",[56,2330,2332],{"className":58,"code":2331,"language":60,"meta":61,"style":61},"\u002F\u002F 相同隐藏类\nconst p1 = { name: \"A\", age: 20 };\nconst p2 = { name: \"B\", age: 22 };\n\n\u002F\u002F 不同隐藏类（差顺序）\nconst p3 = { age: 20, name: \"C\" };\n",[63,2333,2334,2339,2377,2410,2416,2421],{"__ignoreMap":61},[66,2335,2336],{"class":68,"line":69},[66,2337,2338],{"class":223},"\u002F\u002F 相同隐藏类\n",[66,2340,2341,2343,2346,2348,2351,2354,2357,2359,2362,2364,2366,2369,2371,2374],{"class":68,"line":100},[66,2342,1799],{"class":72},[66,2344,2345],{"class":450}," p1",[66,2347,111],{"class":110},[66,2349,2350],{"class":80}," {",[66,2352,2353],{"class":150}," name",[66,2355,2356],{"class":80},":",[66,2358,1319],{"class":1318},[66,2360,2361],{"class":1322},"A",[66,2363,1326],{"class":1318},[66,2365,88],{"class":80},[66,2367,2368],{"class":150}," age",[66,2370,2356],{"class":80},[66,2372,2373],{"class":423}," 20",[66,2375,2376],{"class":80}," };\n",[66,2378,2379,2381,2384,2386,2388,2390,2392,2394,2397,2399,2401,2403,2405,2408],{"class":68,"line":121},[66,2380,1799],{"class":72},[66,2382,2383],{"class":450}," p2",[66,2385,111],{"class":110},[66,2387,2350],{"class":80},[66,2389,2353],{"class":150},[66,2391,2356],{"class":80},[66,2393,1319],{"class":1318},[66,2395,2396],{"class":1322},"B",[66,2398,1326],{"class":1318},[66,2400,88],{"class":80},[66,2402,2368],{"class":150},[66,2404,2356],{"class":80},[66,2406,2407],{"class":423}," 22",[66,2409,2376],{"class":80},[66,2411,2412],{"class":68,"line":144},[66,2413,2415],{"emptyLinePlaceholder":2414},true,"\n",[66,2417,2418],{"class":68,"line":160},[66,2419,2420],{"class":223},"\u002F\u002F 不同隐藏类（差顺序）\n",[66,2422,2423,2425,2428,2430,2432,2434,2436,2438,2440,2442,2444,2446,2449,2451],{"class":68,"line":208},[66,2424,1799],{"class":72},[66,2426,2427],{"class":450}," p3",[66,2429,111],{"class":110},[66,2431,2350],{"class":80},[66,2433,2368],{"class":150},[66,2435,2356],{"class":80},[66,2437,2373],{"class":423},[66,2439,88],{"class":80},[66,2441,2353],{"class":150},[66,2443,2356],{"class":80},[66,2445,1319],{"class":1318},[66,2447,2448],{"class":1322},"C",[66,2450,1326],{"class":1318},[66,2452,2376],{"class":80},[23,2454,2455],{},"优化：在构造函数或对象字面量中一次性定义所有属性，不要动态添加。",[43,2457,2459],{"id":2458},"_3-去优化deoptimization","3. 去优化（Deoptimization）",[23,2461,2462],{},"V8 在运行时进行推测优化（假设代码模式不变）。当假设被打破时，会回退到非优化代码，称为去优化。",[23,2464,2465],{},"常见触发去优化的操作：",[1165,2467,2468,2479,2486],{},[1168,2469,2470,2471,2474,2475,2478],{},"函数中传入不同类型参数（例如有时是 ",[63,2472,2473],{},"number","，有时是 ",[63,2476,2477],{},"string","）。",[1168,2480,2481,2482,2485],{},"在 ",[63,2483,2484],{},"try\u002Fcatch"," 中的热代码路径。",[1168,2487,1039,2488,31,2491,31,2494,36],{},[63,2489,2490],{},"debugger",[63,2492,2493],{},"with",[63,2495,2496],{},"eval",[23,2498,2296],{},[1165,2500,2501,2504,2510],{},[1168,2502,2503],{},"保持函数参数类型稳定。",[1168,2505,2506,2507,2509],{},"避免在高频率函数（如动画循环）中使用 ",[63,2508,2484],{},"，可以将错误处理放到外层。",[1168,2511,2512,2513,1198,2515,36],{},"切勿在生产代码中使用 ",[63,2514,2496],{},[63,2516,2493],{},[38,2518,2519],{"id":2519},"总结",[1002,2521,2522,2532],{},[1005,2523,2524],{},[1008,2525,2526,2529],{},[1011,2527,2528],{},"类别",[1011,2530,2531],{},"关键技术点",[1021,2533,2534,2547,2557,2570,2580,2590,2604],{},[1008,2535,2536,2541],{},[1026,2537,2538],{},[1029,2539,2540],{},"防抖节流",[1026,2542,2543,2544,2546],{},"防抖合并连续触发，节流限制频率；实现中注意 ",[63,2545,190],{}," 和参数传递、立即执行\u002F尾部执行变体",[1008,2548,2549,2554],{},[1026,2550,2551],{},[1029,2552,2553],{},"内存泄漏",[1026,2555,2556],{},"警惕全局变量、定时器、事件监听、闭包、DOM 引用；使用 WeakMap\u002FWeakSet 辅助",[1008,2558,2559,2564],{},[1026,2560,2561],{},[1029,2562,2563],{},"渲染优化",[1026,2565,2566,2567,2569],{},"减少重排重绘，利用 transform\u002Fopacity，批量 DOM 操作，",[63,2568,1382],{}," 合并更新",[1008,2571,2572,2577],{},[1026,2573,2574],{},[1029,2575,2576],{},"网络预加载",[1026,2578,2579],{},"preload（关键）、prefetch（下页）、preconnect（连接预热）、dns-prefetch",[1008,2581,2582,2587],{},[1026,2583,2584],{},[1029,2585,2586],{},"HTTP 优化",[1026,2588,2589],{},"HTTP\u002F2 多路复用 + Brotli\u002Fgzip 压缩",[1008,2591,2592,2597],{},[1026,2593,2594],{},[1029,2595,2596],{},"图片优化",[1026,2598,2599,2600,2603],{},"懒加载（IntersectionObserver \u002F ",[63,2601,2602],{},"loading=\"lazy\"","）、srcset + sizes、picture + WebP\u002FAVIF",[1008,2605,2606,2611],{},[1026,2607,2608],{},[1029,2609,2610],{},"V8 优化",[1026,2612,2613],{},"保持类型稳定（避免隐式转换）、使用一致的隐藏类（完整定义对象属性）、避免去优化（稳定参数）",[23,2615,2616],{},"结合 Lighthouse、Performance 面板与内存快照做针对性优化。",[38,2618,2619],{"id":2619},"参考文献",[23,2621,2622],{},"以下链接在编写时均可正常访问：",[1002,2624,2625,2635],{},[1005,2626,2627],{},[1008,2628,2629,2632],{},[1011,2630,2631],{},"资料",[1011,2633,2634],{},"说明",[1021,2636,2637,2650,2662,2674],{},[1008,2638,2639,2647],{},[1026,2640,2641],{},[27,2642,2646],{"href":2643,"rel":2644},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002Fwindow\u002FrequestAnimationFrame",[2645],"nofollow","MDN：requestAnimationFrame",[1026,2648,2649],{},"动画帧",[1008,2651,2652,2659],{},[1026,2653,2654],{},[27,2655,2658],{"href":2656,"rel":2657},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FHTML\u002FAttributes\u002Frel\u002Fpreload",[2645],"MDN：rel=preload",[1026,2660,2661],{},"预加载",[1008,2663,2664,2671],{},[1026,2665,2666],{},[27,2667,2670],{"href":2668,"rel":2669},"https:\u002F\u002Fweb.dev\u002Fperformance",[2645],"web.dev：Performance",[1026,2672,2673],{},"性能专题（英文）",[1008,2675,2676,2683],{},[1026,2677,2678],{},[27,2679,2682],{"href":2680,"rel":2681},"https:\u002F\u002Fweb.dev\u002Farticles\u002Foptimize-lcp",[2645],"web.dev：Optimize LCP",[1026,2684,2685],{},"加载性能（英文）",[1303,2687,2688],{},"html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s9AJx, html code.shiki .s9AJx{--shiki-light:#9C3EDA;--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":61,"searchDepth":100,"depth":100,"links":2690},[2691,2697,2702,2707,2708],{"id":40,"depth":100,"text":41,"children":2692},[2693,2694,2695,2696],{"id":45,"depth":121,"text":46},{"id":999,"depth":121,"text":1000},{"id":1162,"depth":121,"text":1163},{"id":1370,"depth":121,"text":1371},{"id":1638,"depth":100,"text":1639,"children":2698},[2699,2700,2701],{"id":1642,"depth":121,"text":1643},{"id":1726,"depth":121,"text":1727},{"id":1767,"depth":121,"text":1768},{"id":2214,"depth":100,"text":2215,"children":2703},[2704,2705,2706],{"id":2221,"depth":121,"text":2222},{"id":2313,"depth":121,"text":2314},{"id":2458,"depth":121,"text":2459},{"id":2519,"depth":100,"text":2519},{"id":2619,"depth":100,"text":2619},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fperformance","knowledge\u002Fknowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fperformance.md","md",{"items":2714},[2715,2719,2723,2727,2731,2735],{"path":2716,"title":2717,"description":2718,"category":10,"score":208},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Ferror","错误处理与调试","结构化错误类型、try\u002Fcatch 与全局未捕获处理是健壮应用的基础。",{"path":2720,"title":2721,"description":2722,"category":10,"score":208},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdom-bom","浏览器相关 API","DOM 事件、存储、fetch、Worker、Observer 等由浏览器提供的 Web API（非 ECMAScript 核心）。HTML 结构见 标签。",{"path":2724,"title":2725,"description":2726,"category":10,"score":208},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fcommon","模块化与工程化","ESM、CommonJS 与打包工具（Tree Shaking、代码分割）是前端工程化的基础。入门见 JavaScript 基础 · 模块。",{"path":2728,"title":2729,"description":2730,"category":10,"score":208},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fscope","执行模型与作用域","执行上下文与词法作用域决定变量在何处可访问、闭包如何形成，以及 var \u002F let \u002F const 的差异。语言概览见 JavaScript 基础。",{"path":2732,"title":2733,"description":2734,"category":10,"score":208},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fmap-set","数据结构与集合增强","Map \u002F Set、WeakMap \u002F WeakSet、数组高阶方法、TypedArray 与 Symbol 等扩展了内置数据结构能力。见 语言基础。",{"path":2736,"title":2737,"description":2738,"category":10,"score":208},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fbasics","JavaScript 基础","JavaScript（ECMAScript）是 Web 页面与 Node.js 等运行时的脚本语言：在浏览器中操作 DOM、发起网络请求；在服务端处理 I\u002FO。语法与 HTML、CSS 配合构成前端技术栈。",{"series":2740,"title":60,"items":2741,"index":227,"prev":2783,"next":2784},"booklet\u002Fweb\u002Fjs",[2742,2746,2748,2750,2754,2756,2758,2762,2766,2768,2769,2773,2777,2781],{"path":2743,"title":2744,"date":2745,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fadvanced","函数进阶","2022-10-24",{"path":2736,"title":2737,"date":2747,"pinned":15},"2023-11-24",{"path":2724,"title":2725,"date":2749,"pinned":15},"2025-06-21",{"path":2751,"title":2752,"date":2753,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdesign","设计模式","2021-10-05",{"path":2720,"title":2721,"date":2755,"pinned":15},"2025-07-10",{"path":2716,"title":2717,"date":2757,"pinned":15},"2026-06-25",{"path":2759,"title":2760,"date":2761,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fevent-loop","异步编程与事件循环","2020-03-23",{"path":2763,"title":2764,"date":2765,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fexec","正则表达式","2022-05-21",{"path":2732,"title":2733,"date":2767,"pinned":15},"2024-07-10",{"path":7,"title":8,"date":14,"pinned":15},{"path":2770,"title":2771,"date":2772,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fprototype","原型与面向对象","2020-04-13",{"path":2774,"title":2775,"date":2776,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fproxy","代理与反射","2022-10-23",{"path":2778,"title":2779,"date":2780,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fsafe","安全","2023-06-26",{"path":2728,"title":2729,"date":2782,"pinned":15},"2025-01-29",{"path":2732,"title":2733,"date":2767,"pinned":15},{"path":2770,"title":2771,"date":2772,"pinned":15}]