How do I automate Javascript and CSS minification on Google App Engine?
I couldn't find any proper solution for automating Google App Engine CSS and 开发者_StackOverflowJavascript minification.
If your JS/CSS files are to be used inside an HTML page, then a very good option is to have App Engine optimize your site automatically (minification, bundling, inlining and more) via the experimental "Page Speed" feature. You can turn this on by doing this:
Go to your projects' App Engine dashboard: https://appengine.google.com/settings?&app_id=s~your_project_id
Click on "Application Settings" (bottom left under "Administration" section).
Scroll down to the "Performance" section and locate "PageSpeed Service:". Check the " Enable PageSpeed Service" checkbox and hit "Save".
This will add response filters that will automatically do stuff like combine and minify your JS, turn the minified bundle from a script reference to an inline script (to lesser the count of server requests) and more cool and effortless performance improvments. Read more about this feature here: https://developers.google.com/speed/pagespeed/service/faq
Write a deploy script that makes a copy of your app with minified JS and CSS, and then calls appcfg on it. You shouldn't be minifying it dynamically unless you're generating it dynamically.
I ended up creating this appengine script (uses memcache and slimit). I found slimit to be the best minification script all around, but I'm thinking about using the one from Google instead.
http://ronreiterdotcom.wordpress.com/2011/08/30/automatic-javascript-minification-using-slimit-on-google-app-engine/
You can automate the process pretty efficiently by loading the content of your script into a string, processing it with jsmin and finally save and serve the result. Don't worry about performance, you only run jsmin when the application instance is created (certainty not for every request).
you can grab jsmin.py here.
lets say I have this function that reads the JS from the filesystem (uncompressed, debug version) and returns it's string content in the logger.py module:
class ScriptManager():
def get_javascript(self):
path_to_js = os.path.join(os.path.dirname(__file__), 'js/script.js')
return file(path_to_js,'rb').read()
process it over with jsmin. make sure to use proper caching headers. take this jsrendered sample module as an examp
js_compressed =
jsmin.jsmin(scripts.logger.ScriptManager().get_javascript())
JS_CACHE_FOR_DAYS = 30
class scriptjs(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/javascript'
expires_date = datetime.datetime.utcnow() + datetime.timedelta(JS_CACHE_FOR_DAYS)
expires_str = expires_date.strftime('%d %b %Y %H:%M:%S GMT')
self.response.headers.add_header('Expires', expires_str)
self.response.headers['Cache-Control'] = 'public'
self.response.cache_control.no_cache = None
self.response.out.write(js_compressed)
now return that from a dynamic contnet handler in your main.py:
app = webapp2.WSGIApplication([
('/scripts/script.js', jsrender.scriptjs),...
Nick's answer is the correct way to do it, but you could do it on the fly when the JS/CSS is requested - then set cache-control to public to cache the results upstream.
- Slimmer - http://pypi.python.org/pypi/slimmer/
- JSmin.py - http://code.google.com/p/v8/source/browse/branches/bleeding_edge/tools/jsmin.py
- Cache control header chatter - http://groups.google.com/group/google-appengine/browse_thread/thread/be3fa7b5e170f378 and blog post - http://www.kyle-jensen.com/proxy-caching-on-google-appengine
You could try a build-time or a runtime solution (using maven plugin) provided by a tool called wro4j
Disclaimer: this is a project I'm working on.
精彩评论