diff --git a/.changeset/eighty-bananas-give.md b/.changeset/eighty-bananas-give.md new file mode 100644 index 000000000000..2f6c7ee3dc5b --- /dev/null +++ b/.changeset/eighty-bananas-give.md @@ -0,0 +1,6 @@ +--- +'@modern-js/server-core': patch +--- + +perf: emit a counter event when ssr fallback +perf: ssr 降级时进行打点 diff --git a/packages/document/main-doc/docs/en/guides/advanced-features/server-monitor/logger.mdx b/packages/document/main-doc/docs/en/guides/advanced-features/server-monitor/logger.mdx index 95e7f95f9795..f058fe9609f3 100644 --- a/packages/document/main-doc/docs/en/guides/advanced-features/server-monitor/logger.mdx +++ b/packages/document/main-doc/docs/en/guides/advanced-features/server-monitor/logger.mdx @@ -6,18 +6,19 @@ Log events are distributed by Modern.js as events of type `log`. Based on server-side runtime logic, Modern.js provides the following log events: -| Stage | Message | Level | -| --------------- | -------------------------------------------- | ----- | -| RENDER_HTML | App Render To HTML | error | -| RENDER_STREAM | An error occurs during streaming SSR | error | -| RENDER_SHELL | An error occurs during streaming render shell | error | +| Stage | Message | Level | +| -------------- | --------------------------------------------- | ----- | +| RENDER_HTML | App Render To HTML | error | +| RENDER_STREAM | An error occurs during streaming SSR | error | +| RENDER_SHELL | An error occurs during streaming render shell | error | +| RENDER_DEGRADE | SSR Fallback to CSR | debug | Modern.js also retains SSR logs from legacy versions using `useLoader`: -| Stage | Message | Level | -| ------------- | ------------------------------- | ----- | -| PRERENDER | App Prerender | error | -| USE_LOADER | App run useLoader | error | +| Stage | Message | Level | +| ---------- | ----------------- | ----- | +| PRERENDER | App Prerender | error | +| USE_LOADER | App run useLoader | error | :::tip The `useLoader` API is now deprecated. We recommend migrating to convention-based routing and using Data Loaders for data fetching. Applications already using Data Loaders can enable [`ssr.disablePrerender`](/configure/app/server/ssr.html#object-type) to disable prerendering and improve SSR performance. diff --git a/packages/document/main-doc/docs/en/guides/advanced-features/server-monitor/metrics.mdx b/packages/document/main-doc/docs/en/guides/advanced-features/server-monitor/metrics.mdx index a5731c6fd9b5..742b334aaa61 100644 --- a/packages/document/main-doc/docs/en/guides/advanced-features/server-monitor/metrics.mdx +++ b/packages/document/main-doc/docs/en/guides/advanced-features/server-monitor/metrics.mdx @@ -10,13 +10,14 @@ Based on server-side runtime logic, Modern.js provides the following metric even | Key | Description | | ------------------------ | ------------------------ | -| server-handle-request | EdenX Server request handling duration | +| server-handle-request | Modern.js Server request handling duration | | ssr-render-shell | [SSR] When using Streaming SSR, React renders a shell for early streaming. This marks shell rendering completion time | | ssr-render-html | [SSR] Time taken by React to render component tree to HTML (typically under 50ms) | -| server-middleware | Total execution time of EdenX custom server middlewares | +| server-middleware | Total execution time of Modern.js custom server middlewares | | server-loader | Server-side Data Loader total duration | | server-loader-#id | Individual Data Loader durations on server-side | | server-loader-navigation | Server-side Data Loader duration during client navigation | +| calledby.ssr.fallback | SSR fallback triggered | Modern.js server workflow diagram: diff --git a/packages/document/main-doc/docs/zh/guides/advanced-features/server-monitor/logger.mdx b/packages/document/main-doc/docs/zh/guides/advanced-features/server-monitor/logger.mdx index e80abaf8186b..891e420e5a8a 100644 --- a/packages/document/main-doc/docs/zh/guides/advanced-features/server-monitor/logger.mdx +++ b/packages/document/main-doc/docs/zh/guides/advanced-features/server-monitor/logger.mdx @@ -6,18 +6,19 @@ 基于服务端运行逻辑,Modern.js 在内部提供了以下日志事件: -| 阶段 | 消息 | Level | -| ------------- | -------------------------------------------- | ----- | -| RENDER_HTML | App Render To HTML | error | -| RENDER_STREAM | An error occurs during streaming SSR | error | -| RENDER_SHELL | An error occurs during streaming render shell | error | +| 阶段 | 消息 | Level | +| -------------- | --------------------------------------------- | ----- | +| RENDER_HTML | App Render To HTML | error | +| RENDER_STREAM | An error occurs during streaming SSR | error | +| RENDER_SHELL | An error occurs during streaming render shell | error | +| RENDER_DEGRADE | SSR Fallback to CSR | debug | Modern.js 也保留了旧版本中使用 `useLoader` 获取数据时的 SSR 日志: -| 阶段 | 消息 | Level | -| ------------- | -------------------------------------------- | ----- | -| PRERENDER | App Prerender | error | -| USE_LOADER | App run useLoader | error | +| 阶段 | 消息 | Level | +| ---------- | ----------------- | ----- | +| PRERENDER | App Prerender | error | +| USE_LOADER | App run useLoader | error | :::tip `useLoader` API 目前已经废弃,建议迁移到约定式路由并使用 Data Loader 进行数据获取。已经使用 Data Loader 的应用,可以开启 [`ssr.disablePrerender`](/configure/app/server/ssr.html#object-类型),禁止预渲染,提升 SSR 性能。 @@ -28,5 +29,3 @@ Modern.js 也保留了旧版本中使用 `useLoader` 获取数据时的 SSR 日 import InternalLogger from '@site-docs/components/internal-logger.mdx'; - - diff --git a/packages/document/main-doc/docs/zh/guides/advanced-features/server-monitor/metrics.mdx b/packages/document/main-doc/docs/zh/guides/advanced-features/server-monitor/metrics.mdx index bed963054e47..139695ff4aad 100644 --- a/packages/document/main-doc/docs/zh/guides/advanced-features/server-monitor/metrics.mdx +++ b/packages/document/main-doc/docs/zh/guides/advanced-features/server-monitor/metrics.mdx @@ -8,21 +8,21 @@ 基于服务端运行逻辑,Modern.js 在内部提供了以下指标事件: -| Key | 描述 | -| ------------------------ | --------------- | -| server-handle-request | EdenX Server 处理请求单次耗时 | -| ssr-render-shell | [SSR]在使用 Streaming SSR 时, React 将渲染一个套壳(shell)优先传输。这里表明套壳渲染完成时间 | -| ssr-render-html | [SSR] React 将组件树渲染成 html 所消耗的时间,通常不会超过 50ms | -| server-middleware | EdenX 自定义 Server `Middleware` 执行总时 | -| server-loader | Server 端整体 Data Loader 耗时 | -| server-loader-#id | Server 端各个 Data Loader 耗时 | -| server-loader-navigation | 前端导航时,服务端 Data Loader 的整体耗时 | +| Key | 描述 | +| ------------------------ | -------------------------------------------------------------------------------------------- | +| server-handle-request | Modern.js Server 处理请求单次耗时 | +| ssr-render-shell | [SSR]在使用 Streaming SSR 时, React 将渲染一个套壳(shell)优先传输。这里表明套壳渲染完成时间 | +| ssr-render-html | [SSR] React 将组件树渲染成 html 所消耗的时间,通常不会超过 50ms | +| server-middleware | Modern.js 自定义 Server `Middleware` 执行总时 | +| server-loader | Server 端整体 Data Loader 耗时 | +| server-loader-#id | Server 端各个 Data Loader 耗时 | +| server-loader-navigation | 前端导航时,服务端 Data Loader 的整体耗时 | +| calledby.ssr.fallback | SSR 降级时触发 | Modenr.js 服务端流程如图所示: ![server](https://lf3-static.bytednsdoc.com/obj/eden-cn/eeeh7uhbepxlpe/edenx-website/e374def0-c179-40aa-9cfe-e82e181663b1.jpeg) - ## 内置 Monitor import InternalMetrics from '@site-docs/components/internal-metrics.mdx'; diff --git a/packages/server/core/src/plugins/render/render.ts b/packages/server/core/src/plugins/render/render.ts index 1173eda47f6b..b7d8d4a9c631 100644 --- a/packages/server/core/src/plugins/render/render.ts +++ b/packages/server/core/src/plugins/render/render.ts @@ -29,6 +29,8 @@ import { renderRscHandler } from './renderRscHandler'; import { serverActionHandler } from './serverActionHandler'; import { type SSRRenderOptions, ssrRender } from './ssrRender'; +const SSR_FALLBACK_COUNTER_NAME = 'calledby.ssr.fallback'; + interface CreateRenderOptions { pwd: string; routes: ServerRoute[]; @@ -155,6 +157,18 @@ export async function createRender({ const fallbackWrapper: FallbackWrapper = async (reason, error?) => { fallbackReason = reason; + + monitors?.counter(SSR_FALLBACK_COUNTER_NAME, { + fallback_type: reason, + pathname: forMatchpathname, + }); + + monitors.debug( + `SSR Fallback to CSR - reason = %s, req.url = %s`, + reason, + forMatchpathname, + ); + return onFallback?.(reason, { logger, reporter, metrics }, error); };