Jul 28 2011

Introducing Aardwolf

Category: JavaScript,Mobile,Mobile web,UtilitiesAleksander Kmetec @ 1:34 am

I happen to work in mobile advertising, and mobile advertising these days is all about JavaScript-rich HTML5. And running modern HTML on mobile devices means having to deal with mobile WebKit and its quirks on a daily basis.

As you probably know if you’re in a similar position, no mainstream device running mobile WebKit today supports JavaScript debugging. When debugging rich media ads containing large amounts of JavaScript code in mobile browsers, this becomes a bit of a pain in the neck.

But it’s even worse when it comes to in-app advertising as those ads run inside stripped down WebView components, not inside full featured browsers.

If you think debugging JavaScript in a mobile browser is painful, consider this: on iOS the UIWebView component does not have a console like mobile Safari does, so if your script suddenly dies because of a runtime error, you have absolutely no idea what caused it. On Android you still see error messages printed to the device console, but you can’t debug using alert() statements because alert dialogs aren’t supported by default in Android’s WebView and most companies don’t bother adding support for them.

Add to this the fact that inside a third party application you can’t easily clear the cache or even reload the WebView contents for that matter, and you quickly lose a couple of hours debugging what would otherwise have been a trivial problem.

A remote JavaScript debugger for mobile devices would really make thing easier. So I decided to write one!

No, I don’t mean a remote console! I mean a real debugger with breakpoints, code evaluation when paused at a breakpoint, ability to step forward one statement at a time, create watch expressions and see the call stack.

I decided to base the functionality of this debugger on the idea of code rewriting as I have previously successfully used this approach several years ago to write a PHP profiler in pure PHP. The program would read PHP files, insert profiling timers at every entry and exit point of every function, and spit out self-profiling versions of the original PHP files.

Originally, I intended to the debugger it as an Android app and break execution by making calls into native code through a JavaScript/Java bridge, but upon explaining this idea to Jaka Jančar, a colleague at work, he pointed out it would also be possible to break execution using a synchronous XmlHttpRequest, thus ditching the concept’s dependency on Android’s WebView. A couple of days later I worked out all the details during a 2-hour train ride, then promptly shelved the project for six months. Having figured out all the theoretical problems, I couldn’t be bothered with such minor details as actually writing an implementation.

Then, one damn cold weekend in July, I finally sat down and managed to write something that sort of works. The result is Aardwolf1, a remote JavaScript debugger for Android/iOS, written in pure JavaScript.

And here it is in all of its buggy, unfinished and unstyled glory!

  1. Just some name I picked off of Wikipedia’s insectivore page.


May 21 2009

Ultimate JavaScript minification

Category: Ideas,JavaScript,UtilitiesMatjaž Lipuš @ 10:00 am

This is a guest post by Matjaž Lipuš, a social web geek, front-end web developer and semantic web enthusiast.

After developing some fat client applications using JavaScript frameworks I noticed how some code constantly repeats, making application footprint even bigger than necessary.
A while ago I (once again) stumbled upon article about helping the YUI Compressor. Article is great and in large client side applications could really make a difference in final footprint considering these tips. I think this should be automated as much as possible, so I extended a list of this tips which could be fully automated. And here comes in the YUI Compressor (YUIC).
I am using YUIC for code minification. I also contributed some fixes and suggestions to the author – Julien Lecomte. Those were implemented in past versions. YUIC is a great tool for code minification and munging. I believe it can be further extended and improved generating even smaller output. So here are my tips how to achieve this, ordered by complexity.

Concatenate static strings with +

If you have a big chunk of text to insert into page you would probably split it into multiple lines and making multiple strings. YUIC already has functionality concatenating static strings into one. So code like this:

var x = "This is " +
        "some text";

becomes:

var x="This is some text";

Don not use arrays for this, because YUIC cannot tell you are actually concatenating strings.

Variable declarations at the beginning of the function

Scope in JavaScript is per function. So if you declare a variable twice in the same function, second time variable is just overridden with new value. As JSLint suggests you should declare all variables at the beginning of the function. Looking at this from minification view this means only one var statement! So instead of:

function iterate(array) {
    var result = "";
    for (var i=0, len=array.length; i<len; i++) {
        var el = array[i];
        result += el + ",";
    }
    return result;
}

write:

function iterate(array) {
    var result = "",
        i, len,
        el;
    for (i=0, len=array.length; i<len; i++) {
        el = array[i];
        result += el + ",";
    }
    return result;
}

You should note when declaring global variables there is no need for var statement at all.

This as local variable

Writing serious JavaScript code means writing object-oriented code. In JavaScript we access object members in conjunction with this keyword. This means a lot of this keywords.

Person.prototype.getInfo = function()
{
    var result = "",
        i, len;
    for (i=0,len=this.length; i<len; i++) {
        result += this[i].name + " " + this[i]. surname + " - " + this [i].age;
    }
    return result;
};

