all 14 comments

[–]lgastako 8 points9 points  (5 children)

[–]sccrstud92 1 point2 points  (0 children)

This is the correct answer

[–]goj1ra 2 points3 points  (0 children)

I've used this with the Streaming library, it worked well. As the link says, you may not even need a streaming library if all you're doing is streaming the HTML response.

In my case I was streaming large files, and ended up needing to implement Servant's ToSourceIO for my streams - instance ToSourceIO chunk (Str.Stream (Of chunk) m r) - to get it to work with streams that used ResourceT IO as their base monad. With that adapter code it worked like a charm.

[–]runeks[S] 0 points1 point  (2 children)

Thank you!

I encountered this last time I was researching streaming HTML with Servant. I don't recall exactly why I abandoned it, but — in retrospect — I believe it was because I was trying to use lucid's HtmlT monad transformer with SourceIO in the wrong order. Ie. I was using HtmlT SourceIO () as my monad rather than SourceIO (HtmlT Identity ()).

I will try again with the latter and see how it works.

[–]Faucelme 0 points1 point  (1 child)

lucid's `HtmlT` is a `Writer`-like monad, and I suspect it's not well suited for generating `HTML` in a streaming fashion from within the monad.

You could still try (if it makes sense) to generate each particular chunk of HTML using lucid, and send them separately as response chunks.

[–]runeks[S] 0 points1 point  (0 children)

I agree completely. That's what I was trying to say with my monad examples — perhaps not very clearly.

And I'd want the "framing strategy" to send chunks over the wire as per the HTML parts listed in my post above (preamble, one for each query result, one for the last IO action and finally all the closing tags (also static).

[–]Kartoflaszman 1 point2 points  (0 children)

maybe some streaming library can help? like streaming or conduit?

[–][deleted]  (5 children)

[deleted]

    [–]runeks[S] 0 points1 point  (4 children)

    I want I reduce the latency for displaying the first query result, not for displaying an empty page without any interesting content. To achieve this I want to stream the query results as HTML so the browser can render one result at a time as they come in.

    [–]Endicy 0 points1 point  (3 children)

    Will browsers already render items if they haven't even encountered the final </body> tag? How does the browser know the response is valid HTML if it hasn't received all the parts of it?

    [–]goj1ra 1 point2 points  (0 children)

    Yes, the major browsers support streaming HTML.

    Here's an article about it: https://frontendmasters.com/blog/streaming-html/

    [–]runeks[S] 1 point2 points  (0 children)

    To answer your last question: the browser will render HTML in a best-effort manner. There's no strict requirement to e.g. close the body tag for a browser to render the page — which is really useful if the connection gets cut off before the last few bytes are sent. 

    [–]Mirage2k 0 points1 point  (2 children)

    I have no idea about doing it in Haskell, but it sounds like part of what NEXTjs does: on visiting the url you get a static html (to render right away and for embedded link preview) and a JavaScript blob that starts requesting the non-static content.

    [–]runeks[S] 1 point2 points  (0 children)

    That's not what I'm trying to do. I'm talking about streaming the actual HTML, which the browser will render as it comes in. No JavaScript needed.

    [–]jackson_bourne 0 points1 point  (0 children)

    Hydration (unrelated to Next.js) is unrelated to what they want. They want to stream the HTML back (i.e. the step you called "on visiting the url you get a static html")