{% flush %} tag for progressive rendering of HTML?
stereosteve opened this issue · comments
Hello valyala -
Was interested in doing "progressive rendering" where the first part of a page is flushed before slower content is loaded and rendered. This is possible by decomposing page into chunks and rendering them in order, but requires that you split any existing templates / layouts in half.
It seems like it would be possible to add a {% flush %}
tag that would emit this in the middle of the template:
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
I was able to verify this works in practice by adding this code to a .qtpl.go
:
qw422016.N().S(`<h1>Before flush...</h1>`)
if f, ok := qw422016.W().(http.Flusher); ok {
f.Flush()
}
time.Sleep(5 * time.Second)
qw422016.N().S(`<h1>After flush...</h1>`)
I started to implement here but the use of http
in the middle of the emitted file would require that net/http
be imported at the top, and by that point the emitImportsUse
function has already run.
One option is to just require user to do {% import "net/http" %}
if they plan to use {% flush %}
. The hero project relies on goimports
to solve this problem.
If the import issue could be fixed, would you be interested in adding a tag like this?
After typing this out I realized this can be done by passing the ResponseWriter into the template and doing something like:
{% import "net/http" %}
...
{% code
if f, ok := page.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
%}
// slow code here
So... problem solved!