Assigning this to a local variable means YUIC can munge local variable to a 1-3 letters which means smaller footprint.

Person.prototype.getInfo = function()
{
    var x = this,
        result = "",
        i, len;
    for (i=0,len=x.length; i<len; i++) {
        result += x[i].name + " " + x[i]. surname + " - " + x[i].age;
    }
    return result;
};

You should note local variable must be declared first, as we could access members of this object in the following variables declaration/assignment.

Person.prototype.getInfo = function()
{
    var x= this,
        result = "",
        i, len = x.length;
    for (i=0; i<len; i++) {
        result += x[i].name + " " + x[i]. surname + " - " + x[i].age;
    }
    return result;
};

You should also note using this as local variable is only reasonable when this keyword occurs at least two times per scope, but that is most of the time.

Shorten numbers

Although this seems to be strange it is simple to trim leading zero from decimal numbers. So instead of:

var n1 = 0.1,
    n2 = -0.1;

you should write

var n1 = .1,
    n2 = -.1;

Common strings

As with JavaScript frameworks and it’s hash style configs there is a lot of string repetition.

var form = new MyForm({
    id: "form",
    items: [{
        type: "text",
        cls:  "blue",
        name: "name"
    }, {
        type: "text",
        cls: "blue",
        name: "surname"
    }]
});

This code can be minified (in a inner scope) as:

var textString = "text",
    blueString = "blue",
    form = new MyForm({
    id: "form",
    items: [{
        type: textString,
        cls: blueString,
        name: "name"
    }, {
        type: textString,
        cls: blueString,
        name: "surname"
    }]
});

A special caution must be given to a strings declared as variables as they can be changed. So we cannot use this variable as a constant. These two strings should be separated into two variables unless we are sure value has not been changed until constant string usage.
We could go even further by moving common strings to outer most scope which uses this string and accessing it in inner scopes with closures and even further replacing substrings (in this case »name«). This raises a question about performance penalties doing string concatenation.

Repeating access to object members

function focusInput()
{
	if (this.msgInput) {
		this.msgInput.focus();
	}
}

this could without any problem been written as

function focusInput()
{
	var msgInput = this.msgInput;
	if (msgInput) {
		msgInput.focus();
	}
}

Shorten object’s member access

JavaScript libraries have a nice namespace convention, but in a large usage of library you get a lot of code repetition.

var store  = new Lib.data.Store(),
    record = new Lib.data.Record();
store.add(record);

We can see a common namespace is Lib.data which can be shorten by assigning to a variable

var Data   = Lib.data,
    store  = new Data.Store(),
    record = new Data.Record();
store.add(record);

There could even be further improvements if we are dealing with (static) object which does not have this key word in the function. Good example is the utility function JSON.stringify(), which can be assigned to a local variable.

var toJSON  = JSON.stringify,
    result1 = toJSON(obj1),
    result2 = toJSON(obj2);

Shorten object’s member names

While using namespaces is good in an organizational way it means a lot of code for just accessing object. The idea is to shorten object’s member names. So instead of

function Person(name, surname)
{
    this.firstName = name;
    this.lastName  = surname;
}
Person.prototype.getFullName = function()
{
    return this.firstName  + " " + this.lastName;
};

code looks like

function Person(name, surname)
{
    this.a = name;
    this.b = surname;
}
Person.prototype.c = function()
{
    return this.a + " " + this.b;
};

This is only reasonable for automated process, although keeping short member names can also save a lot of bytes.
You should keep in mind that you must replace member access in all places, this means where they are defined (set) and used. You also cannot shorten reserved members such as Array’s length or documents getElementsById.
So a good idea would probably be keeping a white list of members which should (not) get munged.

I was already doing some work in YUIC about variable declarations at the beginning of the function, shorten numbers and common strings, but it is not 100% stable, although I successfully minified some of the JS libraries.
Also I did not measure any performance penalties of these tips, but it would be interested to see some.
You should note that this would best perform if code is also JSLint compliant.

Tags:


Jan 02 2009

A pixel measurning device

Category: UtilitiesAleksander Kmetec @ 12:00 am

If you type “free on screen ruler” into Google, you get at least 10 useful results back. If only it was like that back in late 2004 when I actually needed one! But it wasn’t, so I had to spend a weekend writing my own, using an early version of Sharp Develop which liked to freeze, crash, and explode a lot. Fun times.

But despite all the difficulties, I managed to finish it. And only 4 short years later it’s finally available to anyone desperate enough to be actually willing to use it, for free.

It’s called yaRuler (yet another ruler – yes, very original, I know) and it looks like this:

What a ruler might look like

What a ruler might look like

Full feature list, screen shots, downloads and source code are available at the yaRuler project page.

Reblog this post [with Zemanta]

Tags: , , , , ,