Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render full documents for requests with Turbo-Frame: header #534

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

seanpdoyle
Copy link
Contributor

Re-submission of #232
Related to hotwired/turbo#1047

Render full documents, including default layout rendering behavior.

Rendering a minimal layout forces turbo:reload events because of the severe difference in the contents of the minimal layout's <head> and the requesting document's fully populated <head>.

@seanpdoyle
Copy link
Contributor Author

As an alternative, we could send the Turbo Action in the Turbo-Action: header, then conditionally include the full layout if that header is present.

@seanpdoyle
Copy link
Contributor Author

seanpdoyle commented Feb 21, 2024

@jorgemanrubia is this change worth re-considering after the introduction of Page Morphing?

To paraphrase the Morphing mental model: "render full HTML documents on the server, then let the client decide how to insert that new content into the document".

Rendering full and valid documents for Turbo Frames is likely to result in similar levels of queries, template renders, and over-the-wire traffic as a full page refresh with Morphing. That also means they stand to benefit from the same kinds of rendering mechanisms that Morphing might influence you to adopt (fragment caching, HTTP caching, etc).

@jorgemanrubia
Copy link
Member

@seanpdoyle the removed layout should only kick in for requests with a Turbo Frame header. Could you put an example of how page refreshes with morphing doesn't play well with this? They seem like unrelated systems to me.

@seanpdoyle
Copy link
Contributor Author

seanpdoyle commented Feb 24, 2024

how page refreshes with morphing doesn't play well with this

I'm sorry for being unclear. I'm suggesting that the Turbo Frame server-side mental model change to be more like Morphing.

Morphing

When submitting a form that redirects back or navigating a link that replaces the page, the server sends a fully formed document. As I understand, the value proposition of a Morphing page refresh is that the server does not care about the diff between what its rendering and what's on the client -- the client will handle negotiating the new content into the existing content. Even if the entirety of the new content is a new flash message, the full <html> document is sent down in the request and it's Turbo responsibility to render it.

Furthermore, the client doesn't communicate anything special to the server. Other than being fetch-initiated requests, the server doesn't require any special headers or information in order to integrate with Morphing.

Frames

From the client's perspective, frames behave in a similar way. Regardless of the contents of the response HTML, Turbo will find the <turbo-frame> element in the response that corresponds to the initiator element based on its [id]. Once it's found, it swaps the new children into the document.

From the server's perspective, the similarities break down. The Turbo-Frame header is a client-side implementation detail that servers expect. Instead of rendering a full document without any additional information from the client, servers use the Turbo-Frame header to determine the response HTML. In the case of turbo-rails, that response HTML can vary wildly based on the presence or absence of that header.

The concept of Frames pre-dates Morphing. In a world where applications are encouraged to enable Morphing for the majority of their pages (instead of other approaches like Frame or Stream form submission responses), any gains won by turbo-rails's server-side decision to skip rendering the page layout are likely to be offset by full document responses elsewhere. This is even more likely with the introduction of <turbo-stream action="refresh"> elements broadcast over Web Sockets.

So what?

Over time, the turbo-rails-driven server-side optimization to return different responses for frames and full pages has led to unintended side-effects and several Issues and codebase workarounds in @hotwired/turbo.

The proposal is that by reversing the optimization and re-establishing the traditional Turbolinks expectations (that the servers responds with full HTML documents and the client expects full HTML documents), we have an opportunity to posit a singular simplified mental model and simplify some of @hotwired/turbo's codepaths and patterns.

Re-submission of [hotwired#232][]
Related to [hotwired/turbo#1047][]

Render full documents, including default layout rendering behavior.

Rendering a minimal layout forces `turbo:reload` events because of the
severe difference in the contents of the minimal layout's `<head>` and
the requesting document's fully populated `<head>`.

[hotwired#232]: hotwired#232
[hotwired/turbo#1047]: hotwired/turbo#1047
@seanpdoyle seanpdoyle force-pushed the render-frames-with-full-document branch from 8e4c72b to 7ca7a35 Compare October 29, 2024 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants