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