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