Repository navigation
feat(trace-view): Add Server Rendering section to pageload span details - #130769
Conversation
A pageload of a static or partially static page can come from HTML that the server rendered earlier for other page loads. The server spans of that render are in another trace, so users cannot find them from this trace. The new section reads page.server_rendering.type and the cache_origin and server_request span links. It shows which part of the page was reused and which part was rendered for this page load, and links to the trace of each. It works for every SDK that sets these attributes, whatever the framework. Move the linked span hook out of the cache lifecycle section, so both sections use it. The section is behind performance-trace-cache-lifecycle.
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 152250c. Configure here.
…uest Go to span took the first http.server span below the pageload. That can be an API request of the page. Use the span that the tree moved below the pageload as the server request of the page.
nsdeschenes
left a comment
There was a problem hiding this comment.
Two small nits to take a peek at, rest LGTM 🚢
| const cacheOrigin = links?.find( | ||
| link => getSpanLinkType(link) === CACHE_ORIGIN_LINK_TYPE | ||
| ); | ||
| const serverRequest = links?.find( | ||
| link => getSpanLinkType(link) === SERVER_REQUEST_LINK_TYPE | ||
| ); |
There was a problem hiding this comment.
nit: Can we pull out these calls to getSpanLinkType(link) out of these .find() calls, and assign to a variable then just pass that variable.
Something like:
const linkType = getSpanLinkType(link)
const cacheOrigin = links?.find(
link => linkType === CACHE_ORIGIN_LINK_TYPE
);
const serverRequest = links?.find(
link => linkType === SERVER_REQUEST_LINK_TYPE
);
There was a problem hiding this comment.
good point but your proposed helper does not work as link only exists in the callback. but I'll add a small helper.
There was a problem hiding this comment.
Ahhh shoot sorry i misread it 🤦
| /** Dashed, because the spans of a reused part are never in this trace. */ | ||
| const ReusedBlock = styled(Stack)` | ||
| border: 1px dashed ${p => p.theme.tokens.border.primary}; | ||
| `; |
There was a problem hiding this comment.
nit: Looking at the docs, i think you should be able to pass this directly to the border property on the Stack. Though you may need to call useTheme to get the theme value 🤔
This is just part of an effort to maintain the reduction of styled calls throughout the app, if the suggestion doesn't work we can leave as is.
There was a problem hiding this comment.
The border prop only renders a solid line but the dashed line is on purpose to give more meaning to "this span is not in this trace". But I can use border=primary and a style prop to override that.
| }); | ||
|
|
||
| return ( | ||
| <Link to={linkedSpan.to} onClick={linkedSpan.onClick}> |
There was a problem hiding this comment.
Non-blocking: for pages rendered at runtime and reused for more than ~1.5 days (long/no revalidate), this link opens an empty trace because the query only searches around the pageload start right? Is it worth hiding the link or hinting at it in that case, or are we fine leaving it?
There was a problem hiding this comment.
Yes, I'll add a follow-up where we can calculate the render time relibably.
There was a problem hiding this comment.
the conventions PR: getsentry/sentry-conventions#799
Find the cache_origin and server_request links with one helper. Draw the reused block with the Stack border prop. The prop only draws solid lines, so the dashed style stays as an inline style.
… trace (#130771) Stacked on #130769 When the server reuses HTML for a page (a static page, or the static shell of a partially static page), the server spans of that render are in another trace. Until now, the waterfall showed nothing in their place, so it looked like instrumentation was missing. This adds a placeholder row under the document request of each pageload with `page.server_rendering.type`: - **No bar on the timeline.** The render can be hours older than the page load, so the row fills the timeline column with a pattern and the text "Rendered earlier: not on this timeline". - **Visible when the pageload is collapsed,** next to the server request, like a server transaction. For a fully static page: https://sentry-4x3dkn58u.sentry.dev/explore/traces/trace/cdf98425fa8746f79352a8394e385f32/?node=sr-85846057874639b8-server-render×tamp=1794319075 <img width="1375" height="387" alt="image" src="https://github.com/user-attachments/assets/9023504d-1b83-4f7a-9329-4de0c1b6a766" /> For a partially static page: https://sentry-4x3dkn58u.sentry.dev/explore/traces/trace/d5f46a9d8bc640ca8d72c415f1b9b0a7/?fov=0.19530032969846994%2C71.30445552967653&node=span-9e805f433be01de5×tamp=1794326348 <img width="1379" height="491" alt="image" src="https://github.com/user-attachments/assets/a63dddcb-0f7a-49b8-b1fc-54a73f492c82" />

A pageload of a static or partially static page can come from HTML that the server rendered earlier for other page loads. The server spans of that render are in another trace.
The new section reads
page.server_rendering.typeand thecache_originandserver_requestspan links. It shows which part of the page was reused and which part was rendered for this page load, and links to the trace of each.The section is behind performance-trace-cache-lifecycle.
"Show Spans" will highlight the dynamic server span within the trace

When both parts are in another trace (e.g. the dynamic server part arrived too late):

Some trace view example links can be seen in the other PR in the stack: #130771