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