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