Skip to content

Conversation

thejackshelton
Copy link
Member

@thejackshelton thejackshelton commented Sep 1, 2025

What is it?

  • Feature / enhancement
  • Bug
  • Docs / tests / types / typos

Description

This PR implements automatic SSR backpatching, enabling SSR-correct relationships between components whose render order can't be guaranteed. Unlike traditional SSR where once HTML is sent you can't modify it, backpatching automatically corrects attribute relationships after streaming completes.

Checklist

  • My code follows the developer guidelines of this project
  • I performed a self-review of my own code
  • I added a changeset with pnpm change
  • I made corresponding changes to the Qwik docs
  • I added new tests to cover the fix / functionality

@thejackshelton thejackshelton requested a review from a team as a code owner September 1, 2025 20:04
@thejackshelton thejackshelton requested review from a team as code owners September 1, 2025 20:04
Copy link

changeset-bot bot commented Sep 1, 2025

🦋 Changeset detected

Latest commit: 9ffb42d

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

pkg-pr-new bot commented Sep 1, 2025

Open in StackBlitz

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/core@7900
npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/router@7900
npm i https://pkg.pr.new/QwikDev/qwik/eslint-plugin-qwik@7900
npm i https://pkg.pr.new/QwikDev/qwik/create-qwik@7900

commit: 9ffb42d

Copy link
Contributor

github-actions bot commented Sep 1, 2025

built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
qwik-docs ✅ Ready (View Log) Visit Preview 9ffb42d

Copy link
Member

@wmertens wmertens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is excellent! Some small nitpicks.

Also, this looks like a good start for OOS, but at that point there might be a noticeable delay between DOM content visible on screen and end of the document arriving in the browser.

How should the backpatcher be changed to allow patching while streaming? Maybe emit the backpatcher as soon as it's needed and then emit script tags with patches every 50ms or so?

That is assuming you can change DOM while it's still streaming in 🤔

@thejackshelton
Copy link
Member Author

thejackshelton commented Sep 3, 2025

This is excellent! Some small nitpicks.

Also, this looks like a good start for OOS, but at that point there might be a noticeable delay between DOM content visible on screen and end of the document arriving in the browser.

How should the backpatcher be changed to allow patching while streaming? Maybe emit the backpatcher as soon as it's needed and then emit script tags with patches every 50ms or so?

That is assuming you can change DOM while it's still streaming in 🤔

Yes there would definitely be a noticeable delay in that case. There is only one data script per container rather than mini scoped ones. This is because the executor script runs at the end anyways and you can improve the encoding of the data script a ton, especially with multiple component instances.

I definitely see it as a separate thing. We should be able to see from the scheduler if the consumer clearly intends to be doing OOO Streaming, in that case we can then emit the script tags / wrapper approach as we go.

In Marko 6 they opt-in by providing fallback UI.

'@qwik.dev/core': patch
---

feat: add SSR backpatching (attributes-only) to ensure SSR/CSR parity for signal-driven attributes; limited to attribute updates (not OoO streaming)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the use-case a little bit better for qwik users? e.g. when is it necessary, how it works, what needs to be done to use it (as an overview ofc)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm... I could try from a high level, although that is a lot to put in a changelog

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:

feat: add SSR backpatching (attributes-only) to allow parent components to know some information about their children during SSR: like how many children they have, or if a certain child contains an attribute or not... This was already achievable in CSR, and is now possible in SSR too.


This creates problems for component libraries where elements need to reference each other (like form inputs linking to their labels via `aria-labelledby`). If the input streams before its label, it can't know the label's ID to set the relationship.

Backpatching automatically fixes these relationships by updating attributes after the entire page has streamed, giving you the same flexibility as client-side rendering.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a sentence to say something along the lines of "as a developer, you don't need to do anything special. Qwik will automatically detect if it needs to backpatch a certain attribute when necessary".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I can add that in


> Note: This is not Out-of-Order Streaming. It only corrects already-sent attributes without delaying the stream.
### Example
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this "Example without backpatching"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I don't get it. It seemed to me the example shows the problem before the PR. After the PR it will just work right? Better to make that more explicit imo.

@maiieul maiieul moved this from Backlog to Waiting For Review in Qwik Development Sep 9, 2025
@thejackshelton thejackshelton merged commit b470ba3 into build/v2 Sep 9, 2025
20 checks passed
@github-project-automation github-project-automation bot moved this from Waiting For Review to Done in Qwik Development Sep 9, 2025
@thejackshelton thejackshelton deleted the v2-backpatch-script branch September 9, 2025 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants