In this tutorial, you will learn how to compress and optimize your static files i.e., javascript (.js) and CSS (.css) files for production. You will work with django-compressor to compress CSS and JS and django-htmlmin to minify HTML files. You can refer to the source code of this project here.
Django Compressor is a python package for the Django web framework to compress and minify CSS and JS files using {% load compress %}
tag.
%[https://youtu.be/WUjMH-qDXoo]
Let's start with installing the dependencies.
Install Dependencies
To optimize static files, you need to install the following dependencies. First, let's install memcached
for caching static files. It's optional but it will speed up your static files serving, so totally worth it. Try it
# Install Memcache
sudo apt-get install Memcached # Ubuntu
brew install memcached # Mac
# Start memcache
sudo service memcached start # Ubuntu
brew services start memcached # Mac
Now install the required PIP packages
If using virtual environment, activate it using
source venv/bin/activate
before installing pip packages. You can learn more about virtual environment here.
pip install python-memcached
pip install django-compressor
pip install django-htmlmin
Default settings for Django compressor
Open up your settings.py
file and make these changes
Configure Memcached
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
Memcached runs through localhost port 11211
by default, so there’s no further configuration here.
[Optional]: There are other options to have a dedicated Memcached server or have Memcached store files locally. Django documentation has more information on how to set that up.
Add compressor to your installed apps
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'compressor',
]
Add middlewares
MIDDLEWARE = [
'django.middleware.gzip.GZipMiddleware', #This one
'htmlmin.middleware.HtmlMinifyMiddleware', #This one
'htmlmin.middleware.MarkRequestMiddleware', #This one
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Configure static files settings
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
STATIC_ROOT = os.path.join(BASE_DIR,"static_root")
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# Add this
'compressor.finders.CompressorFinder',
)
Add compressor and minified settings
COMPRESS_ENABLED = True
COMPRESS_CSS_HASHING_METHOD = 'content'
COMPRESS_FILTERS = {
'css':[
'compressor.filters.css_default.CssAbsoluteFilter',
'compressor.filters.cssmin.rCSSMinFilter',
],
'js':[
'compressor.filters.jsmin.JSMinFilter',
]
}
HTML_MINIFY = True
KEEP_COMMENTS_ON_MINIFYING = True
Compressing files with an example
To compress CSS and JS, load the compress
tag just like you load static
tag
{% load static %}
{% load compress %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
{% compress css %}
<link rel="stylesheet" href="{% static 'style.css' %}">
{% endcompress %}
{% compress js %}
<script src="{% static 'script.js' %}"></script>
{% endcompress %}
</head>
<body>
<center>
<h1>Raturi.in</h1>
<h1 class="heading">Hello Lets compress</h1>
<p class="para">I am just a para</p>
<button onclick="change_colors()">Change colors</button>
</center>
</body>
</html>
Compressed files will look something like this
# CSS
<link rel="stylesheet" href="/static/CACHE/css/output.f7c661b7a124.css" type="text/css" charset="utf-8">
# JS
<script src="/static/CACHE/css/output.f7c661b7a124.css" type="text/css" charset="utf-8"></script>
# Run your server and you can check your source code to verify it.
Run the command below to compress in the given sequence
python manage.py collectstatic
python manage.py compress --force
python manage.py runserver
Now if you check your source code, you will see that your files are compressed.
For production, in your settings.py
set COMPRESS_ENABLED
like below
COMPRESS_ENABLED = not DEBUG
Django compressor Usage
Django Compressor can be used by loading a compress
tag and then enclosing the HTML, CSS files inside the compress
tags.
Syntax of Django compressor:
{% load compress %}
{% compress <js/css> [<file/inline/preload> [block_name]] %}
<html of inline or linked JS/CSS>
{% endcompress %}
Let's see some examples
Compressing CSS and JS file
{% compress css %}
<link rel="stylesheet" href="{% static 'css/style.css' %}" type="text/css" charset="utf-8">
<style type="text/css">p { border:15px solid blue;}</style>
<link rel="stylesheet" href="/static/css/two.css" type="text/css" charset="utf-8">
{% endcompress %}
{% compress js %}
<script defer type="text/javascript" src="{% static 'custom/js/lozad.min.js' %}"></script>
<script>
function loadAdsenseScript(url) {
let script = document.createElement('script');
script.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
script.defer = true;
script['data-ad-client'] = "ca-XXX";
document.head.appendChild(script);
}
</script>
{% endcompress %}
Output
<link rel="stylesheet" href="/static/CACHE/css/output.f7c661b7a124.css" type="text/css" charset="utf-8">
<script type="text/javascript" src="/static/CACHE/js/base.3f33b9146e12.js" charset="utf-8"></script>
You can add inline
parameter if you want content directly rendered to the page instead of a separate file
{% compress js inline %}
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-asdww');
</script>
{% endcompress %}
You can also add preload
parameter to generate the preload tag for the compressed file in the template
{% compress js preload %}
<script>
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark')
}
</script>
{% endcompress %}
Output:
<link rel="preload" href="/static/CACHE/js/d014sdf14fc6.js" as="style" />
That's all for a setup of the Django compressor. You can check the source code of this project here.
You can also check out more django-tutorials.