-
Notifications
You must be signed in to change notification settings - Fork 433
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
Do not invalidate pages in visits that don't render #1144
Conversation
Fixes #1047 Rendering a frame with a data-turbo-action was rendering the response twice. First, the `FrameController` in charge of the frame renders the response using a FrameRenderer. https://github.com/hotwired/turbo/blob/b7187f13b216cee8c855ef1fb6ac790b40dde361/src/core/frames/frame_controller.js#L314 But when we update a frame with a data-turbo-action, we also issue a visit to update the browser URL & history: https://github.com/hotwired/turbo/blob/b7187f13b216cee8c855ef1fb6ac790b40dde361/src/core/frames/frame_controller.js#L373 This session visit was also triggering a loadResponse callback, which in turn was instantiating a `PageSnapshot` and rendering it. This caused problems when the response for the frame didn't include all the tracked assets in the page. The page snapshot considered the assets stale and triggered a reload of the page with reason `tracked_element_mismatch`. This commit fixes the issue by not rendering the page snapshot when navigating within a frame. The commit includes a new test that reproduces the issue returning a turbo frame in an HTML document with an empty `<head>`. Before this fix, the response would trigger a full page reload.
c397232
to
3709bb1
Compare
Nice! A couple of things: Is What is the frame visit actually doing? It doesn’t render and it’s instantiated with |
😵💫 From the looks of the failing tests (any my own brief manual tests), it looks like the visit is doing a fair bit (on the caching front?) |
Skipping the rendering when the visit comes from a frame navigation breaks a few tests related to caching. Instead, let's make sure we don't invalidate the view if the visit is not rendering.
That's a good idea. I've updated the PR so now we use
This was introduced in #398 to add navigation-like behavior to to frame navigations with For now this small patch fixes #1047, which is the main blocker for a Turbo 8 final release. If we're happy with this I think are ready for the final release. |
src/core/view.js
Outdated
@@ -77,7 +78,7 @@ export class View { | |||
this.#resolveRenderPromise(undefined) | |||
delete this.renderPromise | |||
} | |||
} else { | |||
} else if (willRender) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it necessarily needs addressed here, but I find it confusing that we have shouldRender
and willRender
cases. It's not clear how they are different. If you should render, doesn't that imply that you will?
I think the easiest answer is probably to rename willRender
. It really means that the view is being used in a context where rendering is not required. Or more specifically, it's being used to do all the other operations that normally accompany a page render, but after a frame update has already rendered.
But ideally we'd separate the responsibilities to avoid this sort of conditional check happening here. So maybe we're as well to stick with the existing language for now, and then look at refactoring in another PR which keeps the same behaviour?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, agreed to all of that 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree the shouldRender
/ willRender
is confusing here.
Is there a plan to refactor before releasing v8? If not then I reckon we should clarify willRender
by renaming and adding a comment. e.g.:
// A workaround to ignore tracked element mismatch reloads when performing a promoted Visit from a frame navigation
const shouldInvalidate = willRender
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd opened #741 to limit the occurrence of willRender
.
I'd also opened #430 to try and introduce some abstractions for Frame navigation. They've both been kept up to date originally, but I eventually stopped dragging them forward. I've rebased them to catch up with the latest.
Would either be worthwhile to consider for inclusion in 8?
@afcapel Sorry to bother with this but, have you considered any of these concerns before releasing the stable version? #1080 (Turbo crashes completely, I opened #1098 to address it). Other concerns with full page reloading when assets are diferent #1105 and #1116. Thanks! |
I second that closing #1080 (causing blank pages with replace navigations!), would need to be part of a stable release. The potential fix in #1098 makes a lot of sense. We're seeing flashes of unwanted content (stale snapshots) while performing refreshes with morphing. It kinda defeats the purpose of the new shiny morph refreshes. Let me know if we can do anything to help out here? |
Ok, I'll do a final round before publishing a RC 👍 Aiming to fix:
All of them have PRs already open to address them, so it's a matter of validating and merging. Anything else we should consider a blocker? |
Would #1123 make sense to include as well? |
@seanpdoyle has made a big effort with contributions and there are still many unmerged, several bug fixes and some very old ones. If you have time, it would be great if you could review as much as you can, obviously within your availability. |
Sure, I'd also like to clean up the remaining PRs, but unfortunately right now I'm focused on another project and have limited availability. We could always do more, but for context, we've already merged 72 PRs since v7.3.0. |
Out of the pull requests that I've opened at the moment, I consider two worth merging into 8:
The others either require additional troubleshooting, or are refactors and abstractions. |
Cool, thanks @seanpdoyle I'll be sure to review those two as well before the RC. As for other refactorings, they are of course welcome but they'll probably have to wait until after the v8 release. |
Fixes #1047
Supersedes #1143
Rendering a frame with a data-turbo-action was rendering the response twice.
First, the
FrameController
in charge of the frame renders the response using aFrameRenderer
, while processing callback theloadResponse
callback.turbo/src/core/frames/frame_controller.js
Line 314 in b7187f1
But when we update a frame with a data-turbo-action, we also issue a visit to update the browser URL & history:
turbo/src/core/frames/frame_controller.js
Line 373 in b7187f1
This session visit was also triggering a
loadResponse
callback, which in turn was instantiating aPageSnapshot
and rendering it.This caused problems when the response for the frame didn't include all the tracked assets in the page. The page snapshot considered the assets stale and triggered a reload of the page with reason
tracked_element_mismatch
.This commit fixes the issue by not rendering the page snapshot when navigating from a frame.
The commit includes a new test that reproduces the issue returning a turbo frame in an HTML document with an empty
<head>
. Before this fix, the response would trigger a full page reload.This is the call stack before the fix. Notice the two calls to
loadResponse
.