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