Client Side Dependency Strategy
Sunday, May 17th, 2009 by Sebastian MarkbågeThis post is in response to an off-site discussion about modular dependency strategies. But I figured I’d post it here for future reference.
The Calyptus Web Resource Manager is a project that can on compile-time or on runtime handle your JavaScript, CSS, and other client-side dependencies. You can keep source code as separate files on the server or pre-compile packages (such as .ZIP, .DLL or .JAR). Currently source is available only on the .NET/Mono platforms but the concept is valid for all platforms.
Syntax
The syntax is largely inspired to be compatible with ScriptDoc and ECMAScript 4 Draft import statement. In the top of your file you add the dependencies that your file relies on:
/*
@import [package, ]filename
@include [package, ]filename
@build [package, ]filename
@compress [always|release|never]
*/ |
Don’t worry, we’re not going to ruin your precious open-source project with inline docs. Read on.
@import – Indicates that this file has a dependency on the referenced file and that it needs to be included in the final document (implicitly before this one). The other file may be a JavaScript file, CSS, image, Flash or something else. The project is fully extensible.
@include – Same as @import but also indicates that the referenced file should be merged into this one on compile or runtime.
@build – Same as @include but also merges any nested @import statements. Allowing you to create a single packaged file.
@compress – Indicate whether the document should use a compression tool (such as YUI compressor) or not. Defaults to “release”, which means that it won’t compress during the debug stage.
You can reference a file by either filename/namespace or package + filename/namespace. You may include wild cards to reference an entire path or namespace. If you’re referencing another file in the same package, you can exclude the package name.
If you are running ASP.NET you can exclude the package if you’re referencing an assembly that is already referenced in your Web.config.
If you’re in a .js file, the filename will automatically look for files ending in .js.
This allows you to do a namespace like syntax on prepackaged files:
/*
@import MooTools.Core.*
@import MooTools.More.URI
*/ |
If you want to use the runtime view generating tools the syntax depends on what View Engine you’re running. For ASP.NET WebForms you can use the following controls:
<c:Import src="filename" runat="server" /> <c:Import assembly="package" name="namespace/filename" runat="server" /> <c:Include ... /> <c:Build ... /> |
In the future this will be integrated into the ASP.NET ScriptManager as well. For other view engines the syntax would be much prettier.
Example
MyBaseStyle.css
div.BaseClassItem { background-image: url(MyBaseImage.png); } |
MyBaseClass.js
// @import MyTheme.css var MyBaseClass = new Class({ initialize: function(){ this.element = new Element('div', { className: 'BaseClassItem' }); } }); |
MyChildClass.js
// @import MyBaseClass.js var MyChildClass = new Class({ Extends: MyBaseClass, ... }); |
MyView.aspx
<c:Include src="MyChildClass.js" /> |
OUTPUT:
<link href="MyBaseStyle.css" rel="stylesheet" type="text/css" /> <script src="MyBaseClass.js" type="text/javascript"></script> <script type="text/javascript"> var MyChildClass=new Class({Extends:MyBaseClass,...}); </script> |
Since I used the included command the file is included in the output document. All it’s dependencies are automatically added to the document through links.
Any referenced file is only added once to the output. So it’s no problem adding multiple references to the same resource in partial views or by indirect dependencies.
MyOtherView.aspx
<c:Import src="MyChildClass.js" /> <c:Import src="MyBaseClass.js" /> |
OUTPUT:
<link href="MyBaseStyle.css" rel="stylesheet" type="text/css" /> <script src="MyBaseClass.js" type="text/javascript"></script> <script src="MyChildClass.js" type="text/javascript"></script> |
In the sample above, I import the base class after the child class. Since the child is dependent on the base, it will be included first. Therefore the second reference to MyBaseClass.js is excluded.
Typical Work Flow – Late Optimization
Typically you would only use the @import statement in all your resources. You should only reference any direct resources that your code or style sheet uses. Indirect files are referenced by the referenced resources so that if a dependency changes, you don’t have to update all your reliers. Your views will only reference the direct resources that it is using by import statements as well.
This will generate a lot of <script> and <link> tags in your documents. This is not good for production where you want to minimize the overhead of multiple requests. That’s when you start building clusters.
Common.css
/*
@build Headers.css
@build Footers.css
@build MyBaseStyle.css
*/ |
Common.js
/*
@build MooTools.Core.Fx.Tween
@build MyChildClass.js
*/ |
Now I can include the cluster Common.js in my view:
<c:Import src="Common.css" /> <c:Import src="Common.js" /> ... <c:Include src="MyChildClass.js" /> |
OUTPUT:
<link href="Common.css" rel="stylesheet" type="text/css" /> <script src="Common.js" type="text/javascript"></script> |
The MyChildClass.js reference and all it’s dependencies are ignored since those file has already been included in the document by Common.css and Common.js. You can for example add these clusters to your Master view to automatically optimize all your partial views. If you remove a reference from your cluster it won’t break any of your code, since those files are individually added by your partial views to your document.
This pattern will allow you to do late optimization of your load-time by grouping only the files that are commonly used in to clusters. Leaving edge-case files into the outer branches of your site. To accomplish this I recommend that you use a modular framework such as MooTools.
Your clusters should be named and composed in relevant packages for your site, not in packages of JavaScript frameworks. For example, DON’T create a MooTools.js cluster that includes all MooTools files.
By default, @include and @build commands are evaluated as @import during the debug stage. That makes it easy to find the references to your source code with debugging tools such as FireBug.
Messing Up Your Beautiful Source? Use Place Holders
If you’re working with a consultant project you can just put all your references in the source file. That makes it very easy to work with. But if you have an open-source project you may not want to mess up the source with dependency references. Instead, use place holder files that @include the original source and references the dependency place holders using @import.
Fx.js
/*
@import Class.Extras.js
@include Real/Source/Fx/Fx.js
*/ |
Fx.CSS.js
/*
@import Fx.js
@import Element.Style.js
@include Real/Source/Fx/Fx.CSS.js
*/ |
Now you can reference your place holders to get dependencies instead of the original source files.
What about my CDN?
You can use a CDN to store your clusters. Just reference the full URIs in your import statements. There is a pre-built class that does this with MooTools on Google. Just @import GoogleAPIs.MooTools.
I will add an @embedded syntax to reference other files that have already been included. That way you could write your own like this:
MooTools-Cluster-Google.js
/*
@import http://ajax.googleapis.com/ajax/libs/mootools/1.2.2/mootools-yui-compressed.js
@embedded MooTools.Core.*
*/ |
If you reference this cluster in your view, all references to your local MooTools files will be ignored since it they are already included in the Google cluster.
@include on Images
If @include filename.png is used in a style-sheet, every instance of url(filename.png) will automatically be replaced with base64 embedded data at runtime. This is only used on the runtime version since this content can’t be sent to IE browsers. IE browsers will get the url(filename.png) reference intact.
This also works with view/document Include commands. In that case an <img> tag is rendered with a link or embedded content depending on the browser capabilities.
This pattern allows you to do late load time optimization of image dependencies.
Getting Started
As always, begin by checking out the source.
March 28th, 2011 at 16:12
Wow! This blog looks exactly like my old one! It’s on a entirely different topic but it has pretty much the same layout and design. Wonderful choice of colors!
March 29th, 2011 at 00:15
great points altogether, you just won a new reader. What could you suggest in regards to your submit that you made a few days ago? Any certain?
April 12th, 2011 at 20:42
You made some respectable factors there. I regarded on the web for the difficulty and found most people will go along with with your website.
April 17th, 2011 at 09:49
Utilize the precious comp card real estate well by making sure your photos emphasize marketability over all else. For example if your website sells skateboards you might consider incorporating audio clips from punk rock bands as opposed to country music bands.
Ballet Info and Popularity
Latest and Most Charming Coach Handbags
Have some Fun With this Gorgeous Alpine Girl Costume
April 18th, 2011 at 12:23
My partner and i seriously like everything you post here. Really unusual and also brilliant. 1 problem though. I’m running Opera together with Debian and also pieces of one’s up-to-date page layout parts certainly are a tiny wonky. My partner and i notice it’s not just a standard create. Yet it’s something to be able to keep in mind. My partner and i hope which it will aid and also continue to keep up the top notch top quality creating.
April 22nd, 2011 at 01:19
Cool blog. I’ll check back here often.
May 5th, 2011 at 01:32
Hey there! I could have sworn I’ve been to this site before but after checking through some of the post I realized it’s new to me. Nonetheless, I’m definitely happy I found it and I’ll be book-marking and checking back frequently!
christian louboutin size 12
christian louboutin peep toe
christian louboutin simple pump
May 28th, 2011 at 08:31
http://www.muzzary.com is online music database site. Here you can download albums and tracks from various artists and bands and you can find lyrics from many tracks.
Try now http://www.muzzary.com
June 1st, 2011 at 03:32
http://loisculmul.paunphilelpil.oyuncehennemi.com/sitemap.xml
June 11th, 2011 at 22:09
Hello, . I think this site could be very useful for me, Like it a lot, tks for the advice
June 17th, 2011 at 07:44
Весьма Полезная запись, нужно будет подписаться на RSS !
June 23rd, 2011 at 17:49
thanks
Thanks for news. Ill be back. Thanks again
June 27th, 2011 at 20:27
I dont know if I see where you are comming from, but do indeed elaborate a little more. Thanks
July 12th, 2011 at 07:56
Thanks for the ideas you have discussed here. Something important I would like to express is that laptop or computer memory specifications generally go up along with other breakthroughs in the know-how. For instance, if new generations of cpus are brought to the market, there’s usually a corresponding increase in the type calls for of both laptop memory plus hard drive room. This is because software program operated simply by these processor chips will inevitably boost in power to leverage the new engineering.
July 14th, 2011 at 12:53
As I site possessor I believe the content material here is rattling excellent , appreciate it for your efforts. You should keep it up forever! Good Luck.
July 18th, 2011 at 02:31
Hi there I am so glad I found your site, I really found you by mistake, while I was browsing on Aol for something else, Nonetheless I am here now and would just like to say kudos for a incredible post and a all round interesting blog (I also love the theme/design), I don’t have time to read through it all at the minute but I have bookmarked it and also added in your RSS feeds, so when I have time I will be back to read a great deal more, Please do keep up the superb job.
July 27th, 2011 at 17:09
Всем Привет! Заходите на manucoz.ruи вы там найдёте все для ucoz и SEO.
August 4th, 2011 at 15:48
Very nice post. I just stumbled upon your blog and wanted to say that I have truly enjoyed surfing around your blog posts. In any case I’ll be subscribing to your rss feed and I hope you write again very soon!