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