Stripping whitespace from your Django HTML

Darryl Buswell - Dec 28, 2020

At some point in your Django project, you will likely consider options for client side performance optimizations.

At some point in your Django project, you will likely consider options for client side performance optimizations. Minifying HTML is a low hanging fruit here, which simply involves stripping the white space from your HTML code so that you reduce the amount of needless data sent to those visiting your web page.

And with Django being the framework it is, with such a strong open source community, there are a number of packages available which provide code minification. One such example for minifying HTML code is the django-htmlmin package, which is fairly lightweight and should have you up and running quickly. And then there's django-pipeline which is more fully-fledged package, including handlers and compressors for CSS and js alongside HTML minification.

But if your like us, you'll always tend to gravitate towards implementing your own solution rather than including yet another package in your list of app requirements. Particularly for something as simple as stripping white space from served HTML content. So instead, we pulled the code specific to HTML minification from the django-pipeline repository and created our own minification middleware. The code is pretty straight forward, which you can find below.


from django.conf import settings
from django.core.exceptions import MiddlewareNotUsed
from django.utils.encoding import DjangoUnicodeDecodeError
from django.utils.html import strip_spaces_between_tags as minify_html

class HTMLMinifyMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

        if not settings.HTML_MINIFY_ENABLED:
            raise MiddlewareNotUsed

    def __call__(self, request):
        response = self.get_response(request)

        if response.has_header('Content-Type') and 'text/html' in response['Content-Type']:

            try:
                response.content = minify_html(response.content.decode('utf-8').strip())
                response['Content-Length'] = str(len(response.content))

            except DjangoUnicodeDecodeError:
                pass

        return response

If your interested in such a solution. Simply drop the above code into a module, perhaps within your core application. Then, register the middleware in your Django config file. For example, if you want to locate the middleware in an application named 'core', within a module named 'middleware', you would simply insert the below.


MIDDLEWARE = [
    'apps.core.middleware.HTMLMinifyMiddleware',
    ...
]

Note that in the code above, we are also making use of an environment variable 'HTML_MINIFY_ENABLED' to specify whether we do or do not want to minify our HTML code. This is helpful for handling development versus production environments, but it is dependant on having set up your project to handle parsing environment variables. If that's not the case, then you should look to drop any references to 'settings.HTML_MINIFY_ENABLED' as appropriate.

And that's it. Whitespace stripped from your served HTML content via one block of code.



Share this post: