8 ms·
Streaming HTML out of order without JavaScript
- djxfade 3y agoThis looks very interesting, I was not aware that this was possible natively without JS. What's the browser support like?
- MindSwipe 3y agoSeems like browser support is pretty universal, even says so in the article > All browsers support streaming HTML And the caniuse is promising: https://caniuse.com/?search=slot https://caniuse.com/?search=slot
- csande17 3y ago<slot> has been around for a while in Web Components; the relevant feature here is probably the (much newer) shadowrootmode attribute: https://caniuse.com/?search=shadowrootmode https://caniuse.com/?search=shadowrootmode But you can already do a lot with regular streaming and using CSS Grid, inline <script> tags, etc to move stuff around the page.
- mikedelfino 3y agoChrome, Edge and Safari since March 2023; Firefox since February 2024. https://caniuse.com/mdn-html_elements_template_shadowrootmode https://caniuse.com/mdn-html_elements_template_shadowrootmod...
- trollied 3y ago[flagged]
- boxed 3y agoThere are things that are slow that can't be made to be fast. And there are even more that CAN be made fast but only at extreme cost.
- anonymoushn 3y agoLet's come back to this once we've stopped writing software that is 90-99.9% waste (in round trips and in cycles).
- boxed 3y agoI hear people complain about this a lot. But people who write software that is that efficient are 90-99% wasting their precious time on Earth.
- anonymoushn 3y agoMy bad, I finally realized it's better to spend much more time as long as it belongs to other people.
- boxed 3y agoIf you go bankrupt before you even get to market, then you aren't wasting any CPU time of anyone else :P
- quickthrower2 3y agoThe downside here is the need to proxy everything through the same server. That will add latency and possibly throttle bandwidth if that data is coming from third parties. The scenario where this could be good is something where there are background jobs running behind the service that would have been API-ed through the same web server anyway. But I have an ingenious solution for the best of both worlds! An Iframe.
- mg 3y agoAt the core, this seems to be about shadowrootmode=open, a new html feature which already landed in Chromium and Safari: <div> <template shadowrootmode=open> This is <slot name=a></slot> and <slot name=b> </template> <span slot=b>sunny</span> <span slot=a>funny</span> </div> renders as: This is funny and sunny So it looks like HTML got a bit of a native template system now. What I have been wanting for decades is a native template system in HTML which supports urls. Similar the the script tag, but which loads html: <html url="/header.html"> <html url="/content.html"> <html url="/footer.html"> I always wondered why this was never implemented. It seems such a basic functionality which would allow to comfortably build websites in a modular way without scripts or serverside processing.
- robin_reala 3y agoWhile it needs a little JS to initialise, that’s easy enough to do with custom elements: https://github.com/gustafnk/h-include https://github.com/gustafnk/h-include
- reddalo 3y agoIt reminds me of FrontPage extensions, "good" times...
- hiimshort 3y agoThe last example reminds me of the once-proposed html imports feature. It was being pushed by Google back when Polymer was a thing and would've given us actual web components delivered as html documents with full support for html, css, and js just like we use normally. If I remember correctly there were a few issues with the approach that needed to be resolved and nobody stepped up to make it a reality. So instead we got the custom elements spec years later which only implemented a small percentage of what made html imports useful.
- troupo 3y agoIn the end it was only Firefox who implemented HTML Imports, and Google has gone mad and pushed everything in to Javascript.
- deleted 3y ago[deleted]
- alexey2020 3y agoThat's cool and definitely the future of HTML streaming, it simplifies things a lot: js enabled out-of-order streaming leads to SEO problems and frameworks usually need to come up with workarounds - detect bots and turn of streaming for that case. With such technique no workaround is needed, less things to worry about. Excellent!
- quickthrower2 3y agoThis might lead to SEO problems as you wont know what the SE will see rendered i it’s text only view.
- gtroja 3y ago[flagged]
- boxed 3y ago[flagged]
- iolo 3y ago> It's worth noting though that there's no dependency on a JavaScript backend - the same thing can be achieved on PHP, Java, Go, etc. The only Javascript in the article is on the server side to handle the HTTP.
- gtroja 3y agoJavascript is being used to stream the HTML. the title is "Streaming HTML out of order without JavaScript"
- ghusbands 3y agoThe Javascript code in the article is server-side and not essential - it's just one way to take advantage of open shadowrootnodes and it could be written in PHP or anything else. It's showing how you can output your HTML in a very different order, with arbitrary delays, and still get the page layout you expect.
- quickthrower2 3y agoYou could possibly do this using a flexbox? https://developer.mozilla.org/en-US/docs/Web/CSS/order https://developer.mozilla.org/en-US/docs/Web/CSS/order
- felixfbecker 3y agoFlexbox order doesn't affect accessibility tree order, so that's bad for accessibility. DOM order should make semantic sense.
- ricardobeat 3y agoManaged tabindex would solve that. Sounds like a nightmare to maintain though.
- felixfbecker 3y agotabindex only affects tab order (of interactive elements), not the order that a screen reader navigates and reads out content (including non-interactive elements)
- megaman821 3y agoThere is a new reading order attribute coming to fix this.
- Lorin 3y agoWhy wouldn't they just amend the existing feature so it's accessible?
- _heimdall 3y agoBackwards compatibility I'd assume. Someone could have taken advantage of the fact they flex order and accessibility order are different. Changing the functionality now would break those sites, adding a new CSS prop would make the fix opt-in.
- Alifatisk 3y agoThe site loads pretty slowly for me [1], and when they site has fully loaded the list has already been completed, there is no streaming from what I can see. Is Firefox the reason here? 1. https://check-host.net/check-report/16234f41keed https://check-host.net/check-report/16234f41keed
- luke-stanley 3y agoIt worked fine for me in Firefox.
- exchemist 3y agoAlso for me, both on Firefox and Edge - I'm wondering if it's to do with being behind a corporate proxy that MITMs everything and might be buffering rather than passing through partial respones, or has a much higher threshold before streaming? If that is the reason, it'll provide an (even more than usually) poor experience for those behind such a proxy
- bmacho 3y agoThe site[0] works for me in Edge, and Firefox, as intended. The slow loading is the point, you should see how it updates real time, which doesn't happen to you for some reason. As other comment suggests, maybe something on your network doesn't like tiny (~42 characters) HTML fragments. [0] : https://ooo.lamplightdev.workers.dev/ https://ooo.lamplightdev.workers.dev/
- netghost 3y agoFirefox just added support for declarative shadow dom, so that might be it if you're not on the latest version. Alternatively I could imagine some kind of proxy between you and the site buffering things up.
- Alifatisk 3y ago> some kind of proxy between you and the site buffering things up. Yeah I think that might be it, because it works fine on FF (iOS) outside.
- myfonj 3y agoReal fun begins when you realize that the streamed content can react to interactions that user submits from the streamed page: form targetted into hidden iframe or any other mean of issuing HTTP request back to the server and handling data it can react to in next streamed chunk. This way you can have for example "CSS only chat" [1], or basically anything, since the chunk with new data can contain style directives hiding the old data… [1] https://github.com/kkuchta/css-only-chat https://github.com/kkuchta/css-only-chat
- danielvaughn 3y agoNeat, but what would be the intended use case for something like this? I can imagine a scenario where one part of the UI may take extra time to load, so you would defer it to let the other parts load first. Is there another reason I'd want this?
- kevincox 3y agoI used similar streaming HTML for my RSS reader. When you import subscriptions it can take a while as each feed is fetched so I use streaming HTML to show the progress of each feed as it is imported. This provides meaningful progress updates to the user. However previously the limitation was that the content needed to be more or less in order (you could use some CSS tricks but they were limited). Using this trick I would be able to render the full list of pending feeds then insert a result as each finishes being fetched. In fact it seems that for each slot the last element will be used. So you can even create live-updating pages based on this which is really cool. For example imaging you had a score ticker. You could push an update to that region of the page every time the score changes. I think this is definitely a niche use case, but it is very nice to support this without JS. Of course in all but the simplest use cases JS may still be the right solution. For example if the connection drops for any reason there is no mechanism for showing the user an error, let alone retrying.
- crooked-v 3y agoDealing with loading in a smart way (even small amounts of loading), without extra JS overhead, is the fundamental use case. For a comparison, basically the entire bajillions of man-hours that have gone into React Server Components [1], and all the many, many complications and footguns inherent in their approach, is trying to solve the same problem. [1]: https://nextjs.org/docs/app/building-your-application/rendering/server-components https://nextjs.org/docs/app/building-your-application/render...
- k33n 3y agoThe big application for this is multicasting html via UDP. P2P web apps could leverage this.
- politelemon 3y agoThis helped me with a 'visual' understanding of what's happening, go to view-source:https://ooo.lamplightdev.workers.dev/ https://ooo.lamplightdev.workers.dev/ then watch the bottom of the page as the new `<span slot=...>` elements come in. As they come in, the browser's, well, slotting the contents into the corresponding slot in the template.
- commonenemy 3y agoThis brings the memory of BigPipe, facebook has had this years ago (using JS of course).
- msoad 3y agoLet's say I streamed the first chunk with a little JavaScript, would that JavaScript be able to listen to future chunks coming in? In a real application it is crucial to be able to update your frontend state once new data is ready. First thought is [mutation observer](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver https://developer.mozilla.org/en-US/docs/Web/API/MutationObs...) but that seems too deep into the weeds
- AirMax98 3y agoI'd assume that the only reason one would need to know if chunks were incoming is to indicate a loading state in disparate parts of your webpage, e.g. chunk B has some widget that indicates chunk A is loading. In this case, you can probably work off the assumption that loading is the default initialization state, and use JS to communicate to the disparate parts of your page once on chunk A load. There may be something different that you're thinking about here though.
- eyelidlessness 3y agoAnother approach would be to correlate observation with specific custom elements. You can define them in the first chunk, then use their connectedCallback method to observe them as they arrive. The benefit of an approach like this is that the custom element lifecycle APIs are synchronous (which is also the drawback of the approach, and where MutationObserver is more appropriate if that synchrony is a concern).
- andipodean 3y agoPerhaps the most horrible JavaScript I ever wrote did something like this, and has been very useful for over a decade and still going strong. It's a log file that starts with a header: just a script tag with some JS, followed by a special string (I used a special HTML comment as a boundary indicator). The server then appends its logging to this file in a web hosted directory. The JS periodically does an XHR of it's own location.href, polling itself. It then splits on the special boundary string, thus collecting the latest log data, parses it to generate pretty/coloured/linked HTML, and updates the current page according (and controls scrolling if required). This gives you a log file that's continuously being appended to, but can be visited in the browser using any static file serving and automatically updates as it's populated.
- h43z 3y agoIf I add multiple slots with the same name it shows all of them. <div id=t> <template shadowrootmode=open> <slot name="s1">s1</slot> <slot name="s2">s2</slot> <slot name="s3">s3</slot> </template> </div> <script> setTimeout(_=> t.innerHTML += `<span slot="s3">three</sp>`, 1000) setTimeout(_=> t.innerHTML += `<span slot="s1">one</sp>`, 2000) setTimeout(_=> t.innerHTML += `<span slot="s2">two</sp>`, 3000) setTimeout(_=> t.innerHTML += `<span slot="s1">ONE!!</sp>`, 4000) </script> I guess there is no way to replace a slot, again and again?
- niutech 3y agoYou can hide the previous slot contents with CSS: https://jsbin.com/rinevokiwi/edit?html,output https://jsbin.com/rinevokiwi/edit?html,output
- heh89898000 3y agoVery cool. Perhaps this could be used for non-JS CAPTCHAs, since it would force the bot to wait for a few seconds.
- davepeck 3y agoFun stuff! The underlying `swtl` library is itself pretty interesting. Note the use of `delayed(...)` in the blog's example code: a promise in a tagged template. SWTL's `html` allows for this (I think the blog's example follows the simple case here https://github.com/thepassle/swtl/blob/main/html.js#L23 https://github.com/thepassle/swtl/blob/main/html.js#L23). And SWTL's `render` method races the promises (https://github.com/thepassle/swtl/blob/main/render.js#L120 https://github.com/thepassle/swtl/blob/main/render.js#L120) outward.
- egberts1 3y agoThis is a long overdue but promising trend toward a JavaScript-less website. Yeah, I am one of the few outliers who still host JS-free out of cybersecurity reasons.
- niutech 3y agoThis technique of out-of-order streaming using DSD was shown for the first time by lamplightdev on Jun 28, 2022: https://twitter.com/wcbytes/status/1541546418539732997 https://twitter.com/wcbytes/status/1541546418539732997 Demo: https://enamel.pages.dev https://enamel.pages.dev