Post-process response prior to send_resp in render

I’m wondering how if at all it’s possible to post-process (rewrite body) response from render/3… The use case is to minify html. Of course the best option would be to use something that exists. Apart from practicality and this very use case, either I’m missing something… or there is no mechanism like post-plug or render callbacks?

You can register a ‘post’ hook in a plug, that might be able to do it? I’m unsure if it runs before or after sending though.

And you can always just process it via the View modules too. :slight_smile:

Honestly though I’m unsure how worth it, it would be. Maybe minimize the templates only (at compilation time)? That might be a useful Phoenix feature…

As far as I know, response can be send_resp-ed once and in that flow it is within render function. If I plug “after” I get an error (response already sent).

View modules call render/3 and that does send_resp/3… No way of wrapping that. Minification might be as simple as removing new lines, comments and unnecessary spaces… Minifying templates at compilation time seems more complex (generating/keeping intermediary files), but likely more efficient.

View modules call render/3 and that does send_resp/3…

It’s the other way around, I think. render from controller calls render from views to populate conn’s body and then send_resp with that body.

1 Like

Right and I mistook “view modules” as contollers. Now, I am not sure how to post-proces in View as have not yet needed it… Will read the docs… :slight_smile:

there is also this plug - though its kinda old so unsure if it still works - ymmv.

I would also prefer/recommend minifying at compile time… imagine you could do it in some pre compile step with edeliver - but not 100% sure…

2 Likes

You might be able to do this with custom cowboy handler middleware by passing extra options into plug for your cowboy adapter. Untested but if I play with this approach later I’ll report back!

Thanks. It does the job. This is basically a combination of:

  • Plug.Conn.register_before_send
  • rebind body with the result of minify function
  • %Plug.Conn{conn | resp_body: body}

Of course it’s dynamic… I will see how much overhead it adds.

Have tried that (Floki.raw_html). Also needed to add “\n” removal. Bechmarks on a lenghty page show it’s 2-3 ms more vs no minify. No that bad. One con: JS is not really minified just newlines are stripped there.