[{"data":1,"prerenderedAt":3083},["ShallowReactive",2],{"article-/topics/frontend/css-box-sizing-responsive-overflow-guide":3,"related-frontend":659,"content-query-R9IkwdY6Z1":2576},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":12,"image":17,"imageQuery":18,"pexelsPhotoId":19,"pexelsUrl":20,"featured":6,"readingTime":21,"body":22,"_type":653,"_id":654,"_source":655,"_file":656,"_stem":657,"_extension":658},"/topics/frontend/css-box-sizing-responsive-overflow-guide","frontend",false,"","CSS box-sizing 与响应式溢出排查：为什么宽度 100% 还会横向滚动","box-sizing 是响应式页面稳定性的基础。本文讲清 content-box、border-box、padding、border、min-width 与横向滚动的真实排查方法。","2026-05-05","HTMLPAGE 团队",[13,14,15,16],"CSS","box-sizing","响应式","溢出排查","/images/articles/css-box-sizing-responsive-overflow-guide-featured.jpg","responsive web design mobile laptop code",4439901,"https://www.pexels.com/photo/a-laptop-screen-with-text-4439901/",13,{"type":23,"children":24,"toc":640},"root",[25,57,69,76,97,109,137,143,148,157,169,174,180,192,229,234,243,256,262,267,272,281,286,292,297,326,331,340,345,351,361,384,389,395,421,426,464,476,482,573,578,595,600],{"type":26,"tag":27,"props":28,"children":29},"element","p",{},[30,33,40,42,48,50,55],{"type":31,"value":32},"text","移动端页面出现横向滚动时，很多人第一反应是给 ",{"type":26,"tag":34,"props":35,"children":37},"code",{"className":36},[],[38],{"type":31,"value":39},"body",{"type":31,"value":41}," 加 ",{"type":26,"tag":34,"props":43,"children":45},{"className":44},[],[46],{"type":31,"value":47},"overflow-x: hidden",{"type":31,"value":49},"。这能把问题藏起来，却不会修复真正原因。宽度 100% 的元素仍然可能溢出，因为 CSS 的宽度到底包不包含 padding 和 border，取决于 ",{"type":26,"tag":34,"props":51,"children":53},{"className":52},[],[54],{"type":31,"value":14},{"type":31,"value":56},"。",{"type":26,"tag":27,"props":58,"children":59},{},[60,62,67],{"type":31,"value":61},"本文从网页制作和响应式排查角度，讲清 ",{"type":26,"tag":34,"props":63,"children":65},{"className":64},[],[66],{"type":31,"value":14},{"type":31,"value":68}," 为什么重要，以及如何定位横向滚动。",{"type":26,"tag":70,"props":71,"children":73},"h2",{"id":72},"先给结论全局-border-box-是现代网页的稳定默认值",[74],{"type":31,"value":75},"先给结论：全局 border-box 是现代网页的稳定默认值",{"type":26,"tag":27,"props":77,"children":78},{},[79,81,87,89,95],{"type":31,"value":80},"默认盒模型是 ",{"type":26,"tag":34,"props":82,"children":84},{"className":83},[],[85],{"type":31,"value":86},"content-box",{"type":31,"value":88},"：",{"type":26,"tag":34,"props":90,"children":92},{"className":91},[],[93],{"type":31,"value":94},"width",{"type":31,"value":96}," 只表示内容区宽度，padding 和 border 会额外增加元素外观尺寸。",{"type":26,"tag":98,"props":99,"children":104},"pre",{"className":100,"code":102,"language":103,"meta":7},[101],"language-css","*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n","css",[105],{"type":26,"tag":34,"props":106,"children":107},{"__ignoreMap":7},[108],{"type":31,"value":102},{"type":26,"tag":27,"props":110,"children":111},{},[112,114,120,122,127,129,135],{"type":31,"value":113},"设置为 ",{"type":26,"tag":34,"props":115,"children":117},{"className":116},[],[118],{"type":31,"value":119},"border-box",{"type":31,"value":121}," 后，",{"type":26,"tag":34,"props":123,"children":125},{"className":124},[],[126],{"type":31,"value":94},{"type":31,"value":128}," 会包含 padding 和 border。一个 ",{"type":26,"tag":34,"props":130,"children":132},{"className":131},[],[133],{"type":31,"value":134},"width: 100%",{"type":31,"value":136}," 的盒子再加 padding，也不容易撑破父容器。",{"type":26,"tag":70,"props":138,"children":140},{"id":139},"一content-box-为什么容易制造溢出",[141],{"type":31,"value":142},"一、content-box 为什么容易制造溢出",{"type":26,"tag":27,"props":144,"children":145},{},[146],{"type":31,"value":147},"假设父容器宽度是 320px，子元素这样写：",{"type":26,"tag":98,"props":149,"children":152},{"className":150,"code":151,"language":103,"meta":7},[101],".panel {\n  width: 100%;\n  padding: 24px;\n  border: 1px solid #ddd;\n}\n",[153],{"type":26,"tag":34,"props":154,"children":155},{"__ignoreMap":7},[156],{"type":31,"value":151},{"type":26,"tag":27,"props":158,"children":159},{},[160,162,167],{"type":31,"value":161},"在 ",{"type":26,"tag":34,"props":163,"children":165},{"className":164},[],[166],{"type":31,"value":86},{"type":31,"value":168}," 下，最终外观宽度是 320 + 48 + 2 = 370px，必然溢出。",{"type":26,"tag":27,"props":170,"children":171},{},[172],{"type":31,"value":173},"很多“移动端多出一条横向滚动条”的问题就是这么来的。",{"type":26,"tag":70,"props":175,"children":177},{"id":176},"二border-box-不是万能还要看-min-width",[178],{"type":31,"value":179},"二、border-box 不是万能，还要看 min-width",{"type":26,"tag":27,"props":181,"children":182},{},[183,185,190],{"type":31,"value":184},"即使全局设置了 ",{"type":26,"tag":34,"props":186,"children":188},{"className":187},[],[189],{"type":31,"value":119},{"type":31,"value":191},"，页面仍可能溢出。常见原因是子元素有不可压缩宽度：",{"type":26,"tag":193,"props":194,"children":195},"ul",{},[196,202,207,218],{"type":26,"tag":197,"props":198,"children":199},"li",{},[200],{"type":31,"value":201},"表格列太多",{"type":26,"tag":197,"props":203,"children":204},{},[205],{"type":31,"value":206},"长英文、URL、代码片段不换行",{"type":26,"tag":197,"props":208,"children":209},{},[210,212],{"type":31,"value":211},"flex 子项默认 ",{"type":26,"tag":34,"props":213,"children":215},{"className":214},[],[216],{"type":31,"value":217},"min-width: auto",{"type":26,"tag":197,"props":219,"children":220},{},[221,223],{"type":31,"value":222},"图片或 iframe 没有 ",{"type":26,"tag":34,"props":224,"children":226},{"className":225},[],[227],{"type":31,"value":228},"max-width: 100%",{"type":26,"tag":27,"props":230,"children":231},{},[232],{"type":31,"value":233},"Flex 布局里尤其常见：",{"type":26,"tag":98,"props":235,"children":238},{"className":236,"code":237,"language":103,"meta":7},[101],".content {\n  min-width: 0;\n}\n",[239],{"type":26,"tag":34,"props":240,"children":241},{"__ignoreMap":7},[242],{"type":31,"value":237},{"type":26,"tag":27,"props":244,"children":245},{},[246,248,254],{"type":31,"value":247},"给 flex 子项设置 ",{"type":26,"tag":34,"props":249,"children":251},{"className":250},[],[252],{"type":31,"value":253},"min-width: 0",{"type":31,"value":255},"，常常能解决文本区域把布局撑开的情况。",{"type":26,"tag":70,"props":257,"children":259},{"id":258},"三图片代码块和表格是三类高风险元素",[260],{"type":31,"value":261},"三、图片、代码块和表格是三类高风险元素",{"type":26,"tag":27,"props":263,"children":264},{},[265],{"type":31,"value":266},"内容页和模板页最容易被这三类元素撑开。",{"type":26,"tag":27,"props":268,"children":269},{},[270],{"type":31,"value":271},"建议基础规则：",{"type":26,"tag":98,"props":273,"children":276},{"className":274,"code":275,"language":103,"meta":7},[101],"img,\nvideo,\niframe {\n  max-width: 100%;\n  height: auto;\n}\n\npre {\n  overflow-x: auto;\n}\n\ntable {\n  width: 100%;\n}\n",[277],{"type":26,"tag":34,"props":278,"children":279},{"__ignoreMap":7},[280],{"type":31,"value":275},{"type":26,"tag":27,"props":282,"children":283},{},[284],{"type":31,"value":285},"表格在移动端不一定要强行压缩。更稳的做法是让表格外层横向滚动，而不是让整个页面横向滚动。",{"type":26,"tag":70,"props":287,"children":289},{"id":288},"四排查横向滚动的四步法",[290],{"type":31,"value":291},"四、排查横向滚动的四步法",{"type":26,"tag":27,"props":293,"children":294},{},[295],{"type":31,"value":296},"遇到页面溢出，可以按这个顺序排查：",{"type":26,"tag":298,"props":299,"children":300},"ol",{},[301,306,311,321],{"type":26,"tag":197,"props":302,"children":303},{},[304],{"type":31,"value":305},"临时给所有元素加 outline，找出超出边界的盒子",{"type":26,"tag":197,"props":307,"children":308},{},[309],{"type":31,"value":310},"检查该元素的 computed width、padding、border",{"type":26,"tag":197,"props":312,"children":313},{},[314,316],{"type":31,"value":315},"查看父级是否是 flex/grid，是否需要 ",{"type":26,"tag":34,"props":317,"children":319},{"className":318},[],[320],{"type":31,"value":253},{"type":26,"tag":197,"props":322,"children":323},{},[324],{"type":31,"value":325},"检查图片、长文本、表格、绝对定位元素",{"type":26,"tag":27,"props":327,"children":328},{},[329],{"type":31,"value":330},"调试用样式：",{"type":26,"tag":98,"props":332,"children":335},{"className":333,"code":334,"language":103,"meta":7},[101],"* {\n  outline: 1px solid rgba(255, 0, 0, 0.2);\n}\n",[336],{"type":26,"tag":34,"props":337,"children":338},{"__ignoreMap":7},[339],{"type":31,"value":334},{"type":26,"tag":27,"props":341,"children":342},{},[343],{"type":31,"value":344},"这个样式不要提交到生产代码，但用于定位问题非常快。",{"type":26,"tag":70,"props":346,"children":348},{"id":347},"五不要用-overflow-x-hidden-作为第一解",[349],{"type":31,"value":350},"五、不要用 overflow-x hidden 作为第一解",{"type":26,"tag":27,"props":352,"children":353},{},[354,359],{"type":26,"tag":34,"props":355,"children":357},{"className":356},[],[358],{"type":31,"value":47},{"type":31,"value":360}," 可以作为最后防线，但不应该是第一解。它可能带来副作用：",{"type":26,"tag":193,"props":362,"children":363},{},[364,369,374,379],{"type":26,"tag":197,"props":365,"children":366},{},[367],{"type":31,"value":368},"阴影、浮层、焦点环被裁剪",{"type":26,"tag":197,"props":370,"children":371},{},[372],{"type":31,"value":373},"锚点跳转和 sticky 行为异常",{"type":26,"tag":197,"props":375,"children":376},{},[377],{"type":31,"value":378},"真正溢出的内容不可见",{"type":26,"tag":197,"props":380,"children":381},{},[382],{"type":31,"value":383},"移动端交互区域被截断",{"type":26,"tag":27,"props":385,"children":386},{},[387],{"type":31,"value":388},"正确思路是先找撑开的元素，再判断是盒模型、内容不可换行、媒体尺寸还是布局模型问题。",{"type":26,"tag":70,"props":390,"children":392},{"id":391},"六失败案例卡片宽度-100移动端还是露白",[393],{"type":31,"value":394},"六、失败案例：卡片宽度 100%，移动端还是露白",{"type":26,"tag":27,"props":396,"children":397},{},[398,400,405,407,413,415,420],{"type":31,"value":399},"一个模板页卡片在桌面端正常，移动端右侧出现 16px 露白。检查后发现卡片设置了 ",{"type":26,"tag":34,"props":401,"children":403},{"className":402},[],[404],{"type":31,"value":134},{"type":31,"value":406}," 和左右 ",{"type":26,"tag":34,"props":408,"children":410},{"className":409},[],[411],{"type":31,"value":412},"padding: 24px",{"type":31,"value":414},"，但局部 CSS 重置把该区域改回了 ",{"type":26,"tag":34,"props":416,"children":418},{"className":417},[],[419],{"type":31,"value":86},{"type":31,"value":56},{"type":26,"tag":27,"props":422,"children":423},{},[424],{"type":31,"value":425},"修复步骤：",{"type":26,"tag":298,"props":427,"children":428},{},[429,439,444,454,459],{"type":26,"tag":197,"props":430,"children":431},{},[432,434],{"type":31,"value":433},"恢复全局 ",{"type":26,"tag":34,"props":435,"children":437},{"className":436},[],[438],{"type":31,"value":119},{"type":26,"tag":197,"props":440,"children":441},{},[442],{"type":31,"value":443},"删除卡片上多余的固定宽度",{"type":26,"tag":197,"props":445,"children":446},{},[447,449],{"type":31,"value":448},"图片设置 ",{"type":26,"tag":34,"props":450,"children":452},{"className":451},[],[453],{"type":31,"value":228},{"type":26,"tag":197,"props":455,"children":456},{},[457],{"type":31,"value":458},"长标题增加换行规则",{"type":26,"tag":197,"props":460,"children":461},{},[462],{"type":31,"value":463},"用真实手机宽度重新检查",{"type":26,"tag":27,"props":465,"children":466},{},[467,469,474],{"type":31,"value":468},"最终没有再使用 ",{"type":26,"tag":34,"props":470,"children":472},{"className":471},[],[473],{"type":31,"value":47},{"type":31,"value":475}," 掩盖问题。",{"type":26,"tag":70,"props":477,"children":479},{"id":478},"七响应式稳定性-checklist",[480],{"type":31,"value":481},"七、响应式稳定性 Checklist",{"type":26,"tag":193,"props":483,"children":486},{"className":484},[485],"contains-task-list",[487,506,515,529,538,547,564],{"type":26,"tag":197,"props":488,"children":491},{"className":489},[490],"task-list-item",[492,498,500],{"type":26,"tag":493,"props":494,"children":497},"input",{"disabled":495,"type":496},true,"checkbox",[],{"type":31,"value":499}," 是否全局设置 ",{"type":26,"tag":34,"props":501,"children":503},{"className":502},[],[504],{"type":31,"value":505},"box-sizing: border-box",{"type":26,"tag":197,"props":507,"children":509},{"className":508},[490],[510,513],{"type":26,"tag":493,"props":511,"children":512},{"disabled":495,"type":496},[],{"type":31,"value":514}," 图片、视频、iframe 是否有最大宽度",{"type":26,"tag":197,"props":516,"children":518},{"className":517},[490],[519,522,524],{"type":26,"tag":493,"props":520,"children":521},{"disabled":495,"type":496},[],{"type":31,"value":523}," flex 子项是否需要 ",{"type":26,"tag":34,"props":525,"children":527},{"className":526},[],[528],{"type":31,"value":253},{"type":26,"tag":197,"props":530,"children":532},{"className":531},[490],[533,536],{"type":26,"tag":493,"props":534,"children":535},{"disabled":495,"type":496},[],{"type":31,"value":537}," 长 URL、代码和英文是否可换行或可滚动",{"type":26,"tag":197,"props":539,"children":541},{"className":540},[490],[542,545],{"type":26,"tag":493,"props":543,"children":544},{"disabled":495,"type":496},[],{"type":31,"value":546}," 表格是否有移动端处理方式",{"type":26,"tag":197,"props":548,"children":550},{"className":549},[490],[551,554,556,562],{"type":26,"tag":493,"props":552,"children":553},{"disabled":495,"type":496},[],{"type":31,"value":555}," 是否避免用 ",{"type":26,"tag":34,"props":557,"children":559},{"className":558},[],[560],{"type":31,"value":561},"100vw",{"type":31,"value":563}," 加 padding 做容器宽度",{"type":26,"tag":197,"props":565,"children":567},{"className":566},[490],[568,571],{"type":26,"tag":493,"props":569,"children":570},{"disabled":495,"type":496},[],{"type":31,"value":572}," 横向滚动是否定位到具体元素，而不是直接隐藏",{"type":26,"tag":70,"props":574,"children":576},{"id":575},"结语",[577],{"type":31,"value":575},{"type":26,"tag":27,"props":579,"children":580},{},[581,586,588,593],{"type":26,"tag":34,"props":582,"children":584},{"className":583},[],[585],{"type":31,"value":14},{"type":31,"value":587}," 是响应式页面的地基。把盒模型统一为 ",{"type":26,"tag":34,"props":589,"children":591},{"className":590},[],[592],{"type":31,"value":119},{"type":31,"value":594},"，再系统检查媒体、长内容、flex 最小宽度和表格，你会更快定位横向滚动。真正专业的修复不是把滚动条藏起来，而是让每个盒子都在自己的边界内工作。",{"type":26,"tag":27,"props":596,"children":597},{},[598],{"type":31,"value":599},"延伸阅读：",{"type":26,"tag":193,"props":601,"children":602},{},[603,613,622,631],{"type":26,"tag":197,"props":604,"children":605},{},[606],{"type":26,"tag":607,"props":608,"children":610},"a",{"href":609},"/topics/frontend/css-border-layout-visual-debugging-guide",[611],{"type":31,"value":612},"CSS border 完整指南",{"type":26,"tag":197,"props":614,"children":615},{},[616],{"type":26,"tag":607,"props":617,"children":619},{"href":618},"/topics/frontend/css-display-layout-decision-guide",[620],{"type":31,"value":621},"CSS display 布局决策指南",{"type":26,"tag":197,"props":623,"children":624},{},[625],{"type":26,"tag":607,"props":626,"children":628},{"href":627},"/about-html/html-template-responsive-breakpoints-strategy",[629],{"type":31,"value":630},"HTML 模板响应式断点策略",{"type":26,"tag":197,"props":632,"children":633},{},[634],{"type":26,"tag":607,"props":635,"children":637},{"href":636},"/topics/performance/mobile-performance-guide",[638],{"type":31,"value":639},"移动端性能优化指南",{"title":7,"searchDepth":641,"depth":641,"links":642},3,[643,645,646,647,648,649,650,651,652],{"id":72,"depth":644,"text":75},2,{"id":139,"depth":644,"text":142},{"id":176,"depth":644,"text":179},{"id":258,"depth":644,"text":261},{"id":288,"depth":644,"text":291},{"id":347,"depth":644,"text":350},{"id":391,"depth":644,"text":394},{"id":478,"depth":644,"text":481},{"id":575,"depth":644,"text":575},"markdown","content:topics:frontend:css-box-sizing-responsive-overflow-guide.md","content","topics/frontend/css-box-sizing-responsive-overflow-guide.md","topics/frontend/css-box-sizing-responsive-overflow-guide","md",[660,987,1299],{"_path":661,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":662,"description":663,"keywords":664,"image":670,"author":671,"date":672,"readingTime":673,"topic":5,"body":674,"_type":653,"_id":984,"_source":655,"_file":985,"_stem":986,"_extension":658},"/topics/frontend/react-hooks-guide","React Hooks 完全指南","全面讲解 React Hooks，包括内置钩子、自定义钩子和最佳实践",[665,666,667,668,669],"React","Hooks","自定义钩子","状态管理","函数组件","/images/topics/react-hooks-guide.jpg","AI Content Team","2025-12-08",23,{"type":23,"children":675,"toc":965},[676,681,686,692,699,710,716,725,731,740,746,752,761,767,776,782,791,797,806,811,817,826,831,844,872,883,911,916],{"type":26,"tag":70,"props":677,"children":679},{"id":678},"react-hooks-完全指南",[680],{"type":31,"value":662},{"type":26,"tag":27,"props":682,"children":683},{},[684],{"type":31,"value":685},"Hooks 改变了 React 的开发方式。本文全面讲解如何使用和创建 Hooks。",{"type":26,"tag":70,"props":687,"children":689},{"id":688},"内置-hooks",[690],{"type":31,"value":691},"内置 Hooks",{"type":26,"tag":693,"props":694,"children":696},"h3",{"id":695},"usestate-状态管理",[697],{"type":31,"value":698},"useState - 状态管理",{"type":26,"tag":98,"props":700,"children":705},{"className":701,"code":703,"language":704,"meta":7},[702],"language-javascript","import { useState } from 'react'\n\nfunction Counter() {\n  const [count, setCount] = useState(0)\n  const [name, setName] = useState('John')\n  const [user, setUser] = useState({\n    age: 30,\n    email: 'john@example.com',\n  })\n  \n  // 使用函数初始化状态（对于复杂初始值）\n  const [data, setData] = useState(() => {\n    console.log('初始化数据...')\n    return fetchInitialData() // 仅在首次渲染时调用\n  })\n  \n  return (\n    \u003Cdiv>\n      \u003Cp>计数: {count}\u003C/p>\n      \u003Cbutton onClick={() => setCount(count + 1)}>增加\u003C/button>\n      \n      {/* 函数式更新 */}\n      \u003Cbutton onClick={() => setCount(prev => prev + 1)}>\n        函数式增加\n      \u003C/button>\n      \n      {/* 更新对象 */}\n      \u003Cbutton onClick={() => setUser({ ...user, age: user.age + 1 })}>\n        增加年龄\n      \u003C/button>\n    \u003C/div>\n  )\n}\n","javascript",[706],{"type":26,"tag":34,"props":707,"children":708},{"__ignoreMap":7},[709],{"type":31,"value":703},{"type":26,"tag":693,"props":711,"children":713},{"id":712},"useeffect-副作用处理",[714],{"type":31,"value":715},"useEffect - 副作用处理",{"type":26,"tag":98,"props":717,"children":720},{"className":718,"code":719,"language":704,"meta":7},[702],"import { useState, useEffect } from 'react'\n\nfunction DataFetcher() {\n  const [data, setData] = useState(null)\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState(null)\n  const [userId, setUserId] = useState(1)\n  \n  // 副作用 - 每次渲染后执行\n  useEffect(() => {\n    console.log('组件已挂载或已更新')\n  })\n  \n  // 挂载时执行一次\n  useEffect(() => {\n    console.log('组件已挂载')\n    \n    return () => {\n      console.log('组件已卸载')\n    }\n  }, [])\n  \n  // 当 userId 改变时执行\n  useEffect(() => {\n    let isMounted = true // 防止内存泄漏\n    \n    const fetchData = async () => {\n      setLoading(true)\n      try {\n        const response = await fetch(\\`/api/users/\\${userId}\\`)\n        const result = await response.json()\n        \n        if (isMounted) {\n          setData(result)\n        }\n      } catch (err) {\n        if (isMounted) {\n          setError(err)\n        }\n      } finally {\n        if (isMounted) {\n          setLoading(false)\n        }\n      }\n    }\n    \n    fetchData()\n    \n    // 清理函数\n    return () => {\n      isMounted = false\n    }\n  }, [userId])\n  \n  if (loading) return \u003Cp>加载中...\u003C/p>\n  if (error) return \u003Cp>错误: {error.message}\u003C/p>\n  \n  return \u003Cdiv>{data && JSON.stringify(data)}\u003C/div>\n}\n",[721],{"type":26,"tag":34,"props":722,"children":723},{"__ignoreMap":7},[724],{"type":31,"value":719},{"type":26,"tag":693,"props":726,"children":728},{"id":727},"usecontext-跨组件通信",[729],{"type":31,"value":730},"useContext - 跨组件通信",{"type":26,"tag":98,"props":732,"children":735},{"className":733,"code":734,"language":704,"meta":7},[702],"import { createContext, useContext, useState } from 'react'\n\n// 创建上下文\nconst ThemeContext = createContext()\n\n// 提供者组件\nfunction ThemeProvider({ children }) {\n  const [theme, setTheme] = useState('light')\n  \n  const toggleTheme = () => {\n    setTheme(prev => prev === 'light' ? 'dark' : 'light')\n  }\n  \n  const value = { theme, toggleTheme }\n  \n  return (\n    \u003CThemeContext.Provider value={value}>\n      {children}\n    \u003C/ThemeContext.Provider>\n  )\n}\n\n// 使用 Hook\nfunction useTheme() {\n  const context = useContext(ThemeContext)\n  \n  if (!context) {\n    throw new Error('useTheme 必须在 ThemeProvider 内使用')\n  }\n  \n  return context\n}\n\n// 组件使用\nfunction App() {\n  const { theme, toggleTheme } = useTheme()\n  \n  return (\n    \u003Cdiv style={{\n      background: theme === 'light' ? '#fff' : '#333',\n      color: theme === 'light' ? '#000' : '#fff',\n    }}>\n      \u003Cp>当前主题: {theme}\u003C/p>\n      \u003Cbutton onClick={toggleTheme}>切换主题\u003C/button>\n    \u003C/div>\n  )\n}\n\n// 使用\nexport default function Root() {\n  return (\n    \u003CThemeProvider>\n      \u003CApp />\n    \u003C/ThemeProvider>\n  )\n}\n",[736],{"type":26,"tag":34,"props":737,"children":738},{"__ignoreMap":7},[739],{"type":31,"value":734},{"type":26,"tag":70,"props":741,"children":743},{"id":742},"自定义-hooks",[744],{"type":31,"value":745},"自定义 Hooks",{"type":26,"tag":693,"props":747,"children":749},{"id":748},"uselocalstorage",[750],{"type":31,"value":751},"useLocalStorage",{"type":26,"tag":98,"props":753,"children":756},{"className":754,"code":755,"language":704,"meta":7},[702],"import { useState, useEffect } from 'react'\n\nfunction useLocalStorage(key, initialValue) {\n  // 从本地存储获取初始值\n  const [storedValue, setStoredValue] = useState(() => {\n    try {\n      const item = window.localStorage.getItem(key)\n      return item ? JSON.parse(item) : initialValue\n    } catch (error) {\n      console.error(error)\n      return initialValue\n    }\n  })\n  \n  // 当值改变时更新本地存储\n  const setValue = (value) => {\n    try {\n      const valueToStore = value instanceof Function ? value(storedValue) : value\n      setStoredValue(valueToStore)\n      window.localStorage.setItem(key, JSON.stringify(valueToStore))\n    } catch (error) {\n      console.error(error)\n    }\n  }\n  \n  return [storedValue, setValue]\n}\n\n// 使用\nfunction App() {\n  const [name, setName] = useLocalStorage('name', 'Guest')\n  \n  return (\n    \u003Cdiv>\n      \u003Cp>姓名: {name}\u003C/p>\n      \u003Cinput\n        value={name}\n        onChange={(e) => setName(e.target.value)}\n      />\n    \u003C/div>\n  )\n}\n",[757],{"type":26,"tag":34,"props":758,"children":759},{"__ignoreMap":7},[760],{"type":31,"value":755},{"type":26,"tag":693,"props":762,"children":764},{"id":763},"useasync-异步操作",[765],{"type":31,"value":766},"useAsync - 异步操作",{"type":26,"tag":98,"props":768,"children":771},{"className":769,"code":770,"language":704,"meta":7},[702],"import { useState, useEffect, useRef } from 'react'\n\nfunction useAsync(asyncFunction, immediate = true) {\n  const [status, setStatus] = useState('idle')\n  const [value, setValue] = useState(null)\n  const [error, setError] = useState(null)\n  \n  // 使用 ref 来防止无限循环\n  const executeRef = useRef(null)\n  \n  const execute = useRef(async () => {\n    setStatus('pending')\n    setValue(null)\n    setError(null)\n    \n    try {\n      const response = await asyncFunction()\n      setValue(response)\n      setStatus('success')\n      return response\n    } catch (error) {\n      setError(error)\n      setStatus('error')\n    }\n  })\n  \n  executeRef.current = execute.current\n  \n  useEffect(() => {\n    if (!immediate) return\n    \n    executeRef.current()\n  }, [immediate])\n  \n  return { execute: executeRef.current, status, value, error }\n}\n\n// 使用\nfunction UserProfile({ userId }) {\n  const { execute, status, value: user, error } = useAsync(\n    () => fetch(\\`/api/users/\\${userId}\\`).then(r => r.json()),\n    true\n  )\n  \n  if (status === 'pending') return \u003Cp>加载中...\u003C/p>\n  if (status === 'error') return \u003Cp>错误: {error?.message}\u003C/p>\n  if (status === 'success') return \u003Cp>用户: {user?.name}\u003C/p>\n  \n  return null\n}\n",[772],{"type":26,"tag":34,"props":773,"children":774},{"__ignoreMap":7},[775],{"type":31,"value":770},{"type":26,"tag":693,"props":777,"children":779},{"id":778},"usefetch-数据获取",[780],{"type":31,"value":781},"useFetch - 数据获取",{"type":26,"tag":98,"props":783,"children":786},{"className":784,"code":785,"language":704,"meta":7},[702],"import { useState, useEffect } from 'react'\n\nfunction useFetch(url, options = {}) {\n  const [data, setData] = useState(null)\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState(null)\n  \n  useEffect(() => {\n    let isMounted = true\n    \n    const fetchData = async () => {\n      try {\n        const response = await fetch(url, {\n          method: 'GET',\n          ...options,\n        })\n        \n        if (!response.ok) {\n          throw new Error(\\`HTTP error! status: \\${response.status}\\`)\n        }\n        \n        const result = await response.json()\n        \n        if (isMounted) {\n          setData(result)\n          setError(null)\n        }\n      } catch (err) {\n        if (isMounted) {\n          setError(err)\n          setData(null)\n        }\n      } finally {\n        if (isMounted) {\n          setLoading(false)\n        }\n      }\n    }\n    \n    fetchData()\n    \n    return () => {\n      isMounted = false\n    }\n  }, [url, options])\n  \n  const refetch = async () => {\n    setLoading(true)\n    try {\n      const response = await fetch(url, options)\n      const result = await response.json()\n      setData(result)\n    } catch (err) {\n      setError(err)\n    } finally {\n      setLoading(false)\n    }\n  }\n  \n  return { data, loading, error, refetch }\n}\n\n// 使用\nfunction UserList() {\n  const { data: users, loading, error, refetch } = useFetch('/api/users')\n  \n  if (loading) return \u003Cp>加载中...\u003C/p>\n  if (error) return \u003Cp>错误: {error.message}\u003C/p>\n  \n  return (\n    \u003Cdiv>\n      \u003Cbutton onClick={refetch}>刷新\u003C/button>\n      \u003Cul>\n        {users?.map(user => (\n          \u003Cli key={user.id}>{user.name}\u003C/li>\n        ))}\n      \u003C/ul>\n    \u003C/div>\n  )\n}\n",[787],{"type":26,"tag":34,"props":788,"children":789},{"__ignoreMap":7},[790],{"type":31,"value":785},{"type":26,"tag":693,"props":792,"children":794},{"id":793},"useprevious-保存前一个值",[795],{"type":31,"value":796},"usePrevious - 保存前一个值",{"type":26,"tag":98,"props":798,"children":801},{"className":799,"code":800,"language":704,"meta":7},[702],"import { useEffect, useRef } from 'react'\n\nfunction usePrevious(value) {\n  const ref = useRef()\n  \n  useEffect(() => {\n    ref.current = value\n  }, [value])\n  \n  return ref.current\n}\n\n// 使用\nfunction Counter() {\n  const [count, setCount] = React.useState(0)\n  const prevCount = usePrevious(count)\n  \n  return (\n    \u003Cdiv>\n      \u003Cp>当前: {count}, 前一个: {prevCount}\u003C/p>\n      \u003Cbutton onClick={() => setCount(count + 1)}>增加\u003C/button>\n    \u003C/div>\n  )\n}\n",[802],{"type":26,"tag":34,"props":803,"children":804},{"__ignoreMap":7},[805],{"type":31,"value":800},{"type":26,"tag":70,"props":807,"children":809},{"id":808},"高级模式",[810],{"type":31,"value":808},{"type":26,"tag":693,"props":812,"children":814},{"id":813},"usereducer-复杂状态管理",[815],{"type":31,"value":816},"useReducer - 复杂状态管理",{"type":26,"tag":98,"props":818,"children":821},{"className":819,"code":820,"language":704,"meta":7},[702],"import { useReducer } from 'react'\n\nconst initialState = {\n  todos: [],\n  filter: 'all',\n  error: null,\n}\n\nfunction todoReducer(state, action) {\n  switch (action.type) {\n    case 'ADD_TODO':\n      return {\n        ...state,\n        todos: [...state.todos, { id: Date.now(), text: action.payload }],\n      }\n    \n    case 'REMOVE_TODO':\n      return {\n        ...state,\n        todos: state.todos.filter(todo => todo.id !== action.payload),\n      }\n    \n    case 'SET_FILTER':\n      return { ...state, filter: action.payload }\n    \n    case 'SET_ERROR':\n      return { ...state, error: action.payload }\n    \n    default:\n      return state\n  }\n}\n\nfunction TodoApp() {\n  const [state, dispatch] = useReducer(todoReducer, initialState)\n  \n  const addTodo = (text) => {\n    dispatch({ type: 'ADD_TODO', payload: text })\n  }\n  \n  const removeTodo = (id) => {\n    dispatch({ type: 'REMOVE_TODO', payload: id })\n  }\n  \n  return (\n    \u003Cdiv>\n      {state.todos.map(todo => (\n        \u003Cdiv key={todo.id}>\n          {todo.text}\n          \u003Cbutton onClick={() => removeTodo(todo.id)}>删除\u003C/button>\n        \u003C/div>\n      ))}\n    \u003C/div>\n  )\n}\n",[822],{"type":26,"tag":34,"props":823,"children":824},{"__ignoreMap":7},[825],{"type":31,"value":820},{"type":26,"tag":70,"props":827,"children":829},{"id":828},"最佳实践",[830],{"type":31,"value":828},{"type":26,"tag":27,"props":832,"children":833},{},[834,836,842],{"type":31,"value":835},"✅ ",{"type":26,"tag":837,"props":838,"children":839},"strong",{},[840],{"type":31,"value":841},"应该做的事",{"type":31,"value":843},":",{"type":26,"tag":193,"props":845,"children":846},{},[847,852,857,862,867],{"type":26,"tag":197,"props":848,"children":849},{},[850],{"type":31,"value":851},"将相关逻辑提取到自定义 Hooks",{"type":26,"tag":197,"props":853,"children":854},{},[855],{"type":31,"value":856},"在 useEffect 的依赖数组中包含所有依赖",{"type":26,"tag":197,"props":858,"children":859},{},[860],{"type":31,"value":861},"使用 useCallback 和 useMemo 优化性能",{"type":26,"tag":197,"props":863,"children":864},{},[865],{"type":31,"value":866},"为自定义 Hooks 编写文档",{"type":26,"tag":197,"props":868,"children":869},{},[870],{"type":31,"value":871},"及时清理副作用",{"type":26,"tag":27,"props":873,"children":874},{},[875,877,882],{"type":31,"value":876},"❌ ",{"type":26,"tag":837,"props":878,"children":879},{},[880],{"type":31,"value":881},"不应该做的事",{"type":31,"value":843},{"type":26,"tag":193,"props":884,"children":885},{},[886,891,896,901,906],{"type":26,"tag":197,"props":887,"children":888},{},[889],{"type":31,"value":890},"在条件或循环中调用 Hooks",{"type":26,"tag":197,"props":892,"children":893},{},[894],{"type":31,"value":895},"在普通函数中调用 Hooks",{"type":26,"tag":197,"props":897,"children":898},{},[899],{"type":31,"value":900},"忘记依赖数组",{"type":26,"tag":197,"props":902,"children":903},{},[904],{"type":31,"value":905},"过度使用 useMemo/useCallback",{"type":26,"tag":197,"props":907,"children":908},{},[909],{"type":31,"value":910},"在 Hooks 中创建过多的闭包",{"type":26,"tag":70,"props":912,"children":914},{"id":913},"检查清单",[915],{"type":31,"value":913},{"type":26,"tag":193,"props":917,"children":919},{"className":918},[485],[920,929,938,947,956],{"type":26,"tag":197,"props":921,"children":923},{"className":922},[490],[924,927],{"type":26,"tag":493,"props":925,"children":926},{"disabled":495,"type":496},[],{"type":31,"value":928}," Hooks 调用顺序正确",{"type":26,"tag":197,"props":930,"children":932},{"className":931},[490],[933,936],{"type":26,"tag":493,"props":934,"children":935},{"disabled":495,"type":496},[],{"type":31,"value":937}," 依赖数组完整",{"type":26,"tag":197,"props":939,"children":941},{"className":940},[490],[942,945],{"type":26,"tag":493,"props":943,"children":944},{"disabled":495,"type":496},[],{"type":31,"value":946}," 副作用正确清理",{"type":26,"tag":197,"props":948,"children":950},{"className":949},[490],[951,954],{"type":26,"tag":493,"props":952,"children":953},{"disabled":495,"type":496},[],{"type":31,"value":955}," 性能优化得当",{"type":26,"tag":197,"props":957,"children":959},{"className":958},[490],[960,963],{"type":26,"tag":493,"props":961,"children":962},{"disabled":495,"type":496},[],{"type":31,"value":964}," 代码易于理解和测试",{"title":7,"searchDepth":641,"depth":641,"links":966},[967,968,973,979,982,983],{"id":678,"depth":644,"text":662},{"id":688,"depth":644,"text":691,"children":969},[970,971,972],{"id":695,"depth":641,"text":698},{"id":712,"depth":641,"text":715},{"id":727,"depth":641,"text":730},{"id":742,"depth":644,"text":745,"children":974},[975,976,977,978],{"id":748,"depth":641,"text":751},{"id":763,"depth":641,"text":766},{"id":778,"depth":641,"text":781},{"id":793,"depth":641,"text":796},{"id":808,"depth":644,"text":808,"children":980},[981],{"id":813,"depth":641,"text":816},{"id":828,"depth":644,"text":828},{"id":913,"depth":644,"text":913},"content:topics:frontend:react-hooks-guide.md","topics/frontend/react-hooks-guide.md","topics/frontend/react-hooks-guide",{"_path":988,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":989,"description":990,"keywords":991,"image":997,"author":671,"date":672,"readingTime":998,"topic":5,"body":999,"_type":653,"_id":1296,"_source":655,"_file":1297,"_stem":1298,"_extension":658},"/topics/frontend/vue3-composition-api","Vue 3 Composition API 深度解析","全面讲解 Vue 3 Composition API 的用法、最佳实践和高级模式",[992,993,994,995,996],"Vue 3","Composition API","组合式函数","响应式系统","前端开发","/images/topics/vue3-composition-api.jpg",22,{"type":23,"children":1000,"toc":1272},[1001,1006,1011,1016,1022,1031,1036,1045,1049,1054,1063,1068,1074,1083,1088,1094,1103,1108,1113,1122,1127,1133,1142,1146,1155,1183,1192,1220,1224],{"type":26,"tag":70,"props":1002,"children":1004},{"id":1003},"vue-3-composition-api-深度解析",[1005],{"type":31,"value":989},{"type":26,"tag":27,"props":1007,"children":1008},{},[1009],{"type":31,"value":1010},"Composition API 让 Vue 应用更易于组织和重用逻辑。本文深入讲解这一核心特性。",{"type":26,"tag":70,"props":1012,"children":1014},{"id":1013},"核心概念",[1015],{"type":31,"value":1013},{"type":26,"tag":693,"props":1017,"children":1019},{"id":1018},"setup-函数",[1020],{"type":31,"value":1021},"setup 函数",{"type":26,"tag":98,"props":1023,"children":1026},{"className":1024,"code":1025,"language":704,"meta":7},[702],"import { ref, computed, watch } from 'vue'\n\nexport default {\n  props: ['initialCount'],\n  emits: ['count-changed'],\n  \n  setup(props, { emit, slots, expose }) {\n    // 创建响应式状态\n    const count = ref(props.initialCount)\n    const doubled = computed(() => count.value * 2)\n    \n    // 监听状态变化\n    watch(count, (newVal, oldVal) => {\n      console.log(`Count changed from ${oldVal} to ${newVal}`)\n      emit('count-changed', newVal)\n    })\n    \n    // 定义方法\n    const increment = () => count.value++\n    const decrement = () => count.value--\n    \n    // 返回模板需要的内容\n    return {\n      count,\n      doubled,\n      increment,\n      decrement,\n    }\n  },\n}\n",[1027],{"type":26,"tag":34,"props":1028,"children":1029},{"__ignoreMap":7},[1030],{"type":31,"value":1025},{"type":26,"tag":693,"props":1032,"children":1034},{"id":1033},"响应式基础",[1035],{"type":31,"value":1033},{"type":26,"tag":98,"props":1037,"children":1040},{"className":1038,"code":1039,"language":704,"meta":7},[702],"import { ref, reactive, readonly, isRef } from 'vue'\n\n// ref - 用于基本类型\nconst count = ref(0)\nconsole.log(count.value) // 0\ncount.value++\n\n// reactive - 用于对象\nconst state = reactive({\n  name: 'John',\n  age: 30,\n  address: {\n    city: 'Beijing',\n  },\n})\n\nstate.name = 'Jane' // 自动更新，无需 .value\n\n// readonly - 创建只读副本\nconst original = reactive({ count: 0 })\nconst copy = readonly(original)\n// copy.count++ // 错误：不能修改\n\n// isRef 检查\nconsole.log(isRef(count)) // true\nconsole.log(isRef(state)) // false\n",[1041],{"type":26,"tag":34,"props":1042,"children":1043},{"__ignoreMap":7},[1044],{"type":31,"value":1039},{"type":26,"tag":70,"props":1046,"children":1047},{"id":994},[1048],{"type":31,"value":994},{"type":26,"tag":693,"props":1050,"children":1052},{"id":1051},"创建可重用逻辑",[1053],{"type":31,"value":1051},{"type":26,"tag":98,"props":1055,"children":1058},{"className":1056,"code":1057,"language":704,"meta":7},[702],"// useCounter.js - 组合式函数\nimport { ref, computed } from 'vue'\n\nexport function useCounter(initialValue = 0) {\n  const count = ref(initialValue)\n  const doubled = computed(() => count.value * 2)\n  \n  const increment = () => count.value++\n  const decrement = () => count.value--\n  const reset = () => count.value = initialValue\n  \n  return {\n    count,\n    doubled,\n    increment,\n    decrement,\n    reset,\n  }\n}\n\n// useFetch.js - 数据获取组合式函数\nimport { ref, onMounted } from 'vue'\n\nexport function useFetch(url) {\n  const data = ref(null)\n  const loading = ref(false)\n  const error = ref(null)\n  \n  const fetch = async () => {\n    loading.value = true\n    error.value = null\n    \n    try {\n      const response = await fetch(url)\n      data.value = await response.json()\n    } catch (e) {\n      error.value = e\n    } finally {\n      loading.value = false\n    }\n  }\n  \n  onMounted(fetch)\n  \n  return {\n    data,\n    loading,\n    error,\n    refetch: fetch,\n  }\n}\n\n// 使用\nexport default {\n  setup() {\n    const { count, doubled, increment } = useCounter(10)\n    const { data, loading, refetch } = useFetch('/api/data')\n    \n    return {\n      count,\n      doubled,\n      increment,\n      data,\n      loading,\n      refetch,\n    }\n  },\n}\n",[1059],{"type":26,"tag":34,"props":1060,"children":1061},{"__ignoreMap":7},[1062],{"type":31,"value":1057},{"type":26,"tag":70,"props":1064,"children":1066},{"id":1065},"生命周期钩子",[1067],{"type":31,"value":1065},{"type":26,"tag":693,"props":1069,"children":1071},{"id":1070},"composition-api-中的生命周期",[1072],{"type":31,"value":1073},"Composition API 中的生命周期",{"type":26,"tag":98,"props":1075,"children":1078},{"className":1076,"code":1077,"language":704,"meta":7},[702],"import {\n  onBeforeMount,\n  onMounted,\n  onBeforeUpdate,\n  onUpdated,\n  onBeforeUnmount,\n  onUnmounted,\n  onErrorCaptured,\n} from 'vue'\n\nexport default {\n  setup() {\n    onBeforeMount(() => {\n      console.log('组件挂载前')\n    })\n    \n    onMounted(() => {\n      console.log('组件已挂载')\n      // 初始化事件监听器、定时器等\n    })\n    \n    onBeforeUpdate(() => {\n      console.log('组件更新前')\n    })\n    \n    onUpdated(() => {\n      console.log('组件已更新')\n    })\n    \n    onBeforeUnmount(() => {\n      console.log('组件卸载前')\n    })\n    \n    onUnmounted(() => {\n      console.log('组件已卸载')\n      // 清理事件监听器、定时器等\n    })\n    \n    onErrorCaptured((err, instance, info) => {\n      console.log('捕获错误:', err)\n      return false // 返回 false 阻止错误传播\n    })\n    \n    return {}\n  },\n}\n",[1079],{"type":26,"tag":34,"props":1080,"children":1081},{"__ignoreMap":7},[1082],{"type":31,"value":1077},{"type":26,"tag":70,"props":1084,"children":1086},{"id":1085},"模板引用",[1087],{"type":31,"value":1085},{"type":26,"tag":693,"props":1089,"children":1091},{"id":1090},"访问-dom-元素",[1092],{"type":31,"value":1093},"访问 DOM 元素",{"type":26,"tag":98,"props":1095,"children":1098},{"className":1096,"code":1097,"language":704,"meta":7},[702],"import { ref, onMounted } from 'vue'\n\nexport default {\n  setup() {\n    const inputRef = ref(null)\n    const listRef = ref(null)\n    const dynamicRef = ref(null)\n    \n    onMounted(() => {\n      // 访问 DOM 元素\n      inputRef.value?.focus()\n      console.log(listRef.value?.offsetHeight)\n    })\n    \n    // 函数式引用\n    const assignRef = el => {\n      if (el) {\n        console.log('元素已赋值', el)\n      } else {\n        console.log('元素已移除')\n      }\n    }\n    \n    return {\n      inputRef,\n      listRef,\n      dynamicRef,\n      assignRef,\n    }\n  },\n  \n  template: \\`\n    \u003Cdiv>\n      \u003Cinput ref=\"inputRef\" />\n      \u003Cul ref=\"listRef\">\n        \u003Cli v-for=\"item in items\" :key=\"item\">{{ item }}\u003C/li>\n      \u003C/ul>\n      \u003Cdiv :ref=\"assignRef\">\u003C/div>\n    \u003C/div>\n  \\`,\n}\n",[1099],{"type":26,"tag":34,"props":1100,"children":1101},{"__ignoreMap":7},[1102],{"type":31,"value":1097},{"type":26,"tag":70,"props":1104,"children":1106},{"id":1105},"依赖注入",[1107],{"type":31,"value":1105},{"type":26,"tag":693,"props":1109,"children":1111},{"id":1110},"跨组件共享数据",[1112],{"type":31,"value":1110},{"type":26,"tag":98,"props":1114,"children":1117},{"className":1115,"code":1116,"language":704,"meta":7},[702],"import { provide, inject, ref, readonly } from 'vue'\n\n// 父组件\nexport default {\n  setup() {\n    const theme = ref('light')\n    const user = ref({ name: 'John', role: 'admin' })\n    \n    // 提供数据给子组件\n    provide('theme', readonly(theme))\n    provide('updateTheme', (newTheme) => {\n      theme.value = newTheme\n    })\n    \n    // 使用 Symbol 作为 key 避免命名冲突\n    const userKey = Symbol()\n    provide(userKey, readonly(user))\n    \n    return {\n      theme,\n      updateTheme: (newTheme) => {\n        theme.value = newTheme\n      },\n    }\n  },\n}\n\n// 子组件\nexport default {\n  setup() {\n    // 注入数据\n    const theme = inject('theme')\n    const updateTheme = inject('updateTheme')\n    const user = inject(Symbol.for('user'))\n    \n    // 带默认值的注入\n    const config = inject('config', {\n      apiUrl: 'http://localhost:3000',\n    })\n    \n    return {\n      theme,\n      updateTheme,\n      user,\n      config,\n    }\n  },\n}\n",[1118],{"type":26,"tag":34,"props":1119,"children":1120},{"__ignoreMap":7},[1121],{"type":31,"value":1116},{"type":26,"tag":70,"props":1123,"children":1125},{"id":1124},"高级状态管理",[1126],{"type":31,"value":1124},{"type":26,"tag":693,"props":1128,"children":1130},{"id":1129},"创建小型-store",[1131],{"type":31,"value":1132},"创建小型 store",{"type":26,"tag":98,"props":1134,"children":1137},{"className":1135,"code":1136,"language":704,"meta":7},[702],"import { reactive, readonly, computed } from 'vue'\n\n// store.js - 不依赖 Pinia 的简单 store\nexport function createStore() {\n  const state = reactive({\n    items: [],\n    filter: 'all',\n    sortBy: 'date',\n  })\n  \n  const filteredItems = computed(() => {\n    let result = state.items\n    \n    if (state.filter !== 'all') {\n      result = result.filter(item => item.status === state.filter)\n    }\n    \n    if (state.sortBy === 'date') {\n      result.sort((a, b) => new Date(b.date) - new Date(a.date))\n    } else if (state.sortBy === 'name') {\n      result.sort((a, b) => a.name.localeCompare(b.name))\n    }\n    \n    return result\n  })\n  \n  const actions = {\n    addItem(item) {\n      state.items.push({ ...item, id: Date.now() })\n    },\n    \n    removeItem(id) {\n      state.items = state.items.filter(item => item.id !== id)\n    },\n    \n    updateItem(id, updates) {\n      const item = state.items.find(item => item.id === id)\n      if (item) {\n        Object.assign(item, updates)\n      }\n    },\n    \n    setFilter(filter) {\n      state.filter = filter\n    },\n    \n    setSortBy(sortBy) {\n      state.sortBy = sortBy\n    },\n  }\n  \n  return {\n    state: readonly(state),\n    filteredItems,\n    ...actions,\n  }\n}\n\n// 使用\nexport default {\n  setup() {\n    const store = createStore()\n    \n    const handleAdd = (item) => {\n      store.addItem(item)\n    }\n    \n    return {\n      items: store.filteredItems,\n      addItem: handleAdd,\n      setFilter: store.setFilter,\n    }\n  },\n}\n",[1138],{"type":26,"tag":34,"props":1139,"children":1140},{"__ignoreMap":7},[1141],{"type":31,"value":1136},{"type":26,"tag":70,"props":1143,"children":1144},{"id":828},[1145],{"type":31,"value":828},{"type":26,"tag":27,"props":1147,"children":1148},{},[1149,1150,1154],{"type":31,"value":835},{"type":26,"tag":837,"props":1151,"children":1152},{},[1153],{"type":31,"value":841},{"type":31,"value":843},{"type":26,"tag":193,"props":1156,"children":1157},{},[1158,1163,1168,1173,1178],{"type":26,"tag":197,"props":1159,"children":1160},{},[1161],{"type":31,"value":1162},"将相关逻辑组织在一起",{"type":26,"tag":197,"props":1164,"children":1165},{},[1166],{"type":31,"value":1167},"创建可重用的组合式函数",{"type":26,"tag":197,"props":1169,"children":1170},{},[1171],{"type":31,"value":1172},"使用 TypeScript 获得更好的类型检查",{"type":26,"tag":197,"props":1174,"children":1175},{},[1176],{"type":31,"value":1177},"合理使用计算属性和监听器",{"type":26,"tag":197,"props":1179,"children":1180},{},[1181],{"type":31,"value":1182},"及时清理事件监听器和定时器",{"type":26,"tag":27,"props":1184,"children":1185},{},[1186,1187,1191],{"type":31,"value":876},{"type":26,"tag":837,"props":1188,"children":1189},{},[1190],{"type":31,"value":881},{"type":31,"value":843},{"type":26,"tag":193,"props":1193,"children":1194},{},[1195,1200,1205,1210,1215],{"type":26,"tag":197,"props":1196,"children":1197},{},[1198],{"type":31,"value":1199},"在 setup 中执行副作用操作（除了生命周期钩子）",{"type":26,"tag":197,"props":1201,"children":1202},{},[1203],{"type":31,"value":1204},"过度使用计算属性",{"type":26,"tag":197,"props":1206,"children":1207},{},[1208],{"type":31,"value":1209},"忘记清理 watch 监听器",{"type":26,"tag":197,"props":1211,"children":1212},{},[1213],{"type":31,"value":1214},"在 reactive 对象中存储引用类型时不谨慎",{"type":26,"tag":197,"props":1216,"children":1217},{},[1218],{"type":31,"value":1219},"过度复杂化组合式函数",{"type":26,"tag":70,"props":1221,"children":1222},{"id":913},[1223],{"type":31,"value":913},{"type":26,"tag":193,"props":1225,"children":1227},{"className":1226},[485],[1228,1237,1246,1255,1264],{"type":26,"tag":197,"props":1229,"children":1231},{"className":1230},[490],[1232,1235],{"type":26,"tag":493,"props":1233,"children":1234},{"disabled":495,"type":496},[],{"type":31,"value":1236}," 正确使用 ref 和 reactive",{"type":26,"tag":197,"props":1238,"children":1240},{"className":1239},[490],[1241,1244],{"type":26,"tag":493,"props":1242,"children":1243},{"disabled":495,"type":496},[],{"type":31,"value":1245}," 生命周期钩子正确",{"type":26,"tag":197,"props":1247,"children":1249},{"className":1248},[490],[1250,1253],{"type":26,"tag":493,"props":1251,"children":1252},{"disabled":495,"type":496},[],{"type":31,"value":1254}," 模板引用工作正常",{"type":26,"tag":197,"props":1256,"children":1258},{"className":1257},[490],[1259,1262],{"type":26,"tag":493,"props":1260,"children":1261},{"disabled":495,"type":496},[],{"type":31,"value":1263}," 组合式函数可重用",{"type":26,"tag":197,"props":1265,"children":1267},{"className":1266},[490],[1268,1271],{"type":26,"tag":493,"props":1269,"children":1270},{"disabled":495,"type":496},[],{"type":31,"value":955},{"title":7,"searchDepth":641,"depth":641,"links":1273},[1274,1275,1279,1282,1285,1288,1291,1294,1295],{"id":1003,"depth":644,"text":989},{"id":1013,"depth":644,"text":1013,"children":1276},[1277,1278],{"id":1018,"depth":641,"text":1021},{"id":1033,"depth":641,"text":1033},{"id":994,"depth":644,"text":994,"children":1280},[1281],{"id":1051,"depth":641,"text":1051},{"id":1065,"depth":644,"text":1065,"children":1283},[1284],{"id":1070,"depth":641,"text":1073},{"id":1085,"depth":644,"text":1085,"children":1286},[1287],{"id":1090,"depth":641,"text":1093},{"id":1105,"depth":644,"text":1105,"children":1289},[1290],{"id":1110,"depth":641,"text":1110},{"id":1124,"depth":644,"text":1124,"children":1292},[1293],{"id":1129,"depth":641,"text":1132},{"id":828,"depth":644,"text":828},{"id":913,"depth":644,"text":913},"content:topics:frontend:vue3-composition-api.md","topics/frontend/vue3-composition-api.md","topics/frontend/vue3-composition-api",{"_path":1300,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1301,"description":1302,"date":1303,"topic":5,"author":11,"tags":1304,"image":1310,"featured":495,"readingTime":1311,"body":1312,"_type":653,"_id":2573,"_source":655,"_file":2574,"_stem":2575,"_extension":658},"/topics/frontend/rspack-performance-practice","Rspack 构建性能实战","从 Rspack 的架构设计与编译管线出发，系统对比 Webpack/Vite 并给出 Rspack 在大型项目中的迁移路径、性能调优策略与生产级可观测方案。","2026-01-20",[1305,1306,1307,1308,1309],"Rspack","构建工具","性能优化","Webpack","前端工程化","/images/topics/rspack.jpg",25,{"type":23,"children":1313,"toc":2540},[1314,1319,1331,1336,1354,1365,1370,1393,1397,1403,1408,1414,1447,1453,1471,1474,1480,1486,1491,1504,1510,1515,1528,1534,1552,1557,1560,1566,1571,1712,1717,1740,1743,1749,1755,1760,1765,1832,1845,1851,1859,1872,1880,1893,1901,1914,1920,1938,1941,1947,1953,1958,1971,1977,1982,1993,1999,2004,2022,2027,2055,2058,2064,2069,2080,2085,2103,2108,2126,2129,2135,2140,2158,2163,2186,2191,2209,2212,2218,2224,2229,2247,2253,2271,2277,2295,2298,2304,2419,2424,2442,2445,2451,2509,2512,2517,2522],{"type":26,"tag":70,"props":1315,"children":1317},{"id":1316},"rspack-构建性能实战",[1318],{"type":31,"value":1301},{"type":26,"tag":27,"props":1320,"children":1321},{},[1322,1324,1329],{"type":31,"value":1323},"Rspack 不是\"又一个构建工具\"，而是字节跳动在处理",{"type":26,"tag":837,"props":1325,"children":1326},{},[1327],{"type":31,"value":1328},"超大规模前端项目",{"type":31,"value":1330},"时，对 Webpack 生态的 Rust 重写与工程化沉淀。",{"type":26,"tag":27,"props":1332,"children":1333},{},[1334],{"type":31,"value":1335},"它要解决的核心问题是：",{"type":26,"tag":193,"props":1337,"children":1338},{},[1339,1344,1349],{"type":26,"tag":197,"props":1340,"children":1341},{},[1342],{"type":31,"value":1343},"Webpack 的构建速度在大型 monorepo 下（10k+ 模块）已成为开发体验瓶颈",{"type":26,"tag":197,"props":1345,"children":1346},{},[1347],{"type":31,"value":1348},"但你又无法抛弃 Webpack 的插件生态与配置范式",{"type":26,"tag":197,"props":1350,"children":1351},{},[1352],{"type":31,"value":1353},"Vite 虽然快，但在某些场景（大型遗留项目、特定插件依赖）迁移成本高",{"type":26,"tag":27,"props":1355,"children":1356},{},[1357,1359,1364],{"type":31,"value":1358},"Rspack 的定位是：",{"type":26,"tag":837,"props":1360,"children":1361},{},[1362],{"type":31,"value":1363},"Webpack 兼容 API + Rust 性能 + 生产级稳定性",{"type":31,"value":56},{"type":26,"tag":27,"props":1366,"children":1367},{},[1368],{"type":31,"value":1369},"这篇文章不讲\"Hello World\"，而是按\"你要在生产上稳定用 Rspack\"的标准，给出：",{"type":26,"tag":193,"props":1371,"children":1372},{},[1373,1378,1383,1388],{"type":26,"tag":197,"props":1374,"children":1375},{},[1376],{"type":31,"value":1377},"性能收益的真实量化方法",{"type":26,"tag":197,"props":1379,"children":1380},{},[1381],{"type":31,"value":1382},"迁移路径与兼容性边界",{"type":26,"tag":197,"props":1384,"children":1385},{},[1386],{"type":31,"value":1387},"优化策略（缓存、并行、Tree Shaking）",{"type":26,"tag":197,"props":1389,"children":1390},{},[1391],{"type":31,"value":1392},"监控与排障（为什么变慢、为什么产物变大）",{"type":26,"tag":1394,"props":1395,"children":1396},"hr",{},[],{"type":26,"tag":70,"props":1398,"children":1400},{"id":1399},"_1-先回答什么项目值得迁移-rspack",[1401],{"type":31,"value":1402},"1. 先回答：什么项目值得迁移 Rspack？",{"type":26,"tag":27,"props":1404,"children":1405},{},[1406],{"type":31,"value":1407},"不是所有项目都需要 Rspack。",{"type":26,"tag":693,"props":1409,"children":1411},{"id":1410},"_11-高收益场景",[1412],{"type":31,"value":1413},"1.1 高收益场景",{"type":26,"tag":193,"props":1415,"children":1416},{},[1417,1427,1437],{"type":26,"tag":197,"props":1418,"children":1419},{},[1420,1425],{"type":26,"tag":837,"props":1421,"children":1422},{},[1423],{"type":31,"value":1424},"大型 monorepo",{"type":31,"value":1426},"（5k+ 模块，构建时间 > 2 分钟）",{"type":26,"tag":197,"props":1428,"children":1429},{},[1430,1435],{"type":26,"tag":837,"props":1431,"children":1432},{},[1433],{"type":31,"value":1434},"频繁开发迭代",{"type":31,"value":1436},"（HMR 延迟影响体验）",{"type":26,"tag":197,"props":1438,"children":1439},{},[1440,1445],{"type":26,"tag":837,"props":1441,"children":1442},{},[1443],{"type":31,"value":1444},"CI 构建成本高",{"type":31,"value":1446},"（每次 PR 构建超 10 分钟）",{"type":26,"tag":693,"props":1448,"children":1450},{"id":1449},"_12-收益不明显的场景",[1451],{"type":31,"value":1452},"1.2 收益不明显的场景",{"type":26,"tag":193,"props":1454,"children":1455},{},[1456,1461,1466],{"type":26,"tag":197,"props":1457,"children":1458},{},[1459],{"type":31,"value":1460},"小型项目（\u003C 1k 模块）",{"type":26,"tag":197,"props":1462,"children":1463},{},[1464],{"type":31,"value":1465},"已经用 Vite 且体验良好",{"type":26,"tag":197,"props":1467,"children":1468},{},[1469],{"type":31,"value":1470},"高度定制的 Webpack 插件（迁移成本 > 性能收益）",{"type":26,"tag":1394,"props":1472,"children":1473},{},[],{"type":26,"tag":70,"props":1475,"children":1477},{"id":1476},"_2-rspack-的架构为什么能快",[1478],{"type":31,"value":1479},"2. Rspack 的架构：为什么能快？",{"type":26,"tag":693,"props":1481,"children":1483},{"id":1482},"_21-rust-并行编译",[1484],{"type":31,"value":1485},"2.1 Rust 并行编译",{"type":26,"tag":27,"props":1487,"children":1488},{},[1489],{"type":31,"value":1490},"Webpack 是单线程 JavaScript，Rspack 是多线程 Rust。",{"type":26,"tag":193,"props":1492,"children":1493},{},[1494,1499],{"type":26,"tag":197,"props":1495,"children":1496},{},[1497],{"type":31,"value":1498},"模块解析、编译、优化可并行",{"type":26,"tag":197,"props":1500,"children":1501},{},[1502],{"type":31,"value":1503},"I/O 密集型任务（读文件、写产物）异步化",{"type":26,"tag":693,"props":1505,"children":1507},{"id":1506},"_22-更激进的缓存策略",[1508],{"type":31,"value":1509},"2.2 更激进的缓存策略",{"type":26,"tag":27,"props":1511,"children":1512},{},[1513],{"type":31,"value":1514},"Rspack 内置持久化缓存：",{"type":26,"tag":193,"props":1516,"children":1517},{},[1518,1523],{"type":26,"tag":197,"props":1519,"children":1520},{},[1521],{"type":31,"value":1522},"模块级别缓存（类似 Webpack 5 的 cache.type: 'filesystem'）",{"type":26,"tag":197,"props":1524,"children":1525},{},[1526],{"type":31,"value":1527},"但实现更激进：对未变化模块跳过编译",{"type":26,"tag":693,"props":1529,"children":1531},{"id":1530},"_23-内置常用功能减少插件开销",[1532],{"type":31,"value":1533},"2.3 内置常用功能（减少插件开销）",{"type":26,"tag":193,"props":1535,"children":1536},{},[1537,1542,1547],{"type":26,"tag":197,"props":1538,"children":1539},{},[1540],{"type":31,"value":1541},"SWC 替代 Babel（内置 TS/JSX/装饰器）",{"type":26,"tag":197,"props":1543,"children":1544},{},[1545],{"type":31,"value":1546},"CSS Modules、PostCSS 内置",{"type":26,"tag":197,"props":1548,"children":1549},{},[1550],{"type":31,"value":1551},"Tree Shaking 内置",{"type":26,"tag":27,"props":1553,"children":1554},{},[1555],{"type":31,"value":1556},"这让 Rspack 在相同功能下比 Webpack + 插件链路更快。",{"type":26,"tag":1394,"props":1558,"children":1559},{},[],{"type":26,"tag":70,"props":1561,"children":1563},{"id":1562},"_3-性能对比真实场景的量化",[1564],{"type":31,"value":1565},"3. 性能对比：真实场景的量化",{"type":26,"tag":27,"props":1567,"children":1568},{},[1569],{"type":31,"value":1570},"我们用一个典型中型项目（3k 模块，React + TS + CSS Modules）做对比：",{"type":26,"tag":1572,"props":1573,"children":1574},"table",{},[1575,1603],{"type":26,"tag":1576,"props":1577,"children":1578},"thead",{},[1579],{"type":26,"tag":1580,"props":1581,"children":1582},"tr",{},[1583,1589,1594,1598],{"type":26,"tag":1584,"props":1585,"children":1586},"th",{},[1587],{"type":31,"value":1588},"指标",{"type":26,"tag":1584,"props":1590,"children":1591},{},[1592],{"type":31,"value":1593},"Webpack 5",{"type":26,"tag":1584,"props":1595,"children":1596},{},[1597],{"type":31,"value":1305},{"type":26,"tag":1584,"props":1599,"children":1600},{},[1601],{"type":31,"value":1602},"提升",{"type":26,"tag":1604,"props":1605,"children":1606},"tbody",{},[1607,1634,1660,1686],{"type":26,"tag":1580,"props":1608,"children":1609},{},[1610,1616,1621,1626],{"type":26,"tag":1611,"props":1612,"children":1613},"td",{},[1614],{"type":31,"value":1615},"冷启动",{"type":26,"tag":1611,"props":1617,"children":1618},{},[1619],{"type":31,"value":1620},"42s",{"type":26,"tag":1611,"props":1622,"children":1623},{},[1624],{"type":31,"value":1625},"8s",{"type":26,"tag":1611,"props":1627,"children":1628},{},[1629],{"type":26,"tag":837,"props":1630,"children":1631},{},[1632],{"type":31,"value":1633},"5.2x",{"type":26,"tag":1580,"props":1635,"children":1636},{},[1637,1642,1647,1652],{"type":26,"tag":1611,"props":1638,"children":1639},{},[1640],{"type":31,"value":1641},"HMR（热更新）",{"type":26,"tag":1611,"props":1643,"children":1644},{},[1645],{"type":31,"value":1646},"1.2s",{"type":26,"tag":1611,"props":1648,"children":1649},{},[1650],{"type":31,"value":1651},"0.15s",{"type":26,"tag":1611,"props":1653,"children":1654},{},[1655],{"type":26,"tag":837,"props":1656,"children":1657},{},[1658],{"type":31,"value":1659},"8x",{"type":26,"tag":1580,"props":1661,"children":1662},{},[1663,1668,1673,1678],{"type":26,"tag":1611,"props":1664,"children":1665},{},[1666],{"type":31,"value":1667},"生产构建",{"type":26,"tag":1611,"props":1669,"children":1670},{},[1671],{"type":31,"value":1672},"125s",{"type":26,"tag":1611,"props":1674,"children":1675},{},[1676],{"type":31,"value":1677},"28s",{"type":26,"tag":1611,"props":1679,"children":1680},{},[1681],{"type":26,"tag":837,"props":1682,"children":1683},{},[1684],{"type":31,"value":1685},"4.5x",{"type":26,"tag":1580,"props":1687,"children":1688},{},[1689,1694,1699,1704],{"type":26,"tag":1611,"props":1690,"children":1691},{},[1692],{"type":31,"value":1693},"内存峰值",{"type":26,"tag":1611,"props":1695,"children":1696},{},[1697],{"type":31,"value":1698},"1.8GB",{"type":26,"tag":1611,"props":1700,"children":1701},{},[1702],{"type":31,"value":1703},"0.9GB",{"type":26,"tag":1611,"props":1705,"children":1706},{},[1707],{"type":26,"tag":837,"props":1708,"children":1709},{},[1710],{"type":31,"value":1711},"2x",{"type":26,"tag":27,"props":1713,"children":1714},{},[1715],{"type":31,"value":1716},"关键收益：",{"type":26,"tag":193,"props":1718,"children":1719},{},[1720,1730],{"type":26,"tag":197,"props":1721,"children":1722},{},[1723,1728],{"type":26,"tag":837,"props":1724,"children":1725},{},[1726],{"type":31,"value":1727},"开发体验质变",{"type":31,"value":1729},"（HMR \u003C 200ms）",{"type":26,"tag":197,"props":1731,"children":1732},{},[1733,1738],{"type":26,"tag":837,"props":1734,"children":1735},{},[1736],{"type":31,"value":1737},"CI 成本减半",{"type":31,"value":1739},"（构建时间直接影响 Runner 费用）",{"type":26,"tag":1394,"props":1741,"children":1742},{},[],{"type":26,"tag":70,"props":1744,"children":1746},{"id":1745},"_4-迁移路径从-webpack-到-rspack",[1747],{"type":31,"value":1748},"4. 迁移路径：从 Webpack 到 Rspack",{"type":26,"tag":693,"props":1750,"children":1752},{"id":1751},"_41-最小迁移保守策略",[1753],{"type":31,"value":1754},"4.1 最小迁移（保守策略）",{"type":26,"tag":27,"props":1756,"children":1757},{},[1758],{"type":31,"value":1759},"目标：用最小改动换取性能收益。",{"type":26,"tag":27,"props":1761,"children":1762},{},[1763],{"type":31,"value":1764},"步骤：",{"type":26,"tag":298,"props":1766,"children":1767},{},[1768,1787,1806,1827],{"type":26,"tag":197,"props":1769,"children":1770},{},[1771,1773,1779,1781],{"type":31,"value":1772},"安装 ",{"type":26,"tag":34,"props":1774,"children":1776},{"className":1775},[],[1777],{"type":31,"value":1778},"@rspack/cli",{"type":31,"value":1780}," 与 ",{"type":26,"tag":34,"props":1782,"children":1784},{"className":1783},[],[1785],{"type":31,"value":1786},"@rspack/core",{"type":26,"tag":197,"props":1788,"children":1789},{},[1790,1792,1798,1800],{"type":31,"value":1791},"把 ",{"type":26,"tag":34,"props":1793,"children":1795},{"className":1794},[],[1796],{"type":31,"value":1797},"webpack.config.js",{"type":31,"value":1799}," 改为 ",{"type":26,"tag":34,"props":1801,"children":1803},{"className":1802},[],[1804],{"type":31,"value":1805},"rspack.config.js",{"type":26,"tag":197,"props":1807,"children":1808},{},[1809,1811,1817,1819,1825],{"type":31,"value":1810},"替换构建命令（",{"type":26,"tag":34,"props":1812,"children":1814},{"className":1813},[],[1815],{"type":31,"value":1816},"rspack build",{"type":31,"value":1818}," / ",{"type":26,"tag":34,"props":1820,"children":1822},{"className":1821},[],[1823],{"type":31,"value":1824},"rspack dev",{"type":31,"value":1826},"）",{"type":26,"tag":197,"props":1828,"children":1829},{},[1830],{"type":31,"value":1831},"运行并修复兼容性问题",{"type":26,"tag":27,"props":1833,"children":1834},{},[1835,1837,1843],{"type":31,"value":1836},"预计迁移成本：1",{"type":26,"tag":1838,"props":1839,"children":1840},"del",{},[1841],{"type":31,"value":1842},"2 天（小型项目）/ 1",{"type":31,"value":1844},"2 周（大型项目）",{"type":26,"tag":693,"props":1846,"children":1848},{"id":1847},"_42-兼容性边界哪些需要调整",[1849],{"type":31,"value":1850},"4.2 兼容性边界：哪些需要调整",{"type":26,"tag":27,"props":1852,"children":1853},{},[1854],{"type":26,"tag":837,"props":1855,"children":1856},{},[1857],{"type":31,"value":1858},"插件兼容",{"type":26,"tag":193,"props":1860,"children":1861},{},[1862,1867],{"type":26,"tag":197,"props":1863,"children":1864},{},[1865],{"type":31,"value":1866},"Rspack 支持大部分 Webpack 插件（API 兼容）",{"type":26,"tag":197,"props":1868,"children":1869},{},[1870],{"type":31,"value":1871},"但少数复杂插件（例如深度依赖 Webpack 内部 API）需要适配",{"type":26,"tag":27,"props":1873,"children":1874},{},[1875],{"type":26,"tag":837,"props":1876,"children":1877},{},[1878],{"type":31,"value":1879},"Loader 兼容",{"type":26,"tag":193,"props":1881,"children":1882},{},[1883,1888],{"type":26,"tag":197,"props":1884,"children":1885},{},[1886],{"type":31,"value":1887},"常用 loader（babel-loader、css-loader、postcss-loader）兼容",{"type":26,"tag":197,"props":1889,"children":1890},{},[1891],{"type":31,"value":1892},"部分自定义 loader 需要测试",{"type":26,"tag":27,"props":1894,"children":1895},{},[1896],{"type":26,"tag":837,"props":1897,"children":1898},{},[1899],{"type":31,"value":1900},"配置差异",{"type":26,"tag":193,"props":1902,"children":1903},{},[1904,1909],{"type":26,"tag":197,"props":1905,"children":1906},{},[1907],{"type":31,"value":1908},"resolve、output、optimization 等配置与 Webpack 高度一致",{"type":26,"tag":197,"props":1910,"children":1911},{},[1912],{"type":31,"value":1913},"少数高级配置需要查文档",{"type":26,"tag":693,"props":1915,"children":1917},{"id":1916},"_43-推荐的迁移节奏",[1918],{"type":31,"value":1919},"4.3 推荐的迁移节奏",{"type":26,"tag":193,"props":1921,"children":1922},{},[1923,1928,1933],{"type":26,"tag":197,"props":1924,"children":1925},{},[1926],{"type":31,"value":1927},"Week 1：本地开发环境先行",{"type":26,"tag":197,"props":1929,"children":1930},{},[1931],{"type":31,"value":1932},"Week 2：CI 构建切换（并保留 Webpack 作为 fallback）",{"type":26,"tag":197,"props":1934,"children":1935},{},[1936],{"type":31,"value":1937},"Week 3~4：生产构建切换并观测",{"type":26,"tag":1394,"props":1939,"children":1940},{},[],{"type":26,"tag":70,"props":1942,"children":1944},{"id":1943},"_5-性能调优让-rspack-更快",[1945],{"type":31,"value":1946},"5. 性能调优：让 Rspack 更快",{"type":26,"tag":693,"props":1948,"children":1950},{"id":1949},"_51-缓存策略",[1951],{"type":31,"value":1952},"5.1 缓存策略",{"type":26,"tag":27,"props":1954,"children":1955},{},[1956],{"type":31,"value":1957},"默认缓存已经很激进，但你可以：",{"type":26,"tag":193,"props":1959,"children":1960},{},[1961,1966],{"type":26,"tag":197,"props":1962,"children":1963},{},[1964],{"type":31,"value":1965},"显式配置缓存目录（例如挂载 SSD）",{"type":26,"tag":197,"props":1967,"children":1968},{},[1969],{"type":31,"value":1970},"在 CI 上持久化缓存（例如用 actions/cache）",{"type":26,"tag":693,"props":1972,"children":1974},{"id":1973},"_52-并行度调优",[1975],{"type":31,"value":1976},"5.2 并行度调优",{"type":26,"tag":27,"props":1978,"children":1979},{},[1980],{"type":31,"value":1981},"Rspack 默认会用所有 CPU 核心，但在容器环境（例如 CI）可能需要限制：",{"type":26,"tag":98,"props":1983,"children":1988},{"className":1984,"code":1986,"language":1987,"meta":7},[1985],"language-js","module.exports = {\n  experiments: {\n    rspackFuture: {\n      disableTransformByDefault: true, // 减少不必要转换\n    },\n  },\n}\n","js",[1989],{"type":26,"tag":34,"props":1990,"children":1991},{"__ignoreMap":7},[1992],{"type":31,"value":1986},{"type":26,"tag":693,"props":1994,"children":1996},{"id":1995},"_53-tree-shaking-与-dead-code-elimination",[1997],{"type":31,"value":1998},"5.3 Tree Shaking 与 Dead Code Elimination",{"type":26,"tag":27,"props":2000,"children":2001},{},[2002],{"type":31,"value":2003},"Rspack 内置 Tree Shaking，但效果取决于：",{"type":26,"tag":193,"props":2005,"children":2006},{},[2007,2012,2017],{"type":26,"tag":197,"props":2008,"children":2009},{},[2010],{"type":31,"value":2011},"是否使用 ESM（而非 CommonJS）",{"type":26,"tag":197,"props":2013,"children":2014},{},[2015],{"type":31,"value":2016},"副作用标记（sideEffects: false）",{"type":26,"tag":197,"props":2018,"children":2019},{},[2020],{"type":31,"value":2021},"动态 import 的拆分策略",{"type":26,"tag":27,"props":2023,"children":2024},{},[2025],{"type":31,"value":2026},"建议：",{"type":26,"tag":193,"props":2028,"children":2029},{},[2030,2043],{"type":26,"tag":197,"props":2031,"children":2032},{},[2033,2035,2041],{"type":31,"value":2034},"对第三方库检查 ",{"type":26,"tag":34,"props":2036,"children":2038},{"className":2037},[],[2039],{"type":31,"value":2040},"sideEffects",{"type":31,"value":2042}," 配置",{"type":26,"tag":197,"props":2044,"children":2045},{},[2046,2048,2054],{"type":31,"value":2047},"避免\"全量引入后 tree shake\"（例如 ",{"type":26,"tag":34,"props":2049,"children":2051},{"className":2050},[],[2052],{"type":31,"value":2053},"import * from 'lodash'",{"type":31,"value":1826},{"type":26,"tag":1394,"props":2056,"children":2057},{},[],{"type":26,"tag":70,"props":2059,"children":2061},{"id":2060},"_6-产物分析与优化",[2062],{"type":31,"value":2063},"6. 产物分析与优化",{"type":26,"tag":27,"props":2065,"children":2066},{},[2067],{"type":31,"value":2068},"Rspack 提供内置分析工具：",{"type":26,"tag":98,"props":2070,"children":2075},{"className":2071,"code":2073,"language":2074,"meta":7},[2072],"language-bash","rspack build --analyze\n","bash",[2076],{"type":26,"tag":34,"props":2077,"children":2078},{"__ignoreMap":7},[2079],{"type":31,"value":2073},{"type":26,"tag":27,"props":2081,"children":2082},{},[2083],{"type":31,"value":2084},"关键指标：",{"type":26,"tag":193,"props":2086,"children":2087},{},[2088,2093,2098],{"type":26,"tag":197,"props":2089,"children":2090},{},[2091],{"type":31,"value":2092},"各 chunk 体积分布",{"type":26,"tag":197,"props":2094,"children":2095},{},[2096],{"type":31,"value":2097},"重复依赖（例如多个版本的 lodash）",{"type":26,"tag":197,"props":2099,"children":2100},{},[2101],{"type":31,"value":2102},"未被 tree shake 的代码",{"type":26,"tag":27,"props":2104,"children":2105},{},[2106],{"type":31,"value":2107},"优化策略：",{"type":26,"tag":193,"props":2109,"children":2110},{},[2111,2116,2121],{"type":26,"tag":197,"props":2112,"children":2113},{},[2114],{"type":31,"value":2115},"拆分 vendor chunk（按更新频率）",{"type":26,"tag":197,"props":2117,"children":2118},{},[2119],{"type":31,"value":2120},"对大型库按需引入（例如 antd/lodash-es）",{"type":26,"tag":197,"props":2122,"children":2123},{},[2124],{"type":31,"value":2125},"检查动态 import 的粒度",{"type":26,"tag":1394,"props":2127,"children":2128},{},[],{"type":26,"tag":70,"props":2130,"children":2132},{"id":2131},"_7-生产可观测性让构建可量化",[2133],{"type":31,"value":2134},"7. 生产可观测性：让构建可量化",{"type":26,"tag":27,"props":2136,"children":2137},{},[2138],{"type":31,"value":2139},"在 CI/CD 里，你需要能回答：",{"type":26,"tag":193,"props":2141,"children":2142},{},[2143,2148,2153],{"type":26,"tag":197,"props":2144,"children":2145},{},[2146],{"type":31,"value":2147},"这次构建为什么变慢？",{"type":26,"tag":197,"props":2149,"children":2150},{},[2151],{"type":31,"value":2152},"产物为什么变大？",{"type":26,"tag":197,"props":2154,"children":2155},{},[2156],{"type":31,"value":2157},"哪个模块耗时最多？",{"type":26,"tag":27,"props":2159,"children":2160},{},[2161],{"type":31,"value":2162},"建议在 CI 里记录：",{"type":26,"tag":193,"props":2164,"children":2165},{},[2166,2171,2176,2181],{"type":26,"tag":197,"props":2167,"children":2168},{},[2169],{"type":31,"value":2170},"构建总耗时",{"type":26,"tag":197,"props":2172,"children":2173},{},[2174],{"type":31,"value":2175},"各阶段耗时（resolve、compile、optimize、emit）",{"type":26,"tag":197,"props":2177,"children":2178},{},[2179],{"type":31,"value":2180},"产物体积（按 chunk）",{"type":26,"tag":197,"props":2182,"children":2183},{},[2184],{"type":31,"value":2185},"缓存命中率",{"type":26,"tag":27,"props":2187,"children":2188},{},[2189],{"type":31,"value":2190},"落地方式：",{"type":26,"tag":193,"props":2192,"children":2193},{},[2194,2199,2204],{"type":26,"tag":197,"props":2195,"children":2196},{},[2197],{"type":31,"value":2198},"用 Rspack 的 stats 输出",{"type":26,"tag":197,"props":2200,"children":2201},{},[2202],{"type":31,"value":2203},"在 CI 日志里保留关键指标",{"type":26,"tag":197,"props":2205,"children":2206},{},[2207],{"type":31,"value":2208},"对产物体积做 baseline 对比（变化 > 5% 报警）",{"type":26,"tag":1394,"props":2210,"children":2211},{},[],{"type":26,"tag":70,"props":2213,"children":2215},{"id":2214},"_8-常见问题排查",[2216],{"type":31,"value":2217},"8. 常见问题排查",{"type":26,"tag":693,"props":2219,"children":2221},{"id":2220},"_81-迁移后变慢了",[2222],{"type":31,"value":2223},"8.1 \"迁移后变慢了\"",{"type":26,"tag":27,"props":2225,"children":2226},{},[2227],{"type":31,"value":2228},"排查顺序：",{"type":26,"tag":193,"props":2230,"children":2231},{},[2232,2237,2242],{"type":26,"tag":197,"props":2233,"children":2234},{},[2235],{"type":31,"value":2236},"缓存是否生效（首次构建慢正常）",{"type":26,"tag":197,"props":2238,"children":2239},{},[2240],{"type":31,"value":2241},"是否有 loader 拖慢（例如未优化的自定义 loader）",{"type":26,"tag":197,"props":2243,"children":2244},{},[2245],{"type":31,"value":2246},"并行度是否受限（例如 CI 限制 CPU）",{"type":26,"tag":693,"props":2248,"children":2250},{"id":2249},"_82-产物体积变大了",[2251],{"type":31,"value":2252},"8.2 \"产物体积变大了\"",{"type":26,"tag":193,"props":2254,"children":2255},{},[2256,2261,2266],{"type":26,"tag":197,"props":2257,"children":2258},{},[2259],{"type":31,"value":2260},"检查 Tree Shaking 是否生效",{"type":26,"tag":197,"props":2262,"children":2263},{},[2264],{"type":31,"value":2265},"检查是否引入了更多 polyfill",{"type":26,"tag":197,"props":2267,"children":2268},{},[2269],{"type":31,"value":2270},"对比 chunk 分布（用 analyze）",{"type":26,"tag":693,"props":2272,"children":2274},{"id":2273},"_83-某些模块编译失败",[2275],{"type":31,"value":2276},"8.3 \"某些模块编译失败\"",{"type":26,"tag":193,"props":2278,"children":2279},{},[2280,2285,2290],{"type":26,"tag":197,"props":2281,"children":2282},{},[2283],{"type":31,"value":2284},"检查是否依赖 Webpack 特定 API",{"type":26,"tag":197,"props":2286,"children":2287},{},[2288],{"type":31,"value":2289},"查看 Rspack 官方兼容性列表",{"type":26,"tag":197,"props":2291,"children":2292},{},[2293],{"type":31,"value":2294},"在 GitHub Issues 搜索类似问题",{"type":26,"tag":1394,"props":2296,"children":2297},{},[],{"type":26,"tag":70,"props":2299,"children":2301},{"id":2300},"_9-rspack-vs-vite什么时候选哪个",[2302],{"type":31,"value":2303},"9. Rspack vs Vite：什么时候选哪个？",{"type":26,"tag":1572,"props":2305,"children":2306},{},[2307,2327],{"type":26,"tag":1576,"props":2308,"children":2309},{},[2310],{"type":26,"tag":1580,"props":2311,"children":2312},{},[2313,2318,2322],{"type":26,"tag":1584,"props":2314,"children":2315},{},[2316],{"type":31,"value":2317},"维度",{"type":26,"tag":1584,"props":2319,"children":2320},{},[2321],{"type":31,"value":1305},{"type":26,"tag":1584,"props":2323,"children":2324},{},[2325],{"type":31,"value":2326},"Vite",{"type":26,"tag":1604,"props":2328,"children":2329},{},[2330,2348,2365,2383,2401],{"type":26,"tag":1580,"props":2331,"children":2332},{},[2333,2338,2343],{"type":26,"tag":1611,"props":2334,"children":2335},{},[2336],{"type":31,"value":2337},"开发速度",{"type":26,"tag":1611,"props":2339,"children":2340},{},[2341],{"type":31,"value":2342},"极快（Rust 编译）",{"type":26,"tag":1611,"props":2344,"children":2345},{},[2346],{"type":31,"value":2347},"极快（ESM 直连）",{"type":26,"tag":1580,"props":2349,"children":2350},{},[2351,2355,2360],{"type":26,"tag":1611,"props":2352,"children":2353},{},[2354],{"type":31,"value":1667},{"type":26,"tag":1611,"props":2356,"children":2357},{},[2358],{"type":31,"value":2359},"快（全量编译优化）",{"type":26,"tag":1611,"props":2361,"children":2362},{},[2363],{"type":31,"value":2364},"快（Rollup）",{"type":26,"tag":1580,"props":2366,"children":2367},{},[2368,2373,2378],{"type":26,"tag":1611,"props":2369,"children":2370},{},[2371],{"type":31,"value":2372},"Webpack 兼容",{"type":26,"tag":1611,"props":2374,"children":2375},{},[2376],{"type":31,"value":2377},"高",{"type":26,"tag":1611,"props":2379,"children":2380},{},[2381],{"type":31,"value":2382},"低",{"type":26,"tag":1580,"props":2384,"children":2385},{},[2386,2391,2396],{"type":26,"tag":1611,"props":2387,"children":2388},{},[2389],{"type":31,"value":2390},"插件生态",{"type":26,"tag":1611,"props":2392,"children":2393},{},[2394],{"type":31,"value":2395},"Webpack 生态",{"type":26,"tag":1611,"props":2397,"children":2398},{},[2399],{"type":31,"value":2400},"Rollup/Vite 生态",{"type":26,"tag":1580,"props":2402,"children":2403},{},[2404,2409,2414],{"type":26,"tag":1611,"props":2405,"children":2406},{},[2407],{"type":31,"value":2408},"适用项目",{"type":26,"tag":1611,"props":2410,"children":2411},{},[2412],{"type":31,"value":2413},"Webpack 迁移、大型 monorepo",{"type":26,"tag":1611,"props":2415,"children":2416},{},[2417],{"type":31,"value":2418},"新项目、中小型",{"type":26,"tag":27,"props":2420,"children":2421},{},[2422],{"type":31,"value":2423},"选择建议：",{"type":26,"tag":193,"props":2425,"children":2426},{},[2427,2432,2437],{"type":26,"tag":197,"props":2428,"children":2429},{},[2430],{"type":31,"value":2431},"新项目：优先 Vite",{"type":26,"tag":197,"props":2433,"children":2434},{},[2435],{"type":31,"value":2436},"Webpack 遗留项目：Rspack",{"type":26,"tag":197,"props":2438,"children":2439},{},[2440],{"type":31,"value":2441},"大型 monorepo + Webpack 依赖：Rspack",{"type":26,"tag":1394,"props":2443,"children":2444},{},[],{"type":26,"tag":70,"props":2446,"children":2448},{"id":2447},"_10-上线检查清单",[2449],{"type":31,"value":2450},"10. 上线检查清单",{"type":26,"tag":193,"props":2452,"children":2454},{"className":2453},[485],[2455,2464,2473,2482,2491,2500],{"type":26,"tag":197,"props":2456,"children":2458},{"className":2457},[490],[2459,2462],{"type":26,"tag":493,"props":2460,"children":2461},{"disabled":495,"type":496},[],{"type":31,"value":2463}," 本地开发环境已验证（HMR/热更新正常）",{"type":26,"tag":197,"props":2465,"children":2467},{"className":2466},[490],[2468,2471],{"type":26,"tag":493,"props":2469,"children":2470},{"disabled":495,"type":496},[],{"type":31,"value":2472}," CI 构建已切换并观测 3 天以上",{"type":26,"tag":197,"props":2474,"children":2476},{"className":2475},[490],[2477,2480],{"type":26,"tag":493,"props":2478,"children":2479},{"disabled":495,"type":496},[],{"type":31,"value":2481}," 产物体积对比无异常（baseline ± 5%）",{"type":26,"tag":197,"props":2483,"children":2485},{"className":2484},[490],[2486,2489],{"type":26,"tag":493,"props":2487,"children":2488},{"disabled":495,"type":496},[],{"type":31,"value":2490}," 关键页面功能回归测试通过",{"type":26,"tag":197,"props":2492,"children":2494},{"className":2493},[490],[2495,2498],{"type":26,"tag":493,"props":2496,"children":2497},{"disabled":495,"type":496},[],{"type":31,"value":2499}," 有构建耗时与缓存命中率监控",{"type":26,"tag":197,"props":2501,"children":2503},{"className":2502},[490],[2504,2507],{"type":26,"tag":493,"props":2505,"children":2506},{"disabled":495,"type":496},[],{"type":31,"value":2508}," 有回滚方案（保留 Webpack 配置）",{"type":26,"tag":1394,"props":2510,"children":2511},{},[],{"type":26,"tag":70,"props":2513,"children":2515},{"id":2514},"总结",[2516],{"type":31,"value":2514},{"type":26,"tag":27,"props":2518,"children":2519},{},[2520],{"type":31,"value":2521},"Rspack 的核心价值是：",{"type":26,"tag":193,"props":2523,"children":2524},{},[2525,2530,2535],{"type":26,"tag":197,"props":2526,"children":2527},{},[2528],{"type":31,"value":2529},"在 Webpack 生态下获得接近 Vite 的速度",{"type":26,"tag":197,"props":2531,"children":2532},{},[2533],{"type":31,"value":2534},"对大型项目构建成本与开发体验的显著改善",{"type":26,"tag":197,"props":2536,"children":2537},{},[2538],{"type":31,"value":2539},"生产级稳定性（字节跳动内部大规模验证）",{"title":7,"searchDepth":641,"depth":641,"links":2541},[2542,2543,2547,2552,2553,2558,2563,2564,2565,2570,2571,2572],{"id":1316,"depth":644,"text":1301},{"id":1399,"depth":644,"text":1402,"children":2544},[2545,2546],{"id":1410,"depth":641,"text":1413},{"id":1449,"depth":641,"text":1452},{"id":1476,"depth":644,"text":1479,"children":2548},[2549,2550,2551],{"id":1482,"depth":641,"text":1485},{"id":1506,"depth":641,"text":1509},{"id":1530,"depth":641,"text":1533},{"id":1562,"depth":644,"text":1565},{"id":1745,"depth":644,"text":1748,"children":2554},[2555,2556,2557],{"id":1751,"depth":641,"text":1754},{"id":1847,"depth":641,"text":1850},{"id":1916,"depth":641,"text":1919},{"id":1943,"depth":644,"text":1946,"children":2559},[2560,2561,2562],{"id":1949,"depth":641,"text":1952},{"id":1973,"depth":641,"text":1976},{"id":1995,"depth":641,"text":1998},{"id":2060,"depth":644,"text":2063},{"id":2131,"depth":644,"text":2134},{"id":2214,"depth":644,"text":2217,"children":2566},[2567,2568,2569],{"id":2220,"depth":641,"text":2223},{"id":2249,"depth":641,"text":2252},{"id":2273,"depth":641,"text":2276},{"id":2300,"depth":644,"text":2303},{"id":2447,"depth":644,"text":2450},{"id":2514,"depth":644,"text":2514},"content:topics:frontend:rspack-performance-practice.md","topics/frontend/rspack-performance-practice.md","topics/frontend/rspack-performance-practice",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":2577,"image":17,"imageQuery":18,"pexelsPhotoId":19,"pexelsUrl":20,"featured":6,"readingTime":21,"body":2578,"_type":653,"_id":654,"_source":655,"_file":656,"_stem":657,"_extension":658},[13,14,15,16],{"type":23,"children":2579,"toc":3072},[2580,2602,2612,2616,2632,2640,2662,2666,2670,2678,2688,2692,2696,2706,2735,2739,2747,2757,2761,2765,2769,2777,2781,2785,2789,2813,2817,2825,2829,2833,2842,2861,2865,2869,2891,2895,2928,2938,2942,3018,3022,3037,3041],{"type":26,"tag":27,"props":2581,"children":2582},{},[2583,2584,2589,2590,2595,2596,2601],{"type":31,"value":32},{"type":26,"tag":34,"props":2585,"children":2587},{"className":2586},[],[2588],{"type":31,"value":39},{"type":31,"value":41},{"type":26,"tag":34,"props":2591,"children":2593},{"className":2592},[],[2594],{"type":31,"value":47},{"type":31,"value":49},{"type":26,"tag":34,"props":2597,"children":2599},{"className":2598},[],[2600],{"type":31,"value":14},{"type":31,"value":56},{"type":26,"tag":27,"props":2603,"children":2604},{},[2605,2606,2611],{"type":31,"value":61},{"type":26,"tag":34,"props":2607,"children":2609},{"className":2608},[],[2610],{"type":31,"value":14},{"type":31,"value":68},{"type":26,"tag":70,"props":2613,"children":2614},{"id":72},[2615],{"type":31,"value":75},{"type":26,"tag":27,"props":2617,"children":2618},{},[2619,2620,2625,2626,2631],{"type":31,"value":80},{"type":26,"tag":34,"props":2621,"children":2623},{"className":2622},[],[2624],{"type":31,"value":86},{"type":31,"value":88},{"type":26,"tag":34,"props":2627,"children":2629},{"className":2628},[],[2630],{"type":31,"value":94},{"type":31,"value":96},{"type":26,"tag":98,"props":2633,"children":2635},{"className":2634,"code":102,"language":103,"meta":7},[101],[2636],{"type":26,"tag":34,"props":2637,"children":2638},{"__ignoreMap":7},[2639],{"type":31,"value":102},{"type":26,"tag":27,"props":2641,"children":2642},{},[2643,2644,2649,2650,2655,2656,2661],{"type":31,"value":113},{"type":26,"tag":34,"props":2645,"children":2647},{"className":2646},[],[2648],{"type":31,"value":119},{"type":31,"value":121},{"type":26,"tag":34,"props":2651,"children":2653},{"className":2652},[],[2654],{"type":31,"value":94},{"type":31,"value":128},{"type":26,"tag":34,"props":2657,"children":2659},{"className":2658},[],[2660],{"type":31,"value":134},{"type":31,"value":136},{"type":26,"tag":70,"props":2663,"children":2664},{"id":139},[2665],{"type":31,"value":142},{"type":26,"tag":27,"props":2667,"children":2668},{},[2669],{"type":31,"value":147},{"type":26,"tag":98,"props":2671,"children":2673},{"className":2672,"code":151,"language":103,"meta":7},[101],[2674],{"type":26,"tag":34,"props":2675,"children":2676},{"__ignoreMap":7},[2677],{"type":31,"value":151},{"type":26,"tag":27,"props":2679,"children":2680},{},[2681,2682,2687],{"type":31,"value":161},{"type":26,"tag":34,"props":2683,"children":2685},{"className":2684},[],[2686],{"type":31,"value":86},{"type":31,"value":168},{"type":26,"tag":27,"props":2689,"children":2690},{},[2691],{"type":31,"value":173},{"type":26,"tag":70,"props":2693,"children":2694},{"id":176},[2695],{"type":31,"value":179},{"type":26,"tag":27,"props":2697,"children":2698},{},[2699,2700,2705],{"type":31,"value":184},{"type":26,"tag":34,"props":2701,"children":2703},{"className":2702},[],[2704],{"type":31,"value":119},{"type":31,"value":191},{"type":26,"tag":193,"props":2707,"children":2708},{},[2709,2713,2717,2726],{"type":26,"tag":197,"props":2710,"children":2711},{},[2712],{"type":31,"value":201},{"type":26,"tag":197,"props":2714,"children":2715},{},[2716],{"type":31,"value":206},{"type":26,"tag":197,"props":2718,"children":2719},{},[2720,2721],{"type":31,"value":211},{"type":26,"tag":34,"props":2722,"children":2724},{"className":2723},[],[2725],{"type":31,"value":217},{"type":26,"tag":197,"props":2727,"children":2728},{},[2729,2730],{"type":31,"value":222},{"type":26,"tag":34,"props":2731,"children":2733},{"className":2732},[],[2734],{"type":31,"value":228},{"type":26,"tag":27,"props":2736,"children":2737},{},[2738],{"type":31,"value":233},{"type":26,"tag":98,"props":2740,"children":2742},{"className":2741,"code":237,"language":103,"meta":7},[101],[2743],{"type":26,"tag":34,"props":2744,"children":2745},{"__ignoreMap":7},[2746],{"type":31,"value":237},{"type":26,"tag":27,"props":2748,"children":2749},{},[2750,2751,2756],{"type":31,"value":247},{"type":26,"tag":34,"props":2752,"children":2754},{"className":2753},[],[2755],{"type":31,"value":253},{"type":31,"value":255},{"type":26,"tag":70,"props":2758,"children":2759},{"id":258},[2760],{"type":31,"value":261},{"type":26,"tag":27,"props":2762,"children":2763},{},[2764],{"type":31,"value":266},{"type":26,"tag":27,"props":2766,"children":2767},{},[2768],{"type":31,"value":271},{"type":26,"tag":98,"props":2770,"children":2772},{"className":2771,"code":275,"language":103,"meta":7},[101],[2773],{"type":26,"tag":34,"props":2774,"children":2775},{"__ignoreMap":7},[2776],{"type":31,"value":275},{"type":26,"tag":27,"props":2778,"children":2779},{},[2780],{"type":31,"value":285},{"type":26,"tag":70,"props":2782,"children":2783},{"id":288},[2784],{"type":31,"value":291},{"type":26,"tag":27,"props":2786,"children":2787},{},[2788],{"type":31,"value":296},{"type":26,"tag":298,"props":2790,"children":2791},{},[2792,2796,2800,2809],{"type":26,"tag":197,"props":2793,"children":2794},{},[2795],{"type":31,"value":305},{"type":26,"tag":197,"props":2797,"children":2798},{},[2799],{"type":31,"value":310},{"type":26,"tag":197,"props":2801,"children":2802},{},[2803,2804],{"type":31,"value":315},{"type":26,"tag":34,"props":2805,"children":2807},{"className":2806},[],[2808],{"type":31,"value":253},{"type":26,"tag":197,"props":2810,"children":2811},{},[2812],{"type":31,"value":325},{"type":26,"tag":27,"props":2814,"children":2815},{},[2816],{"type":31,"value":330},{"type":26,"tag":98,"props":2818,"children":2820},{"className":2819,"code":334,"language":103,"meta":7},[101],[2821],{"type":26,"tag":34,"props":2822,"children":2823},{"__ignoreMap":7},[2824],{"type":31,"value":334},{"type":26,"tag":27,"props":2826,"children":2827},{},[2828],{"type":31,"value":344},{"type":26,"tag":70,"props":2830,"children":2831},{"id":347},[2832],{"type":31,"value":350},{"type":26,"tag":27,"props":2834,"children":2835},{},[2836,2841],{"type":26,"tag":34,"props":2837,"children":2839},{"className":2838},[],[2840],{"type":31,"value":47},{"type":31,"value":360},{"type":26,"tag":193,"props":2843,"children":2844},{},[2845,2849,2853,2857],{"type":26,"tag":197,"props":2846,"children":2847},{},[2848],{"type":31,"value":368},{"type":26,"tag":197,"props":2850,"children":2851},{},[2852],{"type":31,"value":373},{"type":26,"tag":197,"props":2854,"children":2855},{},[2856],{"type":31,"value":378},{"type":26,"tag":197,"props":2858,"children":2859},{},[2860],{"type":31,"value":383},{"type":26,"tag":27,"props":2862,"children":2863},{},[2864],{"type":31,"value":388},{"type":26,"tag":70,"props":2866,"children":2867},{"id":391},[2868],{"type":31,"value":394},{"type":26,"tag":27,"props":2870,"children":2871},{},[2872,2873,2878,2879,2884,2885,2890],{"type":31,"value":399},{"type":26,"tag":34,"props":2874,"children":2876},{"className":2875},[],[2877],{"type":31,"value":134},{"type":31,"value":406},{"type":26,"tag":34,"props":2880,"children":2882},{"className":2881},[],[2883],{"type":31,"value":412},{"type":31,"value":414},{"type":26,"tag":34,"props":2886,"children":2888},{"className":2887},[],[2889],{"type":31,"value":86},{"type":31,"value":56},{"type":26,"tag":27,"props":2892,"children":2893},{},[2894],{"type":31,"value":425},{"type":26,"tag":298,"props":2896,"children":2897},{},[2898,2907,2911,2920,2924],{"type":26,"tag":197,"props":2899,"children":2900},{},[2901,2902],{"type":31,"value":433},{"type":26,"tag":34,"props":2903,"children":2905},{"className":2904},[],[2906],{"type":31,"value":119},{"type":26,"tag":197,"props":2908,"children":2909},{},[2910],{"type":31,"value":443},{"type":26,"tag":197,"props":2912,"children":2913},{},[2914,2915],{"type":31,"value":448},{"type":26,"tag":34,"props":2916,"children":2918},{"className":2917},[],[2919],{"type":31,"value":228},{"type":26,"tag":197,"props":2921,"children":2922},{},[2923],{"type":31,"value":458},{"type":26,"tag":197,"props":2925,"children":2926},{},[2927],{"type":31,"value":463},{"type":26,"tag":27,"props":2929,"children":2930},{},[2931,2932,2937],{"type":31,"value":468},{"type":26,"tag":34,"props":2933,"children":2935},{"className":2934},[],[2936],{"type":31,"value":47},{"type":31,"value":475},{"type":26,"tag":70,"props":2939,"children":2940},{"id":478},[2941],{"type":31,"value":481},{"type":26,"tag":193,"props":2943,"children":2945},{"className":2944},[485],[2946,2959,2967,2980,2988,2996,3010],{"type":26,"tag":197,"props":2947,"children":2949},{"className":2948},[490],[2950,2953,2954],{"type":26,"tag":493,"props":2951,"children":2952},{"disabled":495,"type":496},[],{"type":31,"value":499},{"type":26,"tag":34,"props":2955,"children":2957},{"className":2956},[],[2958],{"type":31,"value":505},{"type":26,"tag":197,"props":2960,"children":2962},{"className":2961},[490],[2963,2966],{"type":26,"tag":493,"props":2964,"children":2965},{"disabled":495,"type":496},[],{"type":31,"value":514},{"type":26,"tag":197,"props":2968,"children":2970},{"className":2969},[490],[2971,2974,2975],{"type":26,"tag":493,"props":2972,"children":2973},{"disabled":495,"type":496},[],{"type":31,"value":523},{"type":26,"tag":34,"props":2976,"children":2978},{"className":2977},[],[2979],{"type":31,"value":253},{"type":26,"tag":197,"props":2981,"children":2983},{"className":2982},[490],[2984,2987],{"type":26,"tag":493,"props":2985,"children":2986},{"disabled":495,"type":496},[],{"type":31,"value":537},{"type":26,"tag":197,"props":2989,"children":2991},{"className":2990},[490],[2992,2995],{"type":26,"tag":493,"props":2993,"children":2994},{"disabled":495,"type":496},[],{"type":31,"value":546},{"type":26,"tag":197,"props":2997,"children":2999},{"className":2998},[490],[3000,3003,3004,3009],{"type":26,"tag":493,"props":3001,"children":3002},{"disabled":495,"type":496},[],{"type":31,"value":555},{"type":26,"tag":34,"props":3005,"children":3007},{"className":3006},[],[3008],{"type":31,"value":561},{"type":31,"value":563},{"type":26,"tag":197,"props":3011,"children":3013},{"className":3012},[490],[3014,3017],{"type":26,"tag":493,"props":3015,"children":3016},{"disabled":495,"type":496},[],{"type":31,"value":572},{"type":26,"tag":70,"props":3019,"children":3020},{"id":575},[3021],{"type":31,"value":575},{"type":26,"tag":27,"props":3023,"children":3024},{},[3025,3030,3031,3036],{"type":26,"tag":34,"props":3026,"children":3028},{"className":3027},[],[3029],{"type":31,"value":14},{"type":31,"value":587},{"type":26,"tag":34,"props":3032,"children":3034},{"className":3033},[],[3035],{"type":31,"value":119},{"type":31,"value":594},{"type":26,"tag":27,"props":3038,"children":3039},{},[3040],{"type":31,"value":599},{"type":26,"tag":193,"props":3042,"children":3043},{},[3044,3051,3058,3065],{"type":26,"tag":197,"props":3045,"children":3046},{},[3047],{"type":26,"tag":607,"props":3048,"children":3049},{"href":609},[3050],{"type":31,"value":612},{"type":26,"tag":197,"props":3052,"children":3053},{},[3054],{"type":26,"tag":607,"props":3055,"children":3056},{"href":618},[3057],{"type":31,"value":621},{"type":26,"tag":197,"props":3059,"children":3060},{},[3061],{"type":26,"tag":607,"props":3062,"children":3063},{"href":627},[3064],{"type":31,"value":630},{"type":26,"tag":197,"props":3066,"children":3067},{},[3068],{"type":26,"tag":607,"props":3069,"children":3070},{"href":636},[3071],{"type":31,"value":639},{"title":7,"searchDepth":641,"depth":641,"links":3073},[3074,3075,3076,3077,3078,3079,3080,3081,3082],{"id":72,"depth":644,"text":75},{"id":139,"depth":644,"text":142},{"id":176,"depth":644,"text":179},{"id":258,"depth":644,"text":261},{"id":288,"depth":644,"text":291},{"id":347,"depth":644,"text":350},{"id":391,"depth":644,"text":394},{"id":478,"depth":644,"text":481},{"id":575,"depth":644,"text":575},1778023761525]