How to gzip my site?

I was trying to increase performance of my site then i came across the gzip encoding. Fairly i am new to that. I looked up on the internet and most of them are describing on IIS, ngnix, Apache etc.

How can i achieve that on Sanic?

Thank you in advance :heart:

I can post a more Sanic specific approach later, but you should be able to get there by doing something similar to this:

Thanks a lot for guiding me :heart:. Looking forward for the Sanic version of it.

Either way i got at least some idea how to do it :+1:

Instead of Gzip you might wish to use Brotli because it compresses better, faster. In any case, if you are compressing on fly (rather than precompressing your static files) and don’t have super slow network, use one of the lower compression levels to avoid making your CPU the bottle neck, as it might be with both Brotli and Gzip using the default level.

https://blogs.akamai.com/2016/02/understanding-brotlis-potential.html

It would be nice to have a Sanic extension (response middleware) for this but it is also possible to do it on your proxy:

Sorry for the delay. As you can see, it looks very similar.

import gzip
from functools import wraps
from io import BytesIO as IO

from sanic import Sanic, html

app = Sanic(__name__)


def gzipit(handler):
    def decorator(f):
        @wraps(f)
        async def decorated_function(request, *args, **kwargs):
            accept_encoding = request.headers.get("Accept-Encoding", "")
            response = await f(request, *args, **kwargs)

            if ("gzip" not in accept_encoding.lower()) or (
                response.status < 200 or response.status >= 300 or "Content-Encoding" in response.headers
            ):
                return response
            gzip_buffer = IO()
            gzip_file = gzip.GzipFile(mode="wb", fileobj=gzip_buffer)
            gzip_file.write(response.body)
            gzip_file.close()

            response.body = gzip_buffer.getvalue()
            response.headers["Content-Encoding"] = "gzip"
            response.headers["Vary"] = "Accept-Encoding"
            response.headers["Content-Length"] = len(response.body)

            return response

        return decorated_function

    return decorator(handler)


@app.get("/")
@gzipit
async def handler(request):
    return html(
        """
<html>
<h1>Hello, world.</h1>
</html>
"""
    )
1 Like

Thank you @ahopkins @Tronic for insights.

As for @Tronic 's reply, I can pre-compress the site as there is no dynamic content. I would definitely love to use Brotli.

@ahopkins, thank you for sharing the code.

You guys really helped me.

1 Like