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