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