How to minify HTML output in Django
So, you want to compress the size of the HTML that Django generates? Here is the Django way to do it.
In order to do this, you’ll have to write a middleware for your application.
So, create a file called middleware.py (for this example, but you can name it whatever you want) inside your Django app folder (let’s call the app MyTestApp). Copy the following code inside it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import re from django.utils.html import strip_spaces_between_tags from django.conf import settings RE_MULTISPACE = re.compile(r"\s{2,}") RE_NEWLINE = re.compile(r"\n") class MinifyHTMLMiddleware(object): def process_response(self, request, response): if 'text/html' in response['Content-Type'] and settings.COMPRESS_HTML: response.content = strip_spaces_between_tags(response.content.strip()) response.content = RE_MULTISPACE.sub(" ", response.content) response.content = RE_NEWLINE.sub("", response.content) return response |
What this does is: first, it removes all the spaces between tags. The problem is that it will remove the space only if between the tags there will be ONLY spaces. But sometimes you have cases like this:
1 | <div> .....</div> Some text <div> .....</div> |
In this case, the space between the two divs will not be compressed because of the “Some text” string, but nevertheless, the spaces will be rendered as only one. To solve this, the
next thing it does is replace multiple appearances of spaces with only one space. Finally, it will remove all the new lines from the html, because they are anyway ignored by the browsers.
After adding the above code to middleware.py, add the following line to MIDDLEWARE_CLASSES in your settings file:
1 | 'MyTestApp.middleware.MinifyHTMLMiddleware' |
Replace MyTestApp with the name of you app and middleware with the name that you gave to the middleware.py file (if you did gave it another name).
Hope this helps!
UPDATE
You also have to add in your settings COMPRESS_HTML and set it to True, if you want to compress the html, or False otherwise.
1 | COMPRESS_HTML = True |

You forgot to mention the COMPRESS_HTML setting.
Ahh, yeah. Thank you! I’ll update the post.
This is simple and very useful! Thanks!
I suggest you replace newlines with a space and reverse the multispace and newline regexps. This will eliminate the problem you get with links separated from text with newlines. This should not render as foobar:
foo
bar
I suggest you replace newlines with a space and reverse the multispace and newline regexps. This will eliminate the problem you get with links separated from text with newlines. This should not render as foobar:
<a>foo</a>
bar
Additionally you should use getattr(settings, ‘COMPRESS_HTML’, False) to get the setting so that apps do not start crashing when you introduce this middleware.
Thanks for the pointers. I’ll update the post as soon as posible
It is bad to have a processor to minify html in middleware. It will slow down your site. You need preprocessor to minify html and i’m looking for that solution.
Yeah indeed it’s bad idea to do it in middleware.
Try out my template loader, it does not minify CSS and JS but it really simple for HTML
https://github.com/iRynek/django-template-minifier
Neat idea. I’ll give it a try