JintEngine.Compile(code).ToString()

Oct 26, 2009 at 8:45 PM

I'm wondering if I can inject expressions in a program compiled by JintEngine.

Basically, I want to "optimize" the javascript code before sending it to the YUI minifier (which is a great tool by the way, but a little bit limited)

i.e. If this would be the original javascript:

(function(){
var user = {Name: "John", Languages: ["English"]}
//...
if ($.inArray("French", user.Languages)===-1)
   user.Languages.push("French");
if ($.inArray("Romanian", user.Languages)===-1)
   user.Languages.push("Romanian");
})();

This has 247 chars, and only gets minified to 199 chars.

(function(){var a={Name:"John",Languages:["English"]};if($.inArray("French",a.Languages)===-1){a.Languages.push("French")}if($.inArray("Romanian",a.Languages)===-1){a.Languages.push("Romanian")}})();

I want to re-write it to

(function(){
var _Languages = "Languages",  user = D("Name", "John", _Languages, ["English"]), _French = "French", _Romanian = "Romanian", _push = "push", $_inArray = $.inArray;
//...
if ($_inArray(_French, user[_Languages])===-1)
   user[_Languages][_push](_French);
if ($_inArray(_Romanian, user[_Languages])===-1)
   user[_Languages][_push](_Romanian);
})();

This can reduce the minified output a lot in big files. Of course, in our example the minified output will have only 173 chars, this might not sound like a big improvement but on big files you will gain an extra 20% for free, without any penalty costs!

 

(function(){var f="Languages",c=D("Name","John",f,["English"]),e="French",d="Romanian",b="push",a=$.inArray;if(a(e,c[f])===-1){c[f][b](e)}if(a(d,c[f])===-1){c[f][b](d)}})();

So how can I use this great tool + yui compressor to achieve this?

 

Oct 26, 2009 at 10:34 PM

I think part of the job can be done with Jint. Using the parser, you can get a tree represntation of the source code. This tree contains references to Identifiers, which are the names like user, _Languages, .... What you can do is trasversing the tree using the already implemented Visitor pattern, and for each identifier, give a new name and add it to a lookup table for further usage. With another Visitor, you can then  write back the tree to the corresponding source code. I have to do this one also so you can just wait for it if you want, I will have done it soon. The tree based approach is best to my opinion, as you will be able to pipeliine different optimizations with it, in a decoupled manner.

To go further, look at the JintEgine.cs file, where an instance of Program is created. Program is the tree. And an implementation of the visitor is ExecutionVisitor.

Oct 27, 2009 at 8:48 AM

Thanks Sebastien for the quick reply.

Sure, I can wait - overall it's just a matter of reducing the minified size even lower :)

The visitor is perfect, my question is - how can we "inject" the variables into tree? And of course how to replace a ".Property" to "[_Property]" or ".Method(" to "[_Method](" ?

Thanks, Laurentiu

Oct 27, 2009 at 9:11 AM

Again with another visitor. One can be responsible for Properties, another one for methods. You can then have a very flexible set of visitors modifying the tree for specific scenarios.

The tree can also be modified by adding new nodes, which will be serialized as JavaScript with the visitor I was talking about.

Oct 28, 2009 at 3:59 PM

Please let me know when you have finished the serializer.

Thanks,
Laurentiu
DotNetWise

Nov 16, 2009 at 8:05 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.