-
-
Notifications
You must be signed in to change notification settings - Fork 34
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
Optimization when rendering Turbo Frames #1
Comments
This is an interesting idea, but how can you be sure that the target stream isn't part of the base page layout? |
In this case it would be limited to Frames not Streams. Since the framed content is already broken up into included partial templates I think it could only ever be either the base layout or no layout. This functionality is built into the Rails (original) version of Hotwire. Although I suppose this could be harder to pull off in Flask. In Rails the controller rendering the template is aware of what layout to use (something that can be obtained automatically) and can easily be optionally skipped. I think in Flask it would have to be configured at the extension level, but it might also not be possible to separate the layout using It may require a custom It would be nice to figure out how to solve tho because littering all of your templates with that if statement (or a macro) is a bit tedious. Also there's no way to solve the ETag header problem using this method alone. |
Yeah, I don't really understand how the rails optimization works, to be honest. A turbo frame can use a different turbo frame as a navigation target, so I can totally have a frame in my template that targets a frame in the base layout. The general optimization would be to render the entire page with layout and everything and then fish out the target frame (assuming you know which frame it is) maybe in an after_request handler. I don't see how you can do better than this if you want to cover all possible cases. The application, on the other side, could render just the intended frame if it knows what it is and the |
As far as I know it's to control the payload of the frame's HTML and the Rails code above does nothing more than not render the layout when that header is present. But yes, I'm not sure how it fishes out the specifics because it looks like it's only telling it to not load the layout and nothing else. |
If you have a turbo frame in the template that has a target set to some other turbo frame like maybe some section of a sidebar which happens to be defined in the layout, then how does it work? The rails code that you linked would break under such a case. As I said above, the correct optimization would be to render the whole thing, and then in an after_request handler trim anything that is unnecessary, like maybe any HTML that is not inside a turbo frame. I don't think you can fish out the one frame in a generic way, because you don't know which of all the frames is the one that is the target. I think as far as I'm willing to go is to provide a helper method similar to the |
I'm pretty sure if you need to alter a different area of the page, then Frames isn't the right Turbo feature to use. For that you would use Streams. The folks who created Hotwire and Turbo extracted these patterns out of building https://hey.com. That's what the Rails implementation is based upon. That use case of wanting to alter a different area of the page is covered in their screencast video (9:46 and onwards) at https://hotwire.dev/. |
It's a documented feature though: https://turbo.hotwire.dev/handbook/frames#targeting-navigation-into-or-out-of-a-frame. From that section: "Or it can drive another named frame by setting the target to the ID of that frame.". I coded this package according to the turbo.js feature set, not turbo-rails. I'm totally open to come up with optimizations, but not at the cost of breaking a documented feature. |
The Ruby on Rails implementation will remove the layout from responses that are determined to be frame responses by looking for the
Turbo-Frame
header in the request. This can drastically reduce the payload size for frame responses.That implementation in Ruby is here: https://github.com/hotwired/turbo-rails/blob/main/app/controllers/turbo/frames/frame_request.rb
I've been using Hotwire for a while now in Flask apps (since it launched), and have gotten around this by setting this in all of my templates:
But maybe there's a cleaner way to do it at the Flask level through an extension, especially if you want to factor in sending a different ETag value since technically the same URL can now serve different content (layout or no layout based on that header).
That's partly why I haven't created a Turbo extension for Flask, since technically with the above you don't need any type of Flask extension unless you plan to use streams.
The text was updated successfully, but these errors were encountered: