Tuesday, June 25, 2024
HomeRuby On RailsConditionally Allow GZIP on Heroku with Rack::Deflater: Cut back Response Measurement Considerably

Conditionally Allow GZIP on Heroku with Rack::Deflater: Cut back Response Measurement Considerably


When you got here right here after trying to find one thing like “rack deflater path situation” or “rack deflater if possibility,” right here is
your reply:

config.middleware.use(
  Rack::Deflater,
  :if => lambda do |env, _, _, _| 
    env["PATH_INFO"] == "/your/endpoint/path/right here" 
  finish
)

Simply insert this line in your utility.rb, and also you’re set. We might wrap up this put up right here, however… However everyone knows
that we must always not take a bit of random info from the Web as a right. It doesn’t matter what essentially the most superior,
AI-powered search engines like google on the planet might counsel, including non-toxic glue to pizza sauce is rarely a good selection.

Backstory

Let’s begin by explaining how we ended up with such a config. Just lately, we now have been engaged on efficiency enhancements
of the challenge’s most advanced (from the UI perspective) web page. Properly, principally, these are simply… two tables and a chart.
However these tables are massive, like very massive, as they often comprise a couple of thousand cells. It’s a number of HTML when “hotwired”😉😉.
You would say now that with JSON, it will be much less knowledge, however properly, I like how Hotwire works, and I completely
agree with this assertion from their handbook:

Sure, the HTML payload is perhaps a tad bigger than a comparable JSON, however with gzip, the distinction is often negligible,
and also you save all of the client-side effort it takes to fetch JSON and switch it into HTML.”

And that was truly what… didn’t occur in our case 😉. Sooner or later, we seen that downloading the response
took longer than ready for the server on my Web connection.

You may spot the large response measurement, the lacking Content material-Encoding header, and the obtain time right here. The consumer was
sending the Settle for-Encoding: gzip, deflate, br, zstd header, so we simply double-checked utilizing cURL. Use the --write-out
possibility with the size_download variable to see the obtain measurement.

The downloaded content material measurement was the identical for each requests (with and with out the Settle for-Encoding header).

This implies the server doesn’t assist compression by default. Because the challenge is hosted on a normal Heroku setup, there
is nothing like a reverse proxy there (with configured compression). In such a case, Heroku tells us to compress on the applying facet.

A small disclaimer right here is that for this challenge, the responses’ compression just isn’t wanted usually as we do precise
updates of web page parts. Compression after which decompression of such small items of content material would make no sense. It’s possible you’ll
need to see how we often work with Hotwire on this YouTube episode: Make your tables alive with turbo streams. Redirect vs Turbo Streaming. Which one to decide on?.

Furthermore, we even disabled “gzipping” for belongings (config.belongings.gzip = false) so the CDN might do it higher.
There’s already a put up about it right here: Don’t waste your time on belongings compilation on Heroku.

Reasoning behind going with Rack::Deflater

For this particular case and given timebox circumstances, we thought of enabling a Rack::Deflater conditionally an excellent possibility.
With this resolution we lowered the response measurement from ~5MB to ~100KB 😉. It was very satisfying consequence so we determined to present it a attempt.

We’ll in all probability stick with it so long as we don’t want compression for a lot of extra endpoints (which is uncertain,
given our means of working with Turbo Frames and Turbo Streams).

Meals for thought

In the long run, we might collect some metrics about response measurement and discover
some candy spot for which responses (above which measurement, for instance) we must always compress. Then we might transfer the compression
half to the revere proxy (like nginx) utilizing, for instance, the heroku-buildpack-nginx.
Because of that, the app itself wouldn’t must spend sources on compression, and that will be executed by a specialised
software that helps not solely GZIP but additionally Brotli, for instance.



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments