[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"i-ri:search-line":3,"i-ri:moon-line":8,"i-ri:sun-line":10,"i-ri:menu-3-line":12,"i-ri:close-line":14,"notes-module-items-react":16,"notes-page-react-13-production-readiness\u002F01-observability-logging-metrics-tracing":494,"i-ri:arrow-left-s-line":1898,"i-ri:menu-2-line":1900,"i-ri:arrow-right-s-line":1902,"i-ep:copy-document":1904},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"currentColor\" d=\"m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"currentColor\" d=\"M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2h.1A6.98 6.98 0 0 0 10 7m-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938A8 8 0 0 0 4 12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"currentColor\" d=\"M12 18a6 6 0 1 1 0-12a6 6 0 0 1 0 12m0-2a4 4 0 1 0 0-8a4 4 0 0 0 0 8M11 1h2v3h-2zm0 19h2v3h-2zM3.515 4.929l1.414-1.414L7.05 5.636L5.636 7.05zM16.95 18.364l1.414-1.414l2.121 2.121l-1.414 1.414zm2.121-14.85l1.414 1.415l-2.121 2.121l-1.414-1.414zM5.636 16.95l1.414 1.414l-2.121 2.121l-1.414-1.414zM23 11v2h-3v-2zM4 11v2H1v-2z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"currentColor\" d=\"M3 4h18v2H3zm6 7h12v2H9zm-6 7h18v2H3z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cpath fill=\"currentColor\" d=\"m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z\"\u002F>",[17,22,26,30,34,38,42,46,50,54,58,62,66,70,74,78,82,86,90,94,98,102,106,110,114,118,122,126,130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,214,218,222,226,230,234,238,242,246,250,254,258,262,266,270,274,278,282,286,290,294,298,302,306,310,314,318,322,326,330,334,338,342,346,350,354,358,362,366,370,374,378,382,386,390,394,398,402,406,410,414,418,422,426,430,434,438,442,446,450,454,458,462,466,470,474,478,482,486,490],{"path":18,"title":19,"meta":20},"\u002Fnotes\u002Freact\u002F01-basics\u002F01-how-to-read-this-repo","如何阅读本仓库（学习路径与章节依赖）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},"2026-11-05T09:47:15.000Z",{"path":23,"title":24,"meta":25},"\u002Fnotes\u002Freact\u002F01-basics\u002F02-render-vs-commit","React 渲染两阶段：Render vs Commit（总览）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":27,"title":28,"meta":29},"\u002Fnotes\u002Freact\u002F01-basics\u002F03-update-pipeline-birdview","从“更新”到“页面变更”：一次 setState 的全链路鸟瞰",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":31,"title":32,"meta":33},"\u002Fnotes\u002Freact\u002F01-basics","基础入门（建议先读）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":35,"title":36,"meta":37},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F01-browser-multi-process","浏览器多进程架构",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":39,"title":40,"meta":41},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F02-event-loop-overview","事件循环概述",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":43,"title":44,"meta":45},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F03-call-stack","函数调用栈",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":47,"title":48,"meta":49},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F04-threads","线程介绍",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":51,"title":52,"meta":53},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F05-refresh-rate-and-queues","刷新率与执行队列",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":55,"title":56,"meta":57},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F06-settimeout","setTimeout 原理详解",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":59,"title":60,"meta":61},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F07-promise","Promise 原理详解",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":63,"title":64,"meta":65},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F08-event-loop-in-practice","事件循环机制（综合）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":67,"title":68,"meta":69},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F09-priority-queues","优先级队列",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":71,"title":72,"meta":73},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F01-concept","并发模式：概念",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":75,"title":76,"meta":77},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F02-demo","案例演示并发模式",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":79,"title":80,"meta":81},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F03-high-priority-preemption","高优先级插队",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":83,"title":84,"meta":85},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F04-preemption-vs-interruption","插队的影响、与中断的区别",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":87,"title":88,"meta":89},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F05-shouldYield","中断条件：shouldYield",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":91,"title":92,"meta":93},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F06-react-tasks-and-queues","React 中的任务与队列",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":95,"title":96,"meta":97},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F07-ensureRootIsScheduled","ensureRootIsScheduled",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":99,"title":100,"meta":101},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F08-batch-updates-merge","合并多个更新触发",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":103,"title":104,"meta":105},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F09-taskQueue-lifecycle","taskQueue 队列循环的启动与结束",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":107,"title":108,"meta":109},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F10-time-slicing","时间切片是如何实现的",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":111,"title":112,"meta":113},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F11-workLoop-full","workLoop 循环完整逻辑",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":115,"title":116,"meta":117},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F12-priority-design","React 中的优先级设计",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":119,"title":120,"meta":121},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F13-lane-model","lane 模型",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":123,"title":124,"meta":125},"\u002Fnotes\u002Freact\u002F04-fiber\u002F01-three-node-types","三种节点对象",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":127,"title":128,"meta":129},"\u002Fnotes\u002Freact\u002F04-fiber\u002F02-fiberRootNode","FiberRootNode",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":131,"title":132,"meta":133},"\u002Fnotes\u002Freact\u002F04-fiber\u002F03-fiber-tree","Fiber 树",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":135,"title":136,"meta":137},"\u002Fnotes\u002Freact\u002F04-fiber\u002F04-initial-mount-build","Fiber 树初始构建过程",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":139,"title":140,"meta":141},"\u002Fnotes\u002Freact\u002F04-fiber\u002F05-workLoopConcurrent","workLoopConcurrent",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":143,"title":144,"meta":145},"\u002Fnotes\u002Freact\u002F04-fiber\u002F06-stack-and-workInProgress","栈结构 与 workInProgress",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":147,"title":148,"meta":149},"\u002Fnotes\u002Freact\u002F04-fiber\u002F07-executionContext","执行上下文 executionContext",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":151,"title":152,"meta":153},"\u002Fnotes\u002Freact\u002F04-fiber\u002F08-update-lanes","update lanes",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":155,"title":156,"meta":157},"\u002Fnotes\u002Freact\u002F04-fiber\u002F09-render-lanes","render lanes",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":159,"title":160,"meta":161},"\u002Fnotes\u002Freact\u002F04-fiber\u002F10-fiber-lanes","fiber lanes",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":163,"title":164,"meta":165},"\u002Fnotes\u002Freact\u002F04-fiber\u002F11-flags-appendix","附录：flags",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":167,"title":168,"meta":169},"\u002Fnotes\u002Freact\u002F05-hooks\u002F01-background","hook 背景",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":171,"title":172,"meta":173},"\u002Fnotes\u002Freact\u002F05-hooks\u002F02-categories","hook 分类",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":175,"title":176,"meta":177},"\u002Fnotes\u002Freact\u002F05-hooks\u002F03-closures","hook 与闭包",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":179,"title":180,"meta":181},"\u002Fnotes\u002Freact\u002F05-hooks\u002F04-hooks-and-fiber","hook 与 fiber",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":183,"title":184,"meta":185},"\u002Fnotes\u002Freact\u002F05-hooks\u002F05-renderWithHooks","renderWithHooks",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":187,"title":188,"meta":189},"\u002Fnotes\u002Freact\u002F05-hooks\u002F06-init-state-hook","初始化 State Hook",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":191,"title":192,"meta":193},"\u002Fnotes\u002Freact\u002F05-hooks\u002F07-init-effect-hook","初始化 effect Hook",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":195,"title":196,"meta":197},"\u002Fnotes\u002Freact\u002F05-hooks\u002F08-circular-linked-list","环形链表详解",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":199,"title":200,"meta":201},"\u002Fnotes\u002Freact\u002F05-hooks\u002F09-useReducer-vs-useState","useReducer 与 useState 的区别",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":203,"title":204,"meta":205},"\u002Fnotes\u002Freact\u002F05-hooks\u002F10-update-linked-list","update 链表",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":207,"title":208,"meta":209},"\u002Fnotes\u002Freact\u002F05-hooks\u002F11-mount-state-updates","初始阶段的状态更新",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":211,"title":212,"meta":213},"\u002Fnotes\u002Freact\u002F05-hooks\u002F12-baseQueue-vs-pending","baseQueue 与 queue.pending",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":215,"title":216,"meta":217},"\u002Fnotes\u002Freact\u002F05-hooks\u002F13-dispatch-in-update","更新阶段的 dispatch",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":219,"title":220,"meta":221},"\u002Fnotes\u002Freact\u002F05-hooks\u002F14-commitRoot","commitRoot",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":223,"title":224,"meta":225},"\u002Fnotes\u002Freact\u002F06-diff\u002F01-update-overview","React 更新机制概述",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":227,"title":228,"meta":229},"\u002Fnotes\u002Freact\u002F06-diff\u002F02-diff-strategy","diff 策略",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":231,"title":232,"meta":233},"\u002Fnotes\u002Freact\u002F06-diff\u002F03-node-compare","节点比较方式",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":235,"title":236,"meta":237},"\u002Fnotes\u002Freact\u002F06-diff\u002F04-reconcileChildFibers","reconcileChildFibers",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":239,"title":240,"meta":241},"\u002Fnotes\u002Freact\u002F06-diff\u002F05-reconcileSingleElement","reconcileSingleElement",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":243,"title":244,"meta":245},"\u002Fnotes\u002Freact\u002F06-diff\u002F06-reconcileChildrenArray","reconcileChildrenArray",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":247,"title":248,"meta":249},"\u002Fnotes\u002Freact\u002F06-diff\u002F07-why-not-number-key","为什么不建议使用数字作为 key",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":251,"title":252,"meta":253},"\u002Fnotes\u002Freact\u002F07-event-system\u002F01-overview","事件系统概述",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":255,"title":256,"meta":257},"\u002Fnotes\u002Freact\u002F07-event-system\u002F02-event-plugin","事件插件",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":259,"title":260,"meta":261},"\u002Fnotes\u002Freact\u002F07-event-system\u002F03-event-pooling","事件池",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":263,"title":264,"meta":265},"\u002Fnotes\u002Freact\u002F07-event-system\u002F04-root-listeners","根节点事件绑定",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":267,"title":268,"meta":269},"\u002Fnotes\u002Freact\u002F07-event-system\u002F05-event-dispatch","事件触发",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":271,"title":272,"meta":273},"\u002Fnotes\u002Freact\u002F08-interview\u002F01-useEffect-vs-useLayoutEffect","useEffect 与 useLayoutEffect 的区别",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":275,"title":276,"meta":277},"\u002Fnotes\u002Freact\u002F08-interview\u002F02-why-no-conditional-hooks","为什么 hook 不能写在条件判断里",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":279,"title":280,"meta":281},"\u002Fnotes\u002Freact\u002F08-interview\u002F03-understanding-concurrency","聊聊在 React 中，你对并发模式的理解",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":283,"title":284,"meta":285},"\u002Fnotes\u002Freact\u002F08-interview\u002F04-update-mechanism","聊聊 React 的更新机制原理",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":287,"title":288,"meta":289},"\u002Fnotes\u002Freact\u002F08-interview\u002F05-setState-sync-or-async","setState 是同步还是异步的？",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":291,"title":292,"meta":293},"\u002Fnotes\u002Freact\u002F08-interview\u002F06-useState-vs-useReducer","聊聊 useState 与 useReducer 的区别",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":295,"title":296,"meta":297},"\u002Fnotes\u002Freact\u002F08-interview\u002F07-closure-trap","聊聊闭包陷阱问题，以及如何解决",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":299,"title":300,"meta":301},"\u002Fnotes\u002Freact\u002F08-interview\u002F08-time-slicing-details","时间分片是如何实现的（任务拆分\u002F中断\u002F恢复）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":303,"title":304,"meta":305},"\u002Fnotes\u002Freact\u002F08-interview\u002F09-batched-updates-useState","聊聊 useState 的批处理更新机制",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":307,"title":308,"meta":309},"\u002Fnotes\u002Freact\u002F08-interview\u002F10-jsx-to-dom","JSX 是如何转变成为真实 DOM 的",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":311,"title":312,"meta":313},"\u002Fnotes\u002Freact\u002F08-interview\u002F11-useCallback-impl","useCallback 的实现原理是什么",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":315,"title":316,"meta":317},"\u002Fnotes\u002Freact\u002F08-interview\u002F12-scheduling-mechanism","详细聊聊 React 的调度机制",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":319,"title":320,"meta":321},"\u002Fnotes\u002Freact\u002F08-interview\u002F13-priority-and-lanes","聊聊 React 的优先级机制（Lane 模型）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":323,"title":324,"meta":325},"\u002Fnotes\u002Freact\u002F08-interview\u002F14-diff-algorithm","React 的 Diff 算法是什么样的",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":327,"title":328,"meta":329},"\u002Fnotes\u002Freact\u002F08-interview\u002F15-event-system","详细聊聊 React 的事件系统是如何实现的",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":331,"title":332,"meta":333},"\u002Fnotes\u002Freact\u002F08-interview\u002F16-portals-bubbling","React Portals 上的事件是否会冒泡到父组件，原理是什么",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":335,"title":336,"meta":337},"\u002Fnotes\u002Freact\u002F08-interview\u002F17-useEffect-impl","useEffect 的实现原理是什么",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":339,"title":340,"meta":341},"\u002Fnotes\u002Freact\u002F08-interview\u002F18-useContext-impl","请聊聊 useContext 的实现原理",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":343,"title":344,"meta":345},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F01-automatic-batching-and-flushsync","React 18 自动批处理（Automatic Batching）与 flushSync",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":347,"title":348,"meta":349},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F02-strictmode-and-idempotent-effects","React StrictMode：为什么会“双调用”？（源码\u002F机制视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":351,"title":352,"meta":353},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F03-transition-useTransition-useDeferredValue","Transition：startTransition \u002F useTransition \u002F useDeferredValue（机制视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":355,"title":356,"meta":357},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F04-suspense-loading-boundary-design","Suspense：加载态边界如何设计（机制\u002F架构视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":359,"title":360,"meta":361},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F05-error-boundary-reporting-and-recovery","Error Boundary：兜底、重试与上报（自研 vs Sentry）（机制\u002F架构视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":363,"title":364,"meta":365},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice","React 18 实战（并发特性与默认行为）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":367,"title":368,"meta":369},"\u002Fnotes\u002Freact\u002F10-routing-and-navigation\u002F01-routing-and-url-state-mental-model","路由与 URL State：统一心智模型（架构师视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":371,"title":372,"meta":373},"\u002Fnotes\u002Freact\u002F10-routing-and-navigation\u002F02-tanstack-router-route-tree-search-loader-prefetch","TanStack Router（Vite \u002F SPA）：Route Tree \u002F Search \u002F Loader \u002F Prefetch（落地篇）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":375,"title":376,"meta":377},"\u002Fnotes\u002Freact\u002F10-routing-and-navigation\u002F03-next-app-router-segments-layout-loading-error-not-found-prefetch","Next.js App Router：Segments \u002F Layouts \u002F Loading-Error-NotFound \u002F Prefetch（落地篇）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":379,"title":380,"meta":381},"\u002Fnotes\u002Freact\u002F10-routing-and-navigation","路由与导航（TanStack Router \u002F Next App Router）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":383,"title":384,"meta":385},"\u002Fnotes\u002Freact\u002F11-data-layer\u002F01-state-layering-ui-server-url-global","状态分层：UI \u002F Server \u002F URL \u002F Global（架构师视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":387,"title":388,"meta":389},"\u002Fnotes\u002Freact\u002F11-data-layer\u002F02-tanstack-query-caching-and-invalidation","TanStack Query：缓存模型与失效策略（Caching & Invalidation）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":391,"title":392,"meta":393},"\u002Fnotes\u002Freact\u002F11-data-layer\u002F03-optimistic-updates-and-consistency","TanStack Query：乐观更新与一致性（Optimistic Updates & Consistency）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":395,"title":396,"meta":397},"\u002Fnotes\u002Freact\u002F11-data-layer\u002F04-form-architecture-react-hook-form-validation-performance-testability","表单架构：React Hook Form 的受控\u002F非受控、校验、性能与可测试性（架构师视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":399,"title":400,"meta":401},"\u002Fnotes\u002Freact\u002F11-data-layer","数据层（Server State \u002F 表单 \u002F 状态分层）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":403,"title":404,"meta":405},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery\u002F01-hydration-mismatch","Hydration mismatch（React \u002F Next.js）：成因、检测、排查清单与工程化规避",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":407,"title":408,"meta":409},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery\u002F01-nextjs-cache-revalidate-consistency-online-not-updating","Next.js 缓存\u002F重验证与一致性：避免「线上怎么不更新」事故（App Router）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":411,"title":412,"meta":413},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery\u002F02-csr-ssr-ssg-isr-how-to-choose","CSR vs SSR vs SSG vs ISR：怎么选？边界是什么？（体验 + 成本 + 一致性）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":415,"title":416,"meta":417},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery\u002F04-streaming-ssr-with-suspense","Streaming SSR + Suspense：提升前端感知性能的利器",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":419,"title":420,"meta":421},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery","渲染与交付（CSR\u002FSSR\u002FStreaming\u002FHydration\u002F缓存）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":423,"title":424,"meta":425},"\u002Fnotes\u002Freact\u002F13-production-readiness\u002F01-observability-logging-metrics-tracing","前端可观测性体系：日志、指标与链路追踪",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":427,"title":428,"meta":429},"\u002Fnotes\u002Freact\u002F13-production-readiness\u002F02-auth-and-web-security","鉴权与 Web 安全：OAuth, JWT, XSS, CSRF, CSP",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":431,"title":432,"meta":433},"\u002Fnotes\u002Freact\u002F13-production-readiness","生产可用性（错误\u002F可观测\u002F鉴权\u002F安全）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":435,"title":436,"meta":437},"\u002Fnotes\u002Freact\u002F14-performance\u002F01-performance-playbook-and-metrics","前端性能定位 Playbook：从指标到归因",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":439,"title":440,"meta":441},"\u002Fnotes\u002Freact\u002F14-performance\u002F02-rendering-optimization-memo-context-virtualization","React 渲染性能优化：Memo, Context, 与虚拟化",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":443,"title":444,"meta":445},"\u002Fnotes\u002Freact\u002F14-performance\u002F03-asset-and-bundle-optimization","资源与 Bundle 优化：代码分割、图片与 CDN",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":447,"title":448,"meta":449},"\u002Fnotes\u002Freact\u002F14-performance","性能体系（定位 → 优化 → 度量）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":451,"title":452,"meta":453},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F01-component-system-and-design-system","组件体系与设计系统：构建规模化前端的基石",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":455,"title":456,"meta":457},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F02-testing-strategy-rtl-e2e-testability","前端测试体系：RTL, E2E 与可测性设计",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":459,"title":460,"meta":461},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F03-monorepo-and-dependency-management","Monorepo 与依赖治理：pnpm 和 Turborepo",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":463,"title":464,"meta":465},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F04-cicd-and-quality-gates","CI\u002FCD 与质量门禁：构建可靠的自动化流程",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":467,"title":468,"meta":469},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F05-bff-and-api-design","BFF 与 API 设计：前端架构师的视角",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":471,"title":472,"meta":473},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture","工程与架构治理（规模化）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":475,"title":476,"meta":477},"\u002Fnotes\u002Freact\u002F16-advanced\u002F01-rsc-and-server-actions-deep-dive","RSC\u002FServer Actions 深水区：边界、约束与缓存一致性",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":479,"title":480,"meta":481},"\u002Fnotes\u002Freact\u002F16-advanced\u002F02-micro-frontend-governance","微前端治理：样式、路由与通信",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":483,"title":484,"meta":485},"\u002Fnotes\u002Freact\u002F16-advanced\u002F03-realtime-and-offline","实时与离线：WebSocket, PWA 与 Service Worker",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":487,"title":488,"meta":489},"\u002Fnotes\u002Freact\u002F16-advanced\u002F04-a11y-i18n-compliance","a11y, i18n 与合规：构建负责任的全球化应用",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":491,"title":492,"meta":493},"\u002Fnotes\u002Freact\u002F16-advanced","进阶专题（按业务需要选做）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"id":495,"type":496,"sourcePath":497,"routePath":423,"path":423,"title":424,"updatedAt":21,"meta":498,"body":500,"toc":1880},"bm90ZTpub3Rlcy9yZWFjdC8xMy1wcm9kdWN0aW9uLXJlYWRpbmVzcy8wMS1vYnNlcnZhYmlsaXR5LWxvZ2dpbmctbWV0cmljcy10cmFjaW5nLm1k","note","notes\u002Freact\u002F13-production-readiness\u002F01-observability-logging-metrics-tracing.md",{"id":495,"type":496,"sourcePath":497,"slug":499,"title":424,"updatedAt":21,"lastUpdated":21},"react\u002F13-production-readiness\u002F01-observability-logging-metrics-tracing",{"type":501,"children":502},"root",[503,511,527,531,538,543,704,730,733,739,744,751,793,803,851,857,1310,1316,1339,1342,1348,1353,1359,1402,1408,1516,1531,1610,1613,1619,1624,1630,1642,1648,1745,1751,1761,1770,1811,1814,1820,1874],{"type":504,"tag":505,"props":506,"children":508},"element","h1",{"id":507},"前端可观测性体系日志指标与链路追踪",[509],{"type":510,"value":424},"text",{"type":504,"tag":512,"props":513,"children":514},"blockquote",{},[515],{"type":504,"tag":516,"props":517,"children":518},"p",{},[519,525],{"type":504,"tag":520,"props":521,"children":522},"strong",{},[523],{"type":510,"value":524},"一句话结论",{"type":510,"value":526},"：建立一个由日志 (Logging)、指标 (Metrics) 和链路追踪 (Tracing) 构成的“可观测性铁三角”，是主动发现、快速定位并有效解决线上问题的基础，它能将前端从被动的“救火队”转变为主动的“领航员”。",{"type":504,"tag":528,"props":529,"children":530},"hr",{},[],{"type":504,"tag":532,"props":533,"children":535},"h2",{"id":534},"_1-可观测性的三大支柱-the-three-pillars",[536],{"type":510,"value":537},"1. 可观测性的三大支柱 (The Three Pillars)",{"type":504,"tag":516,"props":539,"children":540},{},[541],{"type":510,"value":542},"可观测性 (Observability) 不仅仅是监控 (Monitoring)。监控告诉你“系统出错了”，而可观测性告诉你“系统为什么出错”。",{"type":504,"tag":544,"props":545,"children":546},"table",{},[547,582],{"type":504,"tag":548,"props":549,"children":550},"thead",{},[551],{"type":504,"tag":552,"props":553,"children":554},"tr",{},[555,562,567,572,577],{"type":504,"tag":556,"props":557,"children":559},"th",{"align":558},"left",[560],{"type":510,"value":561},"支柱",{"type":504,"tag":556,"props":563,"children":564},{"align":558},[565],{"type":510,"value":566},"角色",{"type":504,"tag":556,"props":568,"children":569},{"align":558},[570],{"type":510,"value":571},"数据形态",{"type":504,"tag":556,"props":573,"children":574},{"align":558},[575],{"type":510,"value":576},"核心问题",{"type":504,"tag":556,"props":578,"children":579},{"align":558},[580],{"type":510,"value":581},"常用工具",{"type":504,"tag":583,"props":584,"children":585},"tbody",{},[586,626,665],{"type":504,"tag":552,"props":587,"children":588},{},[589,598,606,611,621],{"type":504,"tag":590,"props":591,"children":592},"td",{"align":558},[593],{"type":504,"tag":520,"props":594,"children":595},{},[596],{"type":510,"value":597},"日志 (Logging)",{"type":504,"tag":590,"props":599,"children":600},{"align":558},[601],{"type":504,"tag":520,"props":602,"children":603},{},[604],{"type":510,"value":605},"离散事件记录",{"type":504,"tag":590,"props":607,"children":608},{"align":558},[609],{"type":510,"value":610},"带有时间戳的、非结构化或结构化的文本行。",{"type":504,"tag":590,"props":612,"children":613},{"align":558},[614,619],{"type":504,"tag":520,"props":615,"children":616},{},[617],{"type":510,"value":618},"发生了什么？",{"type":510,"value":620}," (What happened?)",{"type":504,"tag":590,"props":622,"children":623},{"align":558},[624],{"type":510,"value":625},"Sentry, LogRocket, 自研日志库 + ELK\u002FLoki",{"type":504,"tag":552,"props":627,"children":628},{},[629,637,645,650,660],{"type":504,"tag":590,"props":630,"children":631},{"align":558},[632],{"type":504,"tag":520,"props":633,"children":634},{},[635],{"type":510,"value":636},"指标 (Metrics)",{"type":504,"tag":590,"props":638,"children":639},{"align":558},[640],{"type":504,"tag":520,"props":641,"children":642},{},[643],{"type":510,"value":644},"聚合数据度量",{"type":504,"tag":590,"props":646,"children":647},{"align":558},[648],{"type":510,"value":649},"随时间变化的、可聚合的数值（计数器、仪表盘、直方图）。",{"type":504,"tag":590,"props":651,"children":652},{"align":558},[653,658],{"type":504,"tag":520,"props":654,"children":655},{},[656],{"type":510,"value":657},"系统状态如何？",{"type":510,"value":659}," (How is the system doing?)",{"type":504,"tag":590,"props":661,"children":662},{"align":558},[663],{"type":510,"value":664},"Prometheus, Datadog, Vercel Analytics",{"type":504,"tag":552,"props":666,"children":667},{},[668,676,684,689,699],{"type":504,"tag":590,"props":669,"children":670},{"align":558},[671],{"type":504,"tag":520,"props":672,"children":673},{},[674],{"type":510,"value":675},"链路追踪 (Tracing)",{"type":504,"tag":590,"props":677,"children":678},{"align":558},[679],{"type":504,"tag":520,"props":680,"children":681},{},[682],{"type":510,"value":683},"请求生命周期",{"type":504,"tag":590,"props":685,"children":686},{"align":558},[687],{"type":510,"value":688},"一个请求跨越多个服务的完整路径，由 Spans 组成的 Trace。",{"type":504,"tag":590,"props":690,"children":691},{"align":558},[692,697],{"type":504,"tag":520,"props":693,"children":694},{},[695],{"type":510,"value":696},"瓶颈在哪里？",{"type":510,"value":698}," (Where is the bottleneck?)",{"type":504,"tag":590,"props":700,"children":701},{"align":558},[702],{"type":510,"value":703},"OpenTelemetry, Jaeger, Datadog APM, Sentry",{"type":504,"tag":516,"props":705,"children":706},{},[707,709,714,716,721,723,728],{"type":510,"value":708},"这三者相辅相成：通过",{"type":504,"tag":520,"props":710,"children":711},{},[712],{"type":510,"value":713},"指标",{"type":510,"value":715},"发现异常（例如，错误率飙升），通过",{"type":504,"tag":520,"props":717,"children":718},{},[719],{"type":510,"value":720},"链路",{"type":510,"value":722},"定位到具体服务和操作（例如，支付 API 耗时过长），最后通过",{"type":504,"tag":520,"props":724,"children":725},{},[726],{"type":510,"value":727},"日志",{"type":510,"value":729},"查看该操作的详细上下文（例如，请求参数、错误堆栈）。",{"type":504,"tag":528,"props":731,"children":732},{},[],{"type":504,"tag":532,"props":734,"children":736},{"id":735},"_2-前端日志-logging",[737],{"type":510,"value":738},"2. 前端日志 (Logging)",{"type":504,"tag":516,"props":740,"children":741},{},[742],{"type":510,"value":743},"前端日志是事后追溯问题的“黑匣子”。",{"type":504,"tag":745,"props":746,"children":748},"h3",{"id":747},"a-日志分类与分级",[749],{"type":510,"value":750},"A. 日志分类与分级",{"type":504,"tag":752,"props":753,"children":754},"ul",{},[755,766,783],{"type":504,"tag":756,"props":757,"children":758},"li",{},[759,764],{"type":504,"tag":520,"props":760,"children":761},{},[762],{"type":510,"value":763},"行为日志 (Behavior)",{"type":510,"value":765},"：记录用户的关键操作路径（点击、路由跳转、功能使用等），用于分析用户行为和复现问题。",{"type":504,"tag":756,"props":767,"children":768},{},[769,774,776,781],{"type":504,"tag":520,"props":770,"children":771},{},[772],{"type":510,"value":773},"错误日志 (Error)",{"type":510,"value":775},"：记录 JS 错误、Promise rejections、资源加载失败、API 请求失败等。",{"type":504,"tag":520,"props":777,"children":778},{},[779],{"type":510,"value":780},"这是最重要的日志类型",{"type":510,"value":782},"。",{"type":504,"tag":756,"props":784,"children":785},{},[786,791],{"type":504,"tag":520,"props":787,"children":788},{},[789],{"type":510,"value":790},"性能日志 (Performance)",{"type":510,"value":792},"：记录 Core Web Vitals (LCP\u002FINP\u002FCLS)、API 请求耗时、组件渲染时间等。",{"type":504,"tag":516,"props":794,"children":795},{},[796,801],{"type":504,"tag":520,"props":797,"children":798},{},[799],{"type":510,"value":800},"日志分级 (Level)",{"type":510,"value":802},"：",{"type":504,"tag":752,"props":804,"children":805},{},[806,818,829,840],{"type":504,"tag":756,"props":807,"children":808},{},[809,816],{"type":504,"tag":810,"props":811,"children":813},"code",{"className":812},[],[814],{"type":510,"value":815},"error",{"type":510,"value":817},": 严重错误，必须立即处理。",{"type":504,"tag":756,"props":819,"children":820},{},[821,827],{"type":504,"tag":810,"props":822,"children":824},{"className":823},[],[825],{"type":510,"value":826},"warn",{"type":510,"value":828},": 警告，可能存在潜在问题。",{"type":504,"tag":756,"props":830,"children":831},{},[832,838],{"type":504,"tag":810,"props":833,"children":835},{"className":834},[],[836],{"type":510,"value":837},"info",{"type":510,"value":839},": 普通信息，用于记录业务流程。",{"type":504,"tag":756,"props":841,"children":842},{},[843,849],{"type":504,"tag":810,"props":844,"children":846},{"className":845},[],[847],{"type":510,"value":848},"debug",{"type":510,"value":850},": 调试信息，仅在开发或特定排错场景下开启。",{"type":504,"tag":745,"props":852,"children":854},{"id":853},"b-如何采集",[855],{"type":510,"value":856},"B. 如何采集",{"type":504,"tag":858,"props":859,"children":860},"ol",{},[861,1173,1300],{"type":504,"tag":756,"props":862,"children":863},{},[864,869,870],{"type":504,"tag":520,"props":865,"children":866},{},[867],{"type":510,"value":868},"全局错误捕获",{"type":510,"value":802},{"type":504,"tag":871,"props":872,"children":877},"pre",{"className":873,"code":874,"language":875,"meta":876,"style":876},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F 捕获同步错误和资源加载错误\nwindow.addEventListener('error', event => {\n  \u002F\u002F 过滤掉非脚本错误\n  if (event.message) {\n    console.log('JS Error:', event.message, event.filename, event.lineno, event.colno, event.error);\n  } else {\n    console.log('Resource Error:', event.target.src || event.target.href);\n  }\n}, true); \u002F\u002F 使用捕获阶段以捕获资源加载错误\n\n\u002F\u002F 捕获未处理的 Promise 拒绝\nwindow.addEventListener('unhandledrejection', event => {\n  console.log('Promise Rejection:', event.reason);\n});\n","javascript","",[878],{"type":504,"tag":810,"props":879,"children":880},{"__ignoreMap":876},[881,893,942,951,965,993,1011,1047,1056,1081,1091,1100,1137,1164],{"type":504,"tag":882,"props":883,"children":886},"span",{"class":884,"line":885},"line",1,[887],{"type":504,"tag":882,"props":888,"children":890},{"style":889},"--shiki-default:#6A737D;--shiki-dark:#6A737D",[891],{"type":510,"value":892},"\u002F\u002F 捕获同步错误和资源加载错误\n",{"type":504,"tag":882,"props":894,"children":896},{"class":884,"line":895},2,[897,903,909,914,920,925,931,937],{"type":504,"tag":882,"props":898,"children":900},{"style":899},"--shiki-default:#24292E;--shiki-dark:#E1E4E8",[901],{"type":510,"value":902},"window.",{"type":504,"tag":882,"props":904,"children":906},{"style":905},"--shiki-default:#6F42C1;--shiki-dark:#B392F0",[907],{"type":510,"value":908},"addEventListener",{"type":504,"tag":882,"props":910,"children":911},{"style":899},[912],{"type":510,"value":913},"(",{"type":504,"tag":882,"props":915,"children":917},{"style":916},"--shiki-default:#032F62;--shiki-dark:#9ECBFF",[918],{"type":510,"value":919},"'error'",{"type":504,"tag":882,"props":921,"children":922},{"style":899},[923],{"type":510,"value":924},", ",{"type":504,"tag":882,"props":926,"children":928},{"style":927},"--shiki-default:#E36209;--shiki-dark:#FFAB70",[929],{"type":510,"value":930},"event",{"type":504,"tag":882,"props":932,"children":934},{"style":933},"--shiki-default:#D73A49;--shiki-dark:#F97583",[935],{"type":510,"value":936}," =>",{"type":504,"tag":882,"props":938,"children":939},{"style":899},[940],{"type":510,"value":941}," {\n",{"type":504,"tag":882,"props":943,"children":945},{"class":884,"line":944},3,[946],{"type":504,"tag":882,"props":947,"children":948},{"style":889},[949],{"type":510,"value":950},"  \u002F\u002F 过滤掉非脚本错误\n",{"type":504,"tag":882,"props":952,"children":954},{"class":884,"line":953},4,[955,960],{"type":504,"tag":882,"props":956,"children":957},{"style":933},[958],{"type":510,"value":959},"  if",{"type":504,"tag":882,"props":961,"children":962},{"style":899},[963],{"type":510,"value":964}," (event.message) {\n",{"type":504,"tag":882,"props":966,"children":968},{"class":884,"line":967},5,[969,974,979,983,988],{"type":504,"tag":882,"props":970,"children":971},{"style":899},[972],{"type":510,"value":973},"    console.",{"type":504,"tag":882,"props":975,"children":976},{"style":905},[977],{"type":510,"value":978},"log",{"type":504,"tag":882,"props":980,"children":981},{"style":899},[982],{"type":510,"value":913},{"type":504,"tag":882,"props":984,"children":985},{"style":916},[986],{"type":510,"value":987},"'JS Error:'",{"type":504,"tag":882,"props":989,"children":990},{"style":899},[991],{"type":510,"value":992},", event.message, event.filename, event.lineno, event.colno, event.error);\n",{"type":504,"tag":882,"props":994,"children":996},{"class":884,"line":995},6,[997,1002,1007],{"type":504,"tag":882,"props":998,"children":999},{"style":899},[1000],{"type":510,"value":1001},"  } ",{"type":504,"tag":882,"props":1003,"children":1004},{"style":933},[1005],{"type":510,"value":1006},"else",{"type":504,"tag":882,"props":1008,"children":1009},{"style":899},[1010],{"type":510,"value":941},{"type":504,"tag":882,"props":1012,"children":1014},{"class":884,"line":1013},7,[1015,1019,1023,1027,1032,1037,1042],{"type":504,"tag":882,"props":1016,"children":1017},{"style":899},[1018],{"type":510,"value":973},{"type":504,"tag":882,"props":1020,"children":1021},{"style":905},[1022],{"type":510,"value":978},{"type":504,"tag":882,"props":1024,"children":1025},{"style":899},[1026],{"type":510,"value":913},{"type":504,"tag":882,"props":1028,"children":1029},{"style":916},[1030],{"type":510,"value":1031},"'Resource Error:'",{"type":504,"tag":882,"props":1033,"children":1034},{"style":899},[1035],{"type":510,"value":1036},", event.target.src ",{"type":504,"tag":882,"props":1038,"children":1039},{"style":933},[1040],{"type":510,"value":1041},"||",{"type":504,"tag":882,"props":1043,"children":1044},{"style":899},[1045],{"type":510,"value":1046}," event.target.href);\n",{"type":504,"tag":882,"props":1048,"children":1050},{"class":884,"line":1049},8,[1051],{"type":504,"tag":882,"props":1052,"children":1053},{"style":899},[1054],{"type":510,"value":1055},"  }\n",{"type":504,"tag":882,"props":1057,"children":1059},{"class":884,"line":1058},9,[1060,1065,1071,1076],{"type":504,"tag":882,"props":1061,"children":1062},{"style":899},[1063],{"type":510,"value":1064},"}, ",{"type":504,"tag":882,"props":1066,"children":1068},{"style":1067},"--shiki-default:#005CC5;--shiki-dark:#79B8FF",[1069],{"type":510,"value":1070},"true",{"type":504,"tag":882,"props":1072,"children":1073},{"style":899},[1074],{"type":510,"value":1075},"); ",{"type":504,"tag":882,"props":1077,"children":1078},{"style":889},[1079],{"type":510,"value":1080},"\u002F\u002F 使用捕获阶段以捕获资源加载错误\n",{"type":504,"tag":882,"props":1082,"children":1084},{"class":884,"line":1083},10,[1085],{"type":504,"tag":882,"props":1086,"children":1088},{"emptyLinePlaceholder":1087},true,[1089],{"type":510,"value":1090},"\n",{"type":504,"tag":882,"props":1092,"children":1094},{"class":884,"line":1093},11,[1095],{"type":504,"tag":882,"props":1096,"children":1097},{"style":889},[1098],{"type":510,"value":1099},"\u002F\u002F 捕获未处理的 Promise 拒绝\n",{"type":504,"tag":882,"props":1101,"children":1103},{"class":884,"line":1102},12,[1104,1108,1112,1116,1121,1125,1129,1133],{"type":504,"tag":882,"props":1105,"children":1106},{"style":899},[1107],{"type":510,"value":902},{"type":504,"tag":882,"props":1109,"children":1110},{"style":905},[1111],{"type":510,"value":908},{"type":504,"tag":882,"props":1113,"children":1114},{"style":899},[1115],{"type":510,"value":913},{"type":504,"tag":882,"props":1117,"children":1118},{"style":916},[1119],{"type":510,"value":1120},"'unhandledrejection'",{"type":504,"tag":882,"props":1122,"children":1123},{"style":899},[1124],{"type":510,"value":924},{"type":504,"tag":882,"props":1126,"children":1127},{"style":927},[1128],{"type":510,"value":930},{"type":504,"tag":882,"props":1130,"children":1131},{"style":933},[1132],{"type":510,"value":936},{"type":504,"tag":882,"props":1134,"children":1135},{"style":899},[1136],{"type":510,"value":941},{"type":504,"tag":882,"props":1138,"children":1140},{"class":884,"line":1139},13,[1141,1146,1150,1154,1159],{"type":504,"tag":882,"props":1142,"children":1143},{"style":899},[1144],{"type":510,"value":1145},"  console.",{"type":504,"tag":882,"props":1147,"children":1148},{"style":905},[1149],{"type":510,"value":978},{"type":504,"tag":882,"props":1151,"children":1152},{"style":899},[1153],{"type":510,"value":913},{"type":504,"tag":882,"props":1155,"children":1156},{"style":916},[1157],{"type":510,"value":1158},"'Promise Rejection:'",{"type":504,"tag":882,"props":1160,"children":1161},{"style":899},[1162],{"type":510,"value":1163},", event.reason);\n",{"type":504,"tag":882,"props":1165,"children":1167},{"class":884,"line":1166},14,[1168],{"type":504,"tag":882,"props":1169,"children":1170},{"style":899},[1171],{"type":510,"value":1172},"});\n",{"type":504,"tag":756,"props":1174,"children":1175},{},[1176,1181,1183],{"type":504,"tag":520,"props":1177,"children":1178},{},[1179],{"type":510,"value":1180},"React Error Boundary",{"type":510,"value":1182},"：捕获组件渲染期间的错误。",{"type":504,"tag":871,"props":1184,"children":1188},{"className":1185,"code":1186,"language":1187,"meta":876,"style":876},"language-jsx shiki shiki-themes github-light github-dark","class ErrorBoundary extends React.Component {\n  componentDidCatch(error, errorInfo) {\n    logErrorToMyService(error, errorInfo); \u002F\u002F 发送到日志服务\n  }\n  \u002F\u002F ...\n}\n","jsx",[1189],{"type":504,"tag":810,"props":1190,"children":1191},{"__ignoreMap":876},[1192,1229,1259,1277,1284,1292],{"type":504,"tag":882,"props":1193,"children":1194},{"class":884,"line":885},[1195,1200,1205,1210,1215,1220,1225],{"type":504,"tag":882,"props":1196,"children":1197},{"style":933},[1198],{"type":510,"value":1199},"class",{"type":504,"tag":882,"props":1201,"children":1202},{"style":905},[1203],{"type":510,"value":1204}," ErrorBoundary",{"type":504,"tag":882,"props":1206,"children":1207},{"style":933},[1208],{"type":510,"value":1209}," extends",{"type":504,"tag":882,"props":1211,"children":1212},{"style":905},[1213],{"type":510,"value":1214}," React",{"type":504,"tag":882,"props":1216,"children":1217},{"style":899},[1218],{"type":510,"value":1219},".",{"type":504,"tag":882,"props":1221,"children":1222},{"style":905},[1223],{"type":510,"value":1224},"Component",{"type":504,"tag":882,"props":1226,"children":1227},{"style":899},[1228],{"type":510,"value":941},{"type":504,"tag":882,"props":1230,"children":1231},{"class":884,"line":895},[1232,1237,1241,1245,1249,1254],{"type":504,"tag":882,"props":1233,"children":1234},{"style":905},[1235],{"type":510,"value":1236},"  componentDidCatch",{"type":504,"tag":882,"props":1238,"children":1239},{"style":899},[1240],{"type":510,"value":913},{"type":504,"tag":882,"props":1242,"children":1243},{"style":927},[1244],{"type":510,"value":815},{"type":504,"tag":882,"props":1246,"children":1247},{"style":899},[1248],{"type":510,"value":924},{"type":504,"tag":882,"props":1250,"children":1251},{"style":927},[1252],{"type":510,"value":1253},"errorInfo",{"type":504,"tag":882,"props":1255,"children":1256},{"style":899},[1257],{"type":510,"value":1258},") {\n",{"type":504,"tag":882,"props":1260,"children":1261},{"class":884,"line":944},[1262,1267,1272],{"type":504,"tag":882,"props":1263,"children":1264},{"style":905},[1265],{"type":510,"value":1266},"    logErrorToMyService",{"type":504,"tag":882,"props":1268,"children":1269},{"style":899},[1270],{"type":510,"value":1271},"(error, errorInfo); ",{"type":504,"tag":882,"props":1273,"children":1274},{"style":889},[1275],{"type":510,"value":1276},"\u002F\u002F 发送到日志服务\n",{"type":504,"tag":882,"props":1278,"children":1279},{"class":884,"line":953},[1280],{"type":504,"tag":882,"props":1281,"children":1282},{"style":899},[1283],{"type":510,"value":1055},{"type":504,"tag":882,"props":1285,"children":1286},{"class":884,"line":967},[1287],{"type":504,"tag":882,"props":1288,"children":1289},{"style":889},[1290],{"type":510,"value":1291},"  \u002F\u002F ...\n",{"type":504,"tag":882,"props":1293,"children":1294},{"class":884,"line":995},[1295],{"type":504,"tag":882,"props":1296,"children":1297},{"style":899},[1298],{"type":510,"value":1299},"}\n",{"type":504,"tag":756,"props":1301,"children":1302},{},[1303,1308],{"type":504,"tag":520,"props":1304,"children":1305},{},[1306],{"type":510,"value":1307},"封装上报函数",{"type":510,"value":1309},"：提供一个统一的 SDK 函数，业务代码可以手动调用来上报特定日志。该函数应自动附加用户 ID、设备信息、App 版本、页面 URL 等通用元数据。",{"type":504,"tag":745,"props":1311,"children":1313},{"id":1312},"c-推荐方案",[1314],{"type":510,"value":1315},"C. 推荐方案",{"type":504,"tag":752,"props":1317,"children":1318},{},[1319,1329],{"type":504,"tag":756,"props":1320,"children":1321},{},[1322,1327],{"type":504,"tag":520,"props":1323,"children":1324},{},[1325],{"type":510,"value":1326},"Sentry",{"type":510,"value":1328},"：业界标杆。提供错误聚合、SourceMap 关联、版本管理、告警等一站式服务。",{"type":504,"tag":756,"props":1330,"children":1331},{},[1332,1337],{"type":504,"tag":520,"props":1333,"children":1334},{},[1335],{"type":510,"value":1336},"LogRocket",{"type":510,"value":1338},"：可以录制用户会话的视频，像素级复现用户操作和 bug 现场，是排查疑难杂症的神器。",{"type":504,"tag":528,"props":1340,"children":1341},{},[],{"type":504,"tag":532,"props":1343,"children":1345},{"id":1344},"_3-前端指标-metrics",[1346],{"type":510,"value":1347},"3. 前端指标 (Metrics)",{"type":504,"tag":516,"props":1349,"children":1350},{},[1351],{"type":510,"value":1352},"指标提供了系统健康状况的宏观视图。",{"type":504,"tag":745,"props":1354,"children":1356},{"id":1355},"a-关键指标-key-metrics",[1357],{"type":510,"value":1358},"A. 关键指标 (Key Metrics)",{"type":504,"tag":752,"props":1360,"children":1361},{},[1362,1372,1382,1392],{"type":504,"tag":756,"props":1363,"children":1364},{},[1365,1370],{"type":504,"tag":520,"props":1366,"children":1367},{},[1368],{"type":510,"value":1369},"性能指标 (Performance)",{"type":510,"value":1371},"：Core Web Vitals (LCP, INP, CLS), FCP, TTFB。",{"type":504,"tag":756,"props":1373,"children":1374},{},[1375,1380],{"type":504,"tag":520,"props":1376,"children":1377},{},[1378],{"type":510,"value":1379},"可用性指标 (Availability)",{"type":510,"value":1381},"：API 成功率、资源加载成功率。",{"type":504,"tag":756,"props":1383,"children":1384},{},[1385,1390],{"type":504,"tag":520,"props":1386,"children":1387},{},[1388],{"type":510,"value":1389},"流量指标 (Traffic)",{"type":510,"value":1391},"：PV (Page View), UV (Unique Visitor)。",{"type":504,"tag":756,"props":1393,"children":1394},{},[1395,1400],{"type":504,"tag":520,"props":1396,"children":1397},{},[1398],{"type":510,"value":1399},"业务指标 (Business)",{"type":510,"value":1401},"：转化率、功能使用率。",{"type":504,"tag":745,"props":1403,"children":1405},{"id":1404},"b-如何采集与展示",[1406],{"type":510,"value":1407},"B. 如何采集与展示",{"type":504,"tag":752,"props":1409,"children":1410},{},[1411,1468,1486],{"type":504,"tag":756,"props":1412,"children":1413},{},[1414,1419,1421],{"type":504,"tag":520,"props":1415,"children":1416},{},[1417],{"type":510,"value":1418},"采集",{"type":510,"value":1420},"：\n",{"type":504,"tag":752,"props":1422,"children":1423},{},[1424,1442],{"type":504,"tag":756,"props":1425,"children":1426},{},[1427,1432,1434,1440],{"type":504,"tag":520,"props":1428,"children":1429},{},[1430],{"type":510,"value":1431},"Core Web Vitals",{"type":510,"value":1433},": 使用 Google 的 ",{"type":504,"tag":810,"props":1435,"children":1437},{"className":1436},[],[1438],{"type":510,"value":1439},"web-vitals",{"type":510,"value":1441}," 库。",{"type":504,"tag":756,"props":1443,"children":1444},{},[1445,1450,1452,1458,1460,1466],{"type":504,"tag":520,"props":1446,"children":1447},{},[1448],{"type":510,"value":1449},"API 成功率",{"type":510,"value":1451},": 封装 ",{"type":504,"tag":810,"props":1453,"children":1455},{"className":1454},[],[1456],{"type":510,"value":1457},"fetch",{"type":510,"value":1459}," 或 ",{"type":504,"tag":810,"props":1461,"children":1463},{"className":1462},[],[1464],{"type":510,"value":1465},"axios",{"type":510,"value":1467},"，在拦截器中统计请求的成功与失败。",{"type":504,"tag":756,"props":1469,"children":1470},{},[1471,1476,1478,1484],{"type":504,"tag":520,"props":1472,"children":1473},{},[1474],{"type":510,"value":1475},"发送",{"type":510,"value":1477},"：通常采用“信标”(Beacon) API (",{"type":504,"tag":810,"props":1479,"children":1481},{"className":1480},[],[1482],{"type":510,"value":1483},"navigator.sendBeacon",{"type":510,"value":1485},") 在页面卸载前发送数据，因为它不会阻塞页面导航且能保证数据送达。",{"type":504,"tag":756,"props":1487,"children":1488},{},[1489,1494,1496,1501,1503,1508,1510,1515],{"type":504,"tag":520,"props":1490,"children":1491},{},[1492],{"type":510,"value":1493},"存储与可视化",{"type":510,"value":1495},"：将数据发送到 ",{"type":504,"tag":520,"props":1497,"children":1498},{},[1499],{"type":510,"value":1500},"Prometheus",{"type":510,"value":1502}," (时序数据库) + ",{"type":504,"tag":520,"props":1504,"children":1505},{},[1506],{"type":510,"value":1507},"Grafana",{"type":510,"value":1509}," (可视化面板) 或商业服务如 ",{"type":504,"tag":520,"props":1511,"children":1512},{},[1513],{"type":510,"value":1514},"Datadog",{"type":510,"value":782},{"type":504,"tag":516,"props":1517,"children":1518},{},[1519],{"type":504,"tag":520,"props":1520,"children":1521},{},[1522,1524,1529],{"type":510,"value":1523},"示例：使用 ",{"type":504,"tag":810,"props":1525,"children":1527},{"className":1526},[],[1528],{"type":510,"value":1439},{"type":510,"value":1530}," 库",{"type":504,"tag":871,"props":1532,"children":1534},{"className":873,"code":1533,"language":875,"meta":876,"style":876},"import { onLCP, onINP, onCLS } from 'web-vitals';\n\nonLCP(console.log);\nonINP(console.log);\nonCLS(console.log);\n",[1535],{"type":504,"tag":810,"props":1536,"children":1537},{"__ignoreMap":876},[1538,1566,1573,1586,1598],{"type":504,"tag":882,"props":1539,"children":1540},{"class":884,"line":885},[1541,1546,1551,1556,1561],{"type":504,"tag":882,"props":1542,"children":1543},{"style":933},[1544],{"type":510,"value":1545},"import",{"type":504,"tag":882,"props":1547,"children":1548},{"style":899},[1549],{"type":510,"value":1550}," { onLCP, onINP, onCLS } ",{"type":504,"tag":882,"props":1552,"children":1553},{"style":933},[1554],{"type":510,"value":1555},"from",{"type":504,"tag":882,"props":1557,"children":1558},{"style":916},[1559],{"type":510,"value":1560}," 'web-vitals'",{"type":504,"tag":882,"props":1562,"children":1563},{"style":899},[1564],{"type":510,"value":1565},";\n",{"type":504,"tag":882,"props":1567,"children":1568},{"class":884,"line":895},[1569],{"type":504,"tag":882,"props":1570,"children":1571},{"emptyLinePlaceholder":1087},[1572],{"type":510,"value":1090},{"type":504,"tag":882,"props":1574,"children":1575},{"class":884,"line":944},[1576,1581],{"type":504,"tag":882,"props":1577,"children":1578},{"style":905},[1579],{"type":510,"value":1580},"onLCP",{"type":504,"tag":882,"props":1582,"children":1583},{"style":899},[1584],{"type":510,"value":1585},"(console.log);\n",{"type":504,"tag":882,"props":1587,"children":1588},{"class":884,"line":953},[1589,1594],{"type":504,"tag":882,"props":1590,"children":1591},{"style":905},[1592],{"type":510,"value":1593},"onINP",{"type":504,"tag":882,"props":1595,"children":1596},{"style":899},[1597],{"type":510,"value":1585},{"type":504,"tag":882,"props":1599,"children":1600},{"class":884,"line":967},[1601,1606],{"type":504,"tag":882,"props":1602,"children":1603},{"style":905},[1604],{"type":510,"value":1605},"onCLS",{"type":504,"tag":882,"props":1607,"children":1608},{"style":899},[1609],{"type":510,"value":1585},{"type":504,"tag":528,"props":1611,"children":1612},{},[],{"type":504,"tag":532,"props":1614,"children":1616},{"id":1615},"_4-前端在链路追踪中的角色-tracing",[1617],{"type":510,"value":1618},"4. 前端在链路追踪中的角色 (Tracing)",{"type":504,"tag":516,"props":1620,"children":1621},{},[1622],{"type":510,"value":1623},"分布式链路追踪 (Distributed Tracing) 旨在追踪一个请求从用户发起，到经过前端、BFF、后端微服务，再到数据库，最后返回给用户的完整旅程。",{"type":504,"tag":745,"props":1625,"children":1627},{"id":1626},"前端为何关键",[1628],{"type":510,"value":1629},"前端为何关键？",{"type":504,"tag":516,"props":1631,"children":1632},{},[1633,1635,1640],{"type":510,"value":1634},"前端是",{"type":504,"tag":520,"props":1636,"children":1637},{},[1638],{"type":510,"value":1639},"全链路的起点",{"type":510,"value":1641},"。一个完整的 Trace 如果没有前端这一环，就无法衡量用户的真实端到端体验，也无法区分问题是出在网络、CDN 还是服务器。",{"type":504,"tag":745,"props":1643,"children":1645},{"id":1644},"实现原理trace-context-的生成与传递",[1646],{"type":510,"value":1647},"实现原理：Trace Context 的生成与传递",{"type":504,"tag":858,"props":1649,"children":1650},{},[1651,1676,1712,1735],{"type":504,"tag":756,"props":1652,"children":1653},{},[1654,1659,1661,1667,1669,1675],{"type":504,"tag":520,"props":1655,"children":1656},{},[1657],{"type":510,"value":1658},"生成 Trace ID",{"type":510,"value":1660},"：当用户在前端执行一个关键操作（如页面加载或点击按钮发起 API 请求）时，前端的监控 SDK 会生成一个全局唯一的 ",{"type":504,"tag":810,"props":1662,"children":1664},{"className":1663},[],[1665],{"type":510,"value":1666},"Trace ID",{"type":510,"value":1668}," 和一个代表当前操作的 ",{"type":504,"tag":810,"props":1670,"children":1672},{"className":1671},[],[1673],{"type":510,"value":1674},"Span ID",{"type":510,"value":782},{"type":504,"tag":756,"props":1677,"children":1678},{},[1679,1684,1686,1692,1694,1700,1702],{"type":504,"tag":520,"props":1680,"children":1681},{},[1682],{"type":510,"value":1683},"传递 Trace Context",{"type":510,"value":1685},"：前端在发起 API 请求时，会将这个 Trace Context（通常包含 ",{"type":504,"tag":810,"props":1687,"children":1689},{"className":1688},[],[1690],{"type":510,"value":1691},"traceparent",{"type":510,"value":1693}," 和 ",{"type":504,"tag":810,"props":1695,"children":1697},{"className":1696},[],[1698],{"type":510,"value":1699},"tracestate",{"type":510,"value":1701},"）注入到 HTTP 请求头中。",{"type":504,"tag":871,"props":1703,"children":1707},{"className":1704,"code":1706,"language":510},[1705],"language-text","\u002F\u002F W3C Trace Context 标准请求头\ntraceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\n",[1708],{"type":504,"tag":810,"props":1709,"children":1710},{"__ignoreMap":876},[1711],{"type":510,"value":1706},{"type":504,"tag":756,"props":1713,"children":1714},{},[1715,1720,1722,1727,1729,1734],{"type":504,"tag":520,"props":1716,"children":1717},{},[1718],{"type":510,"value":1719},"后端接收与传递",{"type":510,"value":1721},"：后端服务（BFF、微服务）必须配置为能够识别并解析这个请求头。当它处理完请求并调用下一个服务时，它会继续传递 ",{"type":504,"tag":810,"props":1723,"children":1725},{"className":1724},[],[1726],{"type":510,"value":1666},{"type":510,"value":1728},"，并生成自己的 ",{"type":504,"tag":810,"props":1730,"children":1732},{"className":1731},[],[1733],{"type":510,"value":1674},{"type":510,"value":782},{"type":504,"tag":756,"props":1736,"children":1737},{},[1738,1743],{"type":504,"tag":520,"props":1739,"children":1740},{},[1741],{"type":510,"value":1742},"聚合与可视化",{"type":510,"value":1744},"：所有服务都将自己的 Span 信息（包含 Trace ID, Span ID, Parent Span ID, 操作名称, 耗时等）上报给一个收集器 (Collector)，最终在 Jaeger, Zipkin 或 Sentry 等工具中聚合成一个完整的调用链火焰图。",{"type":504,"tag":745,"props":1746,"children":1748},{"id":1747},"推荐方案opentelemetry",[1749],{"type":510,"value":1750},"推荐方案：OpenTelemetry",{"type":504,"tag":516,"props":1752,"children":1753},{},[1754,1759],{"type":504,"tag":520,"props":1755,"children":1756},{},[1757],{"type":510,"value":1758},"OpenTelemetry (OTel)",{"type":510,"value":1760}," 是一个 CNCF 的开源项目，它提供了一套与供应商无关的 API、SDK 和工具，用于检测、生成、收集和导出遥测数据（指标、日志、链路）。这是未来的行业标准。",{"type":504,"tag":516,"props":1762,"children":1763},{},[1764,1769],{"type":504,"tag":520,"props":1765,"children":1766},{},[1767],{"type":510,"value":1768},"在前端集成 OTel 的基本步骤",{"type":510,"value":802},{"type":504,"tag":858,"props":1771,"children":1772},{},[1773,1793,1806],{"type":504,"tag":756,"props":1774,"children":1775},{},[1776,1778,1784,1785,1791],{"type":510,"value":1777},"安装 OTel SDK 和相关检测库 (",{"type":504,"tag":810,"props":1779,"children":1781},{"className":1780},[],[1782],{"type":510,"value":1783},"@opentelemetry\u002Fsdk-trace-web",{"type":510,"value":924},{"type":504,"tag":810,"props":1786,"children":1788},{"className":1787},[],[1789],{"type":510,"value":1790},"@opentelemetry\u002Finstrumentation-document-load",{"type":510,"value":1792}," 等)。",{"type":504,"tag":756,"props":1794,"children":1795},{},[1796,1798,1804],{"type":510,"value":1797},"配置 ",{"type":504,"tag":810,"props":1799,"children":1801},{"className":1800},[],[1802],{"type":510,"value":1803},"TracerProvider",{"type":510,"value":1805}," 和导出器 (Exporter) 将数据发送到后端收集器。",{"type":504,"tag":756,"props":1807,"children":1808},{},[1809],{"type":510,"value":1810},"自动检测库会自动为页面加载、XHR\u002FFetch 请求等创建 Spans。",{"type":504,"tag":528,"props":1812,"children":1813},{},[],{"type":504,"tag":532,"props":1815,"children":1817},{"id":1816},"_5-关联阅读",[1818],{"type":510,"value":1819},"5. 关联阅读",{"type":504,"tag":752,"props":1821,"children":1822},{},[1823,1842,1858],{"type":504,"tag":756,"props":1824,"children":1825},{},[1826,1831,1833],{"type":504,"tag":520,"props":1827,"children":1828},{},[1829],{"type":510,"value":1830},"OpenTelemetry 官方文档",{"type":510,"value":1832},": ",{"type":504,"tag":1834,"props":1835,"children":1839},"a",{"href":1836,"rel":1837},"https:\u002F\u002Fopentelemetry.io\u002Fdocs\u002Finstrumentation\u002Fjs\u002F",[1838],"nofollow",[1840],{"type":510,"value":1841},"opentelemetry.io",{"type":504,"tag":756,"props":1843,"children":1844},{},[1845,1850,1851],{"type":504,"tag":520,"props":1846,"children":1847},{},[1848],{"type":510,"value":1849},"Sentry 官方文档",{"type":510,"value":1832},{"type":504,"tag":1834,"props":1852,"children":1855},{"href":1853,"rel":1854},"https:\u002F\u002Fdocs.sentry.io\u002Fplatforms\u002Fjavascript\u002F",[1838],[1856],{"type":510,"value":1857},"Frontend Monitoring",{"type":504,"tag":756,"props":1859,"children":1860},{},[1861,1866,1867],{"type":504,"tag":520,"props":1862,"children":1863},{},[1864],{"type":510,"value":1865},"Google Web Vitals",{"type":510,"value":1832},{"type":504,"tag":1834,"props":1868,"children":1871},{"href":1869,"rel":1870},"https:\u002F\u002Fweb.dev\u002Fvitals",[1838],[1872],{"type":510,"value":1873},"web.dev\u002Fvitals",{"type":504,"tag":1875,"props":1876,"children":1877},"style",{},[1878],{"type":510,"value":1879},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":876,"searchDepth":895,"depth":895,"links":1881},[1882,1883,1888,1892,1897],{"id":534,"depth":895,"text":537},{"id":735,"depth":895,"text":738,"children":1884},[1885,1886,1887],{"id":747,"depth":944,"text":750},{"id":853,"depth":944,"text":856},{"id":1312,"depth":944,"text":1315},{"id":1344,"depth":895,"text":1347,"children":1889},[1890,1891],{"id":1355,"depth":944,"text":1358},{"id":1404,"depth":944,"text":1407},{"id":1615,"depth":895,"text":1618,"children":1893},[1894,1895,1896],{"id":1626,"depth":944,"text":1629},{"id":1644,"depth":944,"text":1647},{"id":1747,"depth":944,"text":1750},{"id":1816,"depth":895,"text":1819},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1899},"\u003Cpath fill=\"currentColor\" d=\"m10.828 12l4.95 4.95l-1.414 1.415L8 12l6.364-6.364l1.414 1.414z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1901},"\u003Cpath fill=\"currentColor\" d=\"M3 4h18v2H3zm0 7h12v2H3zm0 7h18v2H3z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1903},"\u003Cpath fill=\"currentColor\" d=\"m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z\"\u002F>",{"left":4,"top":4,"width":1905,"height":1905,"rotate":4,"vFlip":6,"hFlip":6,"body":1906},1024,"\u003Cpath fill=\"currentColor\" d=\"M768 832a128 128 0 0 1-128 128H192A128 128 0 0 1 64 832V384a128 128 0 0 1 128-128v64a64 64 0 0 0-64 64v448a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64z\"\u002F>\u003Cpath fill=\"currentColor\" d=\"M384 128a64 64 0 0 0-64 64v448a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64V192a64 64 0 0 0-64-64zm0-64h448a128 128 0 0 1 128 128v448a128 128 0 0 1-128 128H384a128 128 0 0 1-128-128V192A128 128 0 0 1 384 64\"\u002F>"]