Scott Gray wrote:
> Hi All,
>
> I've just finished a freemarker transform that validates and combines
> javascript resources and then renders the script tags, I'm interested to know
> if it's something you want in the project.
>
> Features:
> - Makes sure that each script actually exists before telling the browser
> about it, removes any possibility of the browser 404'ing on javascripts.
> - Automatically combines scripts into a single file to reduce the number of
> http requests the browser has to make
> - Define groupings that control how the scripts are combined, e.g. if you
> have some scripts that are used on every page then you can combine them into
> their own group to take the most advantage of browser caching. You simply
> use the "#" sign to append a group name to the end of each script path:
> <set field="layoutSettings.javaScripts[+0]"
> value="/images/jquery/plugins/datetimepicker/jquery-ui-timepicker-addon-0.9.1.min.js#core"
> global="true"/>
> <set field="layoutSettings.javaScripts[+0]"
> value="/images/jquery/ui/js/jquery-ui-1.8.6.custom.min.js#core"
> global="true"/>
> - Use the #solo group name to indicate scripts that shouldn't be combined,
> useful if you're using some sort of CDN for your jQuery lib or whatever.
> - Caches the results so that the processing for each set of resources happens
> only once
>
> The idea is to remove the need for a balancing act between lots of smaller
> scripts but too many requests or a few large scripts with lots of unused
> code. I figured since it changes something that hasn't changed in years I'd
> check before committing. I could also just commit the transform but not use
> it OOTB.
>
> I'm also planning something similar for CSS files but it's a little more
> complicated because of the @import statement that can appear in them.
Be very careful about combining lots of javascript files into one.
You *must* do proper If-Modified-Since handling, or you will greatly
increase the bandwidth usage of client browsers.
Without a proper ETag, and If-Modified-Since handling, the browser
will download the combined javascript file repeatedly, on each page
load. The solution, is a bit convoluted.
==
allETags = []
greatestLastModified = 0
for(file in files) {
perFileETag = perFileLastModifiedTime + '-' + perFileSize
allETags.add(perFileETag)
if (perFileLastModifiedTime > greatestLastModified) {
greatestLastModified = perFileLastModified
}
}
etag = allEtags.join(':')
response.setHeader('ETag', etag)
response.setLastModifiedTime(greatestLastModified)
==
and...
in IMS mode, the previous ETag will be given. Split that on ':',
iterate each part, comparing the lastModifiedTime and size to the
current list of files.
IMS mode is also different in HEAD and GET mode.
I suppose I should pull out the Binary handler in webslinger, as it
has support for all of this.