[Django]-YSlow Best Practices with Django apps, How to implement them?

3πŸ‘

βœ…

Of the three you listed, two are addressable at the web-server level. For example, in Linux/Apache:

For gzip, edit /etc/apache2/mods-available/deflate.conf

<IfModule mod_deflate.c>  
    AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-javascript text/javascript text/css application/javascript  
</IfModule>  

For Expires headers, first you need to enable mod_expires:

>cd /etc/apache2
>sudo ln -s ../mods-available/expires.load mods-enabled/expires.load

Then you need to configure it for the MIME types you want:

# edit /etc/apache2/sites-available/default  
ExpiresActive On  
ExpiresByType text/css "access plus 12 hours"  
ExpiresByType application/javascript "access plus 12 hours"  
ExpiresByType image/png "access plus 12 hours"  
ExpiresByType image/gif "access plus 12 hours"  

Writeup on why I recommend 12 hours here.

The last item (CDN) is typically something you outsource to someone like Akamai. It’s also quite expensive.

πŸ‘€Chase Seibert

2πŸ‘

I agree very much with you Chase. I’ve developed some django procedures based a lot on the work of Steve Souders and Nicholas Zakas.

My standard practices are:

  • Install django-mediagenerator which is the base for:
    • Combine JS and CSS with mediagenerator bundles
    • Configure mediagenerator to automatically compress JS with google-closure and CSS with YUICompressor
    • ALL static media (non uploaded) is handeled by mediagenerator too. That allows you to use a far-future expires header like 10 years.
  • Minimize the use of images and attempt to produce most of the site in CSS only.
  • Where I must use small images, base64 inline them in the CSS files (using mediagenerator)
  • Where they are large images, combine them into a sprite (I use large images very infrequently though)
  • Nginx and gunicorn for deployment

Nginx gzip config in nginx.conf:

gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_buffers 64 16k;
gzip_disable β€œMSIE [1-6].(?!.*SV1)”;

Nginx far futures expires header:

location /media/ {
    alias   /home/domains/example.com/project/_generated_media/;
    expires 10y;
    add_header Cache-Control public;
}   

They only items left over are image uploads which can still be used with far future expires, because when the image changes the filename should change too.

Using those techniques I have produced sites with 3 http requests. The html file, one CSS request in the header, and one JS request in the footer after the page has rendered.

πŸ‘€AgentK

0πŸ‘

None of these have anything to do with Django, since YSlow is referring to the static assets on your site – JS, CSS and images. Serving these through the development server is bound to lead to failing grades, but doing better will depend on how you configure the real server that ends up serving these.

Leave a comment