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