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