Optimizing Static Content in Django

Optimizing Static Content in Django

In any web project whether it is a static or a dynamic one of the main headache for developers is to compress static files and serve them without affecting the page load time. There are compressors like YUIcompressor, Yuglify and many.

Today backend languages like Python, nodejs, Ruby etc.. provide frameworks or packages to make this compression happen. We have Grunt and Glup task runners from nodejs, Sprocket and Juicer from Ruby for compression. For more check this link

In Django, there are tools for compression and minification of your static code.

Let's know about them and build an app using them.

1. Django Compressor

2. Webassets

Django Compressor:

The main use of Django Compressor is to compress linked and inline JavaScript and CSS into a single cached file.

Let's use this one to build our app.

step 1:

Install Django Compressor

$ pip install django-compressor

Its will download and install dependence, if you have YUI Compressor or yUglify compressor, or else install cssmin and jsmin.

$ pip install cssmin && pip install jsmin

step 2:

Add 'compressor' to your INSTALLED_APPS setting:

INSTALLED_APPS = (
        # other apps
        "compressor",
)

add 'compressor.finders.CompressorFinder' to your STATICFILES_FINDERS

STATICFILES_FINDERS = (
        # other finders..
        'compressor.finders.CompressorFinder',
)

In settings.py file enable COMPRESS_ENABLED, it is better keep it at the end of the file. If it is not enabled it will render the input files without any compression.

COMPRESS_ENABLED = True

Also add COMPRESS_CSS_FILTERS and COMPRESS_JS_FILTERS to settings.py

COMPRESS_CSS_FILTERS = ["compressor.filters.cssmin.CSSMinFilter"]
COMPRESS_JS_FILTERS = ["compressor.filters.jsmin.JSMinFilter"]

altogether,

if not COMPRESS_ENABLED:
       COMPRESS_ENABLED = True
       COMPRESS_CSS_FILTERS = ["compressor.filters.cssmin.CSSMinFilter"]
       COMPRESS_JS_FILTERS = ["compressor.filters.jsmin.JSMinFilter"]

if you want to use YUglify, you need to install YUglify first

if npm is present

$ sudo npm install -g yuglify

if npm is not present

$ sudo apt-get install npm && sudo npm install -g yuglify

and add

COMPRESS_CSS_FILTERS = ["compressor.filters.yuglify.YUglifyCSSFilter"]
COMPRESS_JS_FILTERS = ["compressor.filters.yuglify.YUglifyJSFilter"]

step 3:

In your templates, use

{% load static compress %}
{% compress css %}
        <link rel="stylesheet" href="{% static "css/base.css" %}">
        <link rel="stylesheet" href="{% static "css/style.css" %}">
{% endcompress %}
{% compress js %}
        <script type="text/javascript" src="{% static "js/main.js"%}"></script>
{% endcompress %}

For more information on this package check the documentation. Check example for this app here

Webassets:

Webassets supports multiple python frameworks, for Django the supported version is django-assets. It is simpler than djang-compressor.

Let build another app:

Step 1:

Install Django Assets

$ pip install django-assets

step 2:

Add 'django-assets' to your INSTALLED_APPS setting:

INSTALLED_APPS = (
        # other apps
        "django-assets",
)

add 'django_assets.finders.AssetsFinder' to your STATICFILES_FINDERS

STATICFILES_FINDERS = (
        # other finders..
        'django_assets.finders.AssetsFinder',
)

step 3:

For Assets to render we need to include assets.py in the project folder, when the application starts django-assets will automatically pick the assets.py file for rendering. In the file, we have to include your assets path of JS and CSS.

from django_assets import Bundle, register
       js = Bundle('js/main.js', filters='jsmin', output='gen/packed.js')
       register('js_all', js)
       css = Bundle('css/base.css', 'css/style/style.css', filters='cssmin', output='gen/packed.css')
       register('css_all', css)

or we can add assets.py file to application by specifying an ASSETS_MODULES variable in settings.py

ASSETS_MODULES = [
       'module.assets'
]  

it supports various filter for that check the documentation

or there is another best way, directly we can configure and include in templates

{% load static assets %}
{% assets filters='cssmin', output='gen/packed.%(version)s.css', 'css/base.css', 'css/style/style.css' %}
        <link rel="stylesheet" type="text/css" href="{{ ASSET_URL }}">
{% endassets %}
{% assets filters='jsmin', output='gen/packed.%(version)s.js', 'js/main.js' %}
        <script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}

The '%(version)s' is used for Cache Busting.

For more information on this package check the documentation . Checkout example here