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