crammit
crammit copied to clipboard
Performance enhancement: run slimit/cssmin only when needed
When I use cProfile to observe my minify_assets function, one thing is clear: method inside slimit is called often.
So I optimized the _process_bundle method to skipped files that ends with '.min.js' and '.min.css'. See the snippet below:
def _process_bundle(self, name, paths, type):
sha1, sep = '', ''
contents = [open(path).read() for path in paths]
raw_data = ''.join(contents)
if self.config.get('fingerprint'):
sha1, sep = hashlib.sha1(raw_data).hexdigest(), '-'
file_ext = {
'javascript': '.js',
'css': '.css',
}.get(type)
fname_template = '%s%s%s{suffix}%s{gz}' % (name, sep, sha1, file_ext)
raw_fname = fname_template.format(suffix='', gz='')
self.write(raw_fname, raw_data)
# Minify only if asset haven't been minified previously
minified_data = []
for index, path in enumerate(paths):
if type == 'javascript':
if path.endswith('min.js'):
minified_data.append(contents[index])
else:
minified_data.append(slimit.minify(contents[index], mangle=True))
elif type == 'css':
if path.endswith('min.css'):
minified_data.append(contents[index])
else:
minified_data.append(cssmin.cssmin(contents[index]))
minified_data = ''.join(minified_data)
The difference is staggering.
Before:
772394 function calls (761023 primitive calls) in 7.112 seconds
After:
181488 function calls (180859 primitive calls) in 0.766 seconds
I didn't change my assets.yml file. For example, jquery.min.js had always been included.
I also tried replacing slimit with other pure python js minifier before the optimization and the result is the same.
Thanks for bringing it up. I think it can be beneficial to have a configuration option that allows one to provide a list of file patterns to exclude from processing.
Sounds like a good idea.