Javascript and CSS Compression in MSBuild

Posted in development, javascript by Kris Gray on April 20th, 2007

Want to compress your CSS and Javascript files during your build process? Here is what you need.

Download CSSTidy, and add the executable somewhere on your build machine.

Download and install the MSBuild Community Tasks, or you can do just the Jazmin JSCompress task, though I didn’t do that so I don’t have any source XML for that.

To be clean, I added a Property for the location of CssTidy

<PropertyGroup>
<CssTidy>c:\BuildTools\CssTidy.exe</CssTidy>
</PropertyGroup>

Also I registered the MSBuildCommunityTasks

<!-- Required Import to use MSBuild Community Tasks -->
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\
MSBuild.Community.Tasks.Targets"/>

Then, build a list of all the files you want to compress.
<ItemGroup>
<CssFiles Include="$(websitedir)\**\*.css"/>
<ScriptFiles Include="$(websitedir)\**\*.js"/>
</ItemGroup>

$(websitedir) is just a variable for where the website is, obviously I could have used c:\inetpub\wwwroot or whatever instead.

Then I build two tasks, one that calls CssTidy…
<Target Name="compress_css">
<Attrib Files="%(CssFiles.FullPath)" ReadOnly="false"/>
<Exec Command="$(CssTidy) %(CssFiles.FullPath) %(CssFiles.FullPath) --template=highest" />
</Target>

If your not familiar with the %() syntax, this causes MsBuild to iterate over each item in the CssFiles collection and run this tag for each instance. Otherwise I would get a semi-colon delimited list which nothing handles that well.

The Attrib tag makes everything write-able thus the ReadOnly=”false” attribute, this didn’t seem to be an issue for CssTidy, but it was for JSCompress and I put it here just incase it becomes an issue one day.

The Exec Line executes the CssTidy program, with the FullPath of the searched file (this is meta-data of the item), its included twice to represent the input and output. The –template=highest portion just says do your absolute best!

Then the you add one for JSCompress…
<Target Name="compress_js">
<Attrib Files="%(ScriptFiles.FullPath)" ReadOnly="false"/>
<JSCompress Files="%(ScriptFiles.FullPath)"></JSCompress>
</Target>

Attrib we’ve been over, this is really important here, as JSCompress was failing on readOnly files.

Then I tell it to run the JSCompress tag for each of the ScriptFiles. I feel like I’m explaining exactly what your seeing and already understanding. I hate it when people do that.

Then you need to call these targets.
<CallTarget Targets="compress_css"/>
<CallTarget Targets="compress_js"/>

Not much to it. Hopefully this helps you bring quick loading times to all the web surfers of the world.

7 comments

Javascript performance notes

Posted in javascript by Kris Gray on April 10th, 2007

Getting information on JavaScript performance really is like finding a female programmer. (No punchline to protect myself from the females.) So excuse me if you’ve heard some of this before, but for those JS Perf virgins out there here’s some of the notes I’ve compiled.

Caching

In Javascript you can copy references to Arrays, Functions, Dom elements, anything and once you have that element cached in a local context, you avoid some icky lookups. having lots of periods in a reference (sys.ajax.enums.serverparsed.transformers.optimusprime) creates a lot of object lookups that will hit you on every lookup. In the grand scheme of things, this isn’t that big of a problem, often you won’t be doing any operation often enough that the milliseconds this call would save in any particular call, but something to keep in mind.

Don’t hit the Dom

The last big script application I wrote was an excel like application, so on some occasions there were 450 x 60 (27,000) cells on the page, which I would have to iterate over and perform some operation. In this application the number one performance gain was to cache the properties of each cell and determine if any operations are necessary based on that cached version. Avoiding .innerHTML for reading, not using getAttribute, setAttribute for storing information about the cell, and don’t store references to script manager objects on the dom object.

Prototype’s

The difference here is memory, you only need one instance of a function, unless for some reason you construct the string of the function, but for the most part, if you use prototypes you’ll only get the one instance of the function instead of an instance for each instance. Got it?

Loop backwards and Duffs Device

Put this in the “Almost to small to care” folder. Looping backwards for some reason, gets you a few milliseconds on your loop. Duffs device is a method of executing the same code while not needing to loop quite as much. Its worth it in loops of several thousand iterations, but overall it hurts readability and bloats the code, so look for gains elsewhere.

switch (count % 8)  /* count > 0 assumed */ { case 0:        do {  *to = *from++;

case 7:              *to = *from++;

case 6:              *to = *from++;

case 5:              *to = *from++;

case 4:              *to = *from++;

case 3:              *to = *from++;

case 2:              *to = *from++;

case 1:              *to = *from++;

}  while ((count -= 8) > 0);

}

