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