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