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