From Event to Action: Accelerate Your Decision Making with Real-Time Automation
Font End Development + Automation with Django
1. Tips & Tricks for Front End Development Automation Evan Reiser
2. Front End Automation? Tools / Tricks to speed up front end dev work Why talk about this? Same reason we all like Django: More time solving our biz/eng problems Less time doing the same repeatable patterns We want to: Build web apps + add features Not: waste time deploying media, organizing assets, minifying js/css, making sprites etc.
3. django experience Co-founder @ GamerNook Social Network for Gamers 100k+ Members Co-founder @ BloomSpot Luxury Daily Deals 3rd Largest Daily Deals site Co-founder @ AdStack Algorithmically Managed Facebook Advertising
4. Overview Pains with Front end Development Deploying Media Files Compressing / Combine media files Generating Sprites Automate all of this
5. Problems / Pains Annoying parts of front end development Deploying media to media server / CDN Combining JS / CSS files Minimizing JS / CSS Cache-busting media files in prod Building sprite images Referencing sprites in CSS Having to do this all manually These are all common patterns We shouldn’t have to waste time on them
7. django.contrib.staticfiles Pulls media from various places Places them in another place Different folder Media Server Or any custom storage backend S3 / CloudFront CDN
8. Media Files => CDN 1) Set up static files to find #settings.py STATICFILES_DIRS = ( os.path.join(os.getcwd(),"media"), ) STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) STATIC_ROOT = os.path.join(os.getcwd(),"static")
9.
10. Is a python library for interacting with Amazon Web Services
13. Media Files => CDN 4) Reference media in your templates #settings.py TEMPLATE_CONTEXT_PROCESSORS += ( 'django.core.context_processors.static', ) {# Some Template #} <link rel="stylesheet" href="{{STATIC_URL}}style.css" /> <link rel="stylesheet" href=“http://cdn.adstack.com/style.css" />
14. Managing Media Managing Media CSS / JavaScript assets We want to: Reduce Http requests Reduce bandwidth We don’t want to: Think about front-end performance while coding Interrupt our development
15. Managing Media 1. We want to reduce the number of HTTP requests for serving JS + CSS <link rel="stylesheet" href="{{STATIC_URL}}css/admin/base.css" /> <link rel="stylesheet" href="{{STATIC_URL}}css/admin/changelists.css" /> <link rel="stylesheet" href="{{STATIC_URL}}css/icon_sprites.css"/> <link rel="stylesheet" href="{{STATIC_URL}}css/common_10.css" /> <link rel="stylesheet" href="{{STATIC_URL}}css/tablesorter.css" /> <link rel="stylesheet" href="{{STATIC_URL}}css/multiselect.css" /> <link rel="stylesheet" href="{{STATIC_URL}}css/superfish.css" /> <link rel="stylesheet" href="{{STATIC_URL}}css/all.css" />
16. Managing Media 2. We want to minify css / js content and only include what’s needed (reduce bandwidth) /* Make sure to rename this file before you deploy to break client caching!!! */ /* Headers */ H1 { font-weight:bold; } H2 { font-weight;bold; } H1,H2 {font-weight:bold} Obviously the same thing goes for JS
17. Managing Media 3. Don’t want to have to change the asset names to prevent client side caching Style.css Style2.css Style3.css Style4.css Style5.css
18. Managing Media One way to do this is django_compressor Converts & combines linked or inline css/js into cacheable static files Compression / minification support for: CSS Tidy, YUI CSS + JS, Google’s Closure Compiler, JSmin, cssmin Builds unique static file names to bust cache No need to heavily modify existing templates Plus: Extendable for custom post processing / filtering via python
20. Compressor Settings We use a custom Storage Class to store the results on S3 from django.core.files.storage import get_storage_class from storages.backends.s3boto import S3BotoStorage #A special Storage class that saves to S3 and Locally class CachedS3BotoStorage(S3BotoStorage): def __init__(self, *args, **kwargs): super(CachedS3BotoStorage, self).__init__(*args, **kwargs) self.local_storage = get_storage_class( "compressor.storage.CompressorFileStorage")() def save(self, name, content): name = super(CachedS3BotoStorage, self).save(name,content) self.local_storage._save(name, content) return name
26. Automatic Sprites What are sprites? Sprites are composite images made up of other images Why? Reduce # HTTP requests How? CSS is used to only show part of the composite image
27. Automatic Sprites How do we use sprites? Set them as a css background on a fixed size element Position them so only part of the larger image shows Cool. But this is really a pain Creating images Custom css for positioning
42. Automatic Sprites 5) We can easily write template tags to make this easier #front_end_tags.py from django import template register = template.Library() @register.inclusion_tag("common/front_end/icon.html") def icon(icon_name): return locals() {# common/front_end/icon.html #} <span class="icon icon_{{ icon_name }}"></span> 6) Now it’s a bit easier to develop <div> {% icon "user" %} Hello Evan</div>
I’ve worked on a broad range of startups and I’ve w
We need this custom storage backend so that it writes both locally and pushes it to S3. I think its local because it will then check to see if it exists on disk and if so it will assume it exists on the CDN
You can have your system compress these things on the fly, but I imagine in most cases you actually want it to compress all your media as part of your deploy process