Ask a Jedi: Strategies for minimizing/customizing resources loaded by a template

Wow, that’s a horribly complex title. Hopefully it makes sense. Anyway, here is the question from reader Doug:

You've covered using custom tags for layout in a couple posts. My struggle is with the head tags.

Say for example, I have 10 different forms in my app, all requiring different jQuery validation scripts. In what manner should I build the head portion of a template to only pull in the specific .js I need?

My current approach just doesn't seem as clean as it could be... I'm cfimporting in a directory of tags, and then including only the ones needed in my head custom tag:

<js:jqSubmitForm form="verticalForm">

It works, but each of the 10 form validation scripts is stored separately and then called just for the one form that needs it. I guess since the script truly is unique to that form, there's no way around it.
But figured I'd inquire... do you recommend a better approach?

So first off - let me begin by saying that my "custom tag for layout" approach is something I've generally moved away from. Not because I don't like the approach (I think 'wrapping' is one of the few places where custom tags make sense in a modern ColdFusion application), but because I'm generally using a framework that has it's own way of handling layout and page content. (As an aside, I am finding myself using the approach in CFBuilder extensions - but more on that later.) Despite that, there is still a need for this. You could simply include every library your site needs within your main template. But doing so adds unnecessary load and processing to your pages. Does it really matter? Probably not for 99% of our sites, but if we can easily manage what resources (JS frameworks, CSS files) get loaded in a template than there is no reason not too.

The approach I've taken is actually pretty similar to Doug's. I update my template to allow for flags that indicate which libraries to load. As an example, here is a snippet of code from Adobe Groups (built using ColdFusion 9 and Model-Glue).

<cfset loadmce = event.getValue("loadmce",false)> <cfset loadrsvp = event.getValue("loadrsvp", false)>

For those who don't know Model-Glue, this code allows views to set a value, loadmce, or loadesvp, to indicate JavaScript libraries and code that need to be loaded. In this specific case one is for tinyMCE and one is for RSVP code. I felt that both code blocks were large enough that I did not want to include them in every request. In a custom tag approach, this could simply be:

<cfparam name="attributes.loadmce" default="false"> <cfparam name="attributes.loadrsvp" default="false">

I kept the flags/names a bit generic. I didn't want my views specifying a particular file to load, like tinymce.1.9.js. I felt that by keeping it generic it would both be easier to read and easier to update behind the scenes.

On another note - I've also made use of JavaScript in my views as well. As much as I'd like to keep everything with head blocks, I don't always particularly worry about it. If I know that I'm always loading jQuery for example, I've got no qualms about doing this in a view:

<script> $(document).ready(function() { stuff }); </script>

JQuery has no issues with multiple blocks like this. I also feel it's better to keep code like this closer to the view. It's worth it to break it out of the head so I can see it closer to the rest of my page layout. (If that doesn't make sense, let me know.)

So - does this seem like a sensible approach? It's worked for me - but how about others?

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate for Extend by Auth0. He focuses on serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.

Lafayette, LA