Hotwire - Turbo Frame
Why
Turbo Drive is a drop-in replacement that enables speeding up navigation.
Turbo Frame allows predefined parts of a page to be updated on request. Any links and forms inside a frame are captured, and the frame contents automatically updated after receiving a response.
Frames are created by wrapping a segment of the page in a <turbo-frame> element. Each element must have a unique ID, which is used to match the content being replaced when requesting new pages from the server. A single page can have multiple frames, each establishing their own context.
In most cases, requests that originate from a <turbo-frame> are expected to fetch content for that frame (or for another part of the page, depending on the use of the target or data-turbo-frame attributes). This means the response should always contain the expected <turbo-frame> element. If a response is missing the <turbo-frame> element that Turbo expects, it’s considered an error; when it happens Turbo will write an informational message into the frame, and throw an exception.
What
When
A major contributor of the turbo framework said that developers should always try frame first, then seek stream if the former one does not resolve the problem. I think one of good thing for Turbo Frame is that it require little the code amount for a new codebase and little effort for an existing one.
How
Turbo Frame
-
By default
Turbo Frameis eager-loading. But it can be lazy-loading by setting attributeloading: "lazy". This means it won’t loading fromsrcuntil the frame element is visible. But be noticed, the frame element will never load if you put it at the end of page since it’s never visible. -
It blows my mind how to use
lazy-loadingframe to accomplishscroll-to-bottom-to-load-moreeffect. No javascript at all! One caveat is that you need to embed thenext-page frameintocurrent-page frame. So in the end you’ll find many nested frames. (70) Ruby on Rails #68 Frames: Infinite Scroll Pagination - YouTube
Turbo Stream
-
I just wonder the
template.turbo_stream.erbstuff only works forstream, or it works forframeas well. It seems the client-side turbo javascript framework only addstext/vnd.turbo-stream.htmltoACCEPTheaders for a non-GET request. -
Another cool technique is we usually
REDIRECTfor aDOrequest (eg:POST/PUT/PATH) whileSHOWsomething forGETrequest. Those are common patterns. But withturbo_stream, we can performDO-SHOWrather thanDO-REDIRECT. This is done by create a corresponding template in views, like if you want to update the view item when you update a record, just create filecreate.turbo_stream.html.erbin the views folder, specifyingturbo_streamaction there. No need to explicitlyrespond_to, rails will automatically find that template and render. -
Turbo Streamdoes not work withGETmethod. Not sure why, but with browser inspector, we can see that turbo has taken over all http calls. (Click any link or button then go to browser inspector -> network -> select a request -> check theinitiatorpanel. Someturbo.es2017-esm.jsjavascript framework make the actual http call). Turbo addstext/vnd.turbo-stream.htmltoAcceptof request header, along with other default content-type (text/html, application/xhtml+xml) fornon-Getrequests. ForGetrequests,Acceptis not modified. -
Seems the content-type in
Acceptof request header is served by order. ie, fortext/vnd.turbo-stream.html, text/html, application/xhtml+xml,text/vnd.turbo-stream.htmlis served as response from format collector ofrespond_toblock. Maybe this is another rails convention. -
Turbo streamallows you to send more than one actions (against different targets) in one response. From backend you can do it in therender turbo_streammethod or put them in the?.turbo_stream.erbtemplate. Quite flexible.