Manager Objects

In this aforementioned excel like application, I adhered to an object oriented methodology, which turned out to be neurotic. This application ended up having thousands of objects in memory just to manage each cell. It would have been much smarter to have one object that manages all these thousands of cells. This also allows for removing the reference on the dom object to their individual script object instance. Instead I would put just a string identifier on the object which I would use to get from a hash.

var scope

This should be in the obvious section, but if you don’t use var when declaring your variables, the JS engine searches up the chain looking for a property to set, and if it doesn’t find it, then it uses a global variable on the window. At which point references to the variable become global property lookups.

Leaky Memory

Memory holes are causes by circular references that confuse the garbage collector. Namely, DomElement -> Script Object -> Dom Element. Avoid at all costs, if you need, save a string id on the Dom element, and use that to retrieve the script object when you need it.

function Obj(xEl) {

 this.Ref = xEl;

}//--- Memory hole in the making

document.getElementById("el").xScript = new Obj(document.getElementById("el"));

eval()

Everyone knows this is already a performance hog and you shouldn’t use it. Not sure why? Well, when the page loads it goes through all the Script on the page, parses it and loads it then shuts down so the page can go about the rest of its business. When you eval, you start this loading engine again, and this is as heavy a process as it sounds. While not as evil, the new Function(“”) constructor is just as evil, it uses an eval to construct a function from a string value. Never eval to get a variable reference, you can use the bracket structure to pass the name of the variable to its parent object

window["location"]["href"] = "http://www.blackbeltcoder.net/"

If you can think of any others, please post a comment and we’ll get those added. I’ll probably add a part 2 as I remember a few other tricks.

2 comments

Javascript Singleton Part II

Posted in AJAX, development, javascript by Kris Gray on January 27th, 2007

So I wrote that Singleton post a few weeks ago, and what it really turned into is how to initialize Static Properties. Though calling it a Singleton post really makes you look kind of silly, since its a piss poor example of that.

Here is the Class Diagram from Wikipedia for the Singleton Pattern

singleton_classdia.png

To break that down, we have a Public Instance Function that retrieves the singleton instance, and a private constructor so the object can only create itself.

In the example I gave earlier, you can’t have a private constructor, and you can still call the public constructor again after the singleton has been defined. I was really excited to see that the new Prototype 1.5 library that was released (maybe the old one too, I’m just starting to get into it) contains some classes such as the Position class that have no public constructor, and are available without having to construct them initally.

How did they do this I wondered. A quick dig into the library shows that Prototype just uses the inline object syntax, which makes the Position class just an object instance, which of course has no constructor.

var Position = { "Methods" : function() { /* */ } }

I really like this a lot better, and I’ll probably be utilizing it a bit more in the library for our companies product. I’d love to see more libraries out there that you can include and you would get these specialized functional classes. Prototype’s Position is really helpful, what else could we want?

No comments

Javascript Singleton using static properties

Posted in development, javascript by Kris Gray on January 8th, 2007

I’m pretty sure I don’t need to go over the benefits of having a singleton, especially in javascript when you often want to avoid using a global variable whenever possible.

I want to apoligize for the poor formatting of the script, I don’t have the luxury of some of the awesome wordpress plugins out there.

First, lets create a generic object with some base init logic.

function BatmanObj() {
this.mInit = fnInit;
this.mInit();
function fnInit() {}
}

So here we have our Batman object, and we want to always know that we can get the BatMobileObj, and who knows, batman may need access to his BatMobile too.

To do this, we Reference the Objects name, then our property or methods signature.

// Makes Current a reference to an instance of
//the BatmanObj
BatmanObj.Current = new BatmanObj();
// Makes mTurnOnSpotlight a static Method.
BatmanObj.mTurnOnSpotlight = function() {
return BatmanObj.Current;
}

One of the conditions we need to start defining Static Methods and Properties is an instance of an object, so we can’t do it in the container of the object, or outside the definition but its perfectly fine to do in our handy fnInit function.

function BatMobileObj() { }  

function BatmanObj() {
// Bad, Error, Crash and Burn
BatmanObj.xBatMobile = new BatMobileObj();
this.mInit = fnInit;
this.mInit();  

function fnInit() {
// Yay, Success!!
if(!BatmanObj.xBatMobile)
BatmanObj.xBatMobile = new BatMobileObj();  

if(!BatmanObj.Current)
BatmanObj.Current = this;
}
}

The Singleton is only valid once the object is instantiated, but, is good beyond that.

3 comments

« Previous Page