Notes of Maks Nemisj

Experiments with JavaScript

I wrote a vim script which can help you to do ‘gf’ on require statements when coding node.js modules. It uses node.js module resolution algorithm to add all the node_modules folders into the vim path variable, so that you can do ‘gf’ on modules which are not relative to the current folder of the file. Which means that doing ‘gf’ on require(‘express’) will open folder of the express source code.

Why. Currently in my tests I don’t use relative paths to the source code, but instead module name and path, like:

require('my-module/lib/some-unit-to-test.js');

so that I don’t have a path dependency of the test relative to the source code. This script helps me to jump into the source code from the test file. Might be useful for other people who also do vim and node.js.

https://raw.github.com/nemisj/vimfiles/master/local-config/after/ftplugin/javascript.vim

Put it in vimfiles/after/after/ftplugin/ and it will do the trick.

, ,

Hi all, today is another javascript experiment where I use Array’s iteration methods forEach and map to look how call function is implemented and how we can use call to implement something ‘not-standard’.

You know often I use forEach or map on an array to execute one method of the instances in this array, e.g.,

var json = arr.map(function (obj) {
    return obj.serialize();
});

Today I thought: “hey, but actually, that would be cool to execute "serialize" method not directly in a anonymous function, but pass it as a parameter to the map method in a more declarative style”. Something like this one:

// arr is an instance of Array field with Zork's
var json = arr.map(obj.serialize);

To say frankly, one of the reasons why I love javascript so much, is because there is always a way to implement something in an obscure manner and I think this case is not any different.

So, let’s start our small journey and imagine that objects in the arr variable are of the type Zork.

When I first thought about how would I achieve this, my first thought was: “Ok, that’s nice, but where do I take the reference to the serialize method from if it’s on every obj, which is available at the moment of iteration? But it’s avaliable also on the prototype of the obj instance, on the prototype of the Zork“, pseudo-code:

var json = arr.map( Zork.prototype.serialize );

But, we all know that it wont work, since map will pass instance of every object as a first argument and scope of serialize method would be wrong.

Luckily, javascript has the ability to change scope of any function/method to the desired one. This can be achieved by using call or apply method which is a member of any normal function in javascript.

Call” method receives scope as the first argument, this means that passing any Zork instance to the call will change scope and execute serialize with a correct scope. Here the example code:

var json = arr.map(function (obj) {
    return Zork.prototype.serialize.call(obj);
});

Check, that’s exactly what I need. So, theoretically this means, that I can also pass “call” function directly to the map

var json = arr.map( Zork.prototype.serialize.call );

When I tried to execute the above function Firfox gave me an error saying:

TypeError: Function.prototype.call called on incompatible undefined

This is not very explanatory message, but after making a couple of tests the answer was a bit shocking for me. I will show you this tests later on, but first my conclusion: “It appears that call function is using the same context resolution principles as for normal “method” calls, but instead call uses its ‘this’ variable for resolving referenced function and not associated object.”

Before I continue let’s remain the basics how javascript resolves this variable for functions.

Function can be called at least in five different ways: “invoke as method”, “invoke as baseless function”, “invoke using “Function.protoype.call”, “function.prototype.apply” and “invoke a constructor using new”. Currently we are interested in two of them: “invoke as method” and “invoke as baseless function”.

When we are caching method and invoking it separatly we are dealing with “invoke as baseless function”. At this moment, execution context ( with other words this variable ) is resolved to the global. Here is example code:

var myObject = {
    some_method: function () {
        return this;
    };
};
//
var cached = myObject.some_method;
cached();

In this code this variable doesn’t point to the myObject object, but instead points to the global something. This is due to the fact, that called function is not called as property of myObject, but instead as anonymous baseless function.

But when function is invoked as a property of the object (“invoke as method”), this variable will point to that object. To say with other words: when function is called “this variable always points to the object to which this function belongs as a property at the moment of the execution. Example to make it clear:

var myObject = {
    some_method: function () {
        return this;
    };
};
//
var second_object = {};
second_object.newMethod = myObject.some_method;
second_object.newMethod();

In the code above “this” variable will point to the second_object, because at the moment of the execution newMethod function was property of second_object object.

Now, after we remembered how context resolution works in javascript, let’s return to our call story.

As I stated, call function is using the same resolution principles and doesn’t have tight reference to it’s associated function and uses this variable to execute associated function. Interesting, isn’t it? In the normal flow execution this variable points to the object, but in our case it points to the function. In pseudo-code you could write call implementation something like this:

var call = function () {
    this();
}

To test my thoughts I’ve created a test snippets which will show below. My snippets uses Zork prototype which is defined as follows:

function Zork(name) {
    this.name = name;
}
Zork.prototype.serialize = function () {
    console.log(this.name);
    return 'My name is ' + this.name;
}

I propose to run call function as anonymous (baseless) function and ensure that it throws the same error as above:

var serializeCall = Zork.prototype.serialize.call;
serializeCall({
    name: 'Nemisj'
});

Console gave back exactly the same error as above.

TypeError: Function.prototype.call called on incompatible undefined

Now let’s execute “call” as a property of “serialize” method, so that we can see whether “call” function is using serialize method as its execution context:

var serialize = Zork.prototype.serialize;
serialize.call({
    name: 'Nemisj'
});

After executing that code it has printed “Nemisj” which proved that “call” is not bound to the referenced function, but defines it at the moment of the execution. If my assumption is correct it also means that I can invoke call function by using its own call method, only instead of passing object to the second call I will pass serialize method.

var serializeCall = Zork.prototype.serialize.call;
serializeCall.call( Zork.prototype.serialize, { name: 'Nemisj' });

This might look a bit weired, but it’s still working :)

This information led me to the next conclusion: In normal situation, if I want this variable to point to the correct object, I use “bind“. But does this mean, that I can use bind function to preserve the associated method for call function? Let’s try it out:

var serializeCallBinded = Zork.prototype.serialize.call.bind( Zork.prototype.serialize );
serializeCallBinded({
    name: 'Nemisj'
});

And the answer is: YES :) After executing this code, it still prints “Nemisj”. Great, now we know how to execute call as anonymous function, let’s move on with our achievement. First implementation with bind:

var serializeCallBinded = Zork.prototype.serialize.call.bind( Zork.prototype.serialize );
var json = arr.map( serializeCallBinded );

But, any iteration method of an Array supports second parameter, which defines the SCOPE of the executed function and since call uses it’s scope to reference the parent function it means, that I can pass the “serialize” method as the second argument and have one nice one-liner:

var json = arr.map( Zork.prototype.serialize.call, Zork.prototype.serialize );

Run…and…check ( http://jsfiddle.net/vNRjd/2 )…code is working :) Well, mission is accomplished I guess.

Except that it does look a bit weird. Passing the same function twice, writing the long Zork.prototype twice..mhee…not nice :) Let’s add some sugar to it.

Because “call” function is isolated and is not bound to its parent function until the invocation, we can pass any native call method to the map as the first argument:

var json = arr.map( Function.prototype.call, Zork.prototype.serialize );

It’s not necessary to give the call method of the prototype of a function, it also can be any call method from any method/function, even the evil “eval” one:

var json = arr.map( eval.call, Zork.prototype.serialize );

But the Function constructor also has a direct “call” method, which simplifies our invocation even more:

var json = arr.map( Function.call, Zork.prototype.serialize );

This looks much prettier and almost human readable: map an array by calling the serialize of Zork :)

I don’t advocate using this code in your production environment. It’s not very self explanatory and it’s a bit slow :) For those who like graphs here is one http://jsperf.com/combine-foreach-and-call. There are more reasons why you shouldn’t write such unreadable code, but I leave it up to you. By making such obscure implementations I understand the working of javascript more and more and I hope you do too.

Have a happy coding.

, , , , , , ,

I bet you know the technique of caching “this” scope in order to use it in a closure.

var self = this;
setTimeout(function () {
    self.doSomething();
}, 100);

Of course it’s not a nice way of writing your code, but sometimes it’s just a fast shortcut, especially if you’re working with an older browser which doesn’t support “bind” feature.

Nevertheless, even when I do use it I stopped using “self” as a variable name for “this” cache. Anything else _this, that, This, whatever_cache_name, but NO self.

And a reason is very simple. self is always available at run-time, even if you move your code or refactor it. It will be always a defined variable, no matter what, leaving you without a nice error like “ReferenceError: self is not defined”. Meaning that forgotten var self = this will be sitting as a spy in your code till the last moment before it will break.

Recently I was doing string casting to a number and while you think it’s simple as it is, it took me a bit to make it fully functional.

My first approach was to use a Number constructor for casting, which would return number or NaN if value was not parsable to the number. But for empty strings, boolean values and null values, this approach gave unsatisfying result.

   Number("zork123") // NaN
   Number("")) // 0
   Number(" "))  // 0
   Number(null) // 0
   Number(false) // 0
   Number(true) // 1

Then, I decided to use isNaN to check the string before applying Number constructor. But isNaN was for no help either. It looks like underneath isNaN uses Number implementation and gives the same result as above :(

   isNaN("zork123")) // true
   isNaN("")) // false
   isNaN(" "))  // false
   isNaN(0))  // false
   isNaN(null) // false
   isNaN(false) // false

After my isNaN attempt faild my next idea was to use parseFloat. But problem with parseFloat is that strings like “123aa” are parsed into 123.

   parseFloat('zork123') // 123
   parseFloat("")) // NaN
   parseFloat(" "))  // NaN
   parseFloat(null) // NaN
   parseFloat(false) // NaN
   parseFloat(true) // NaN
   parseFloat('11111') // 11111
   parseFloat('1.2') // 1

The one solution which is left, was to cast value to the String by using String constructor and then pass it to the Number constructor, which would make boolean and null in a string representation and would result in NaN value for bad strings. Great.

   Number(String('zork123') // NaN
   Number(String("")) // 0
   Number(String(null)); // NaN
   Number(String(false)); // NaN
   Number(String('1.2')) // 1.2

Of course empty string is a breaker here, so time test string before using for emptiness:

    Number(String.trim(value) === '' ? NaN : String(value))

Note: dont’ forget that trim ( https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/Trim ) works only in IE9+ and normal modern browsers

JavaScript keeps surprising me over and over again. I Love this language, but some of the aspects of it, like this one, are just nuts :)

Related StackOverflow question:

http://stackoverflow.com/questions/825402/why-does-isnan-equal-false

, ,

^

This article is dedicated to regular expressions in python based on javascript knowledge. This is the follow up to the article “Javascript to Python API reference guide”.

There is not much of python RegExps that you could directly map to javascript. For this reason i’ve decided to write an introduction article to regexp in python, by using your current knowledge of JavaScript RegExps. It would still be possible to reverse-engineer this article to get the knowledge about JavaScript based on Python examples ;). But enough talking, let’s start diving.

(Main)

Working with regexp begins with importing the “re” module.

    import re

Now you are ready to perform searches, but forget about the lovely inline RegExp literals like /zork/gi. Python leaves us with normal, boring strings e.g., "zork" and flags also are not the part of the expression, but are defined in a different place. As you will shortly see for yourself.

Due to the fact that the expression is a string, you will quickly get tired of using escapes in your regexp. The good news is that python has raw-strings, which can help you with this problem. Just prepend the ‘r’ symbol before a string and backslashes will be interpreted as characters and not escapes:

    # python:
    str = r"regexp."

Now the basics are covered, it’s time to start. I propose we start this journey with a simple regexp test, which most of us perform everyday.

    // js:
    var r = /bork/.test("dork bork fork zork");
    (r === true);

Python doesn’t provide any direct equivalent instead, the search method can be used to accomplish the desired task. This method returns None if nothing is found and this is exactly what we can use for our test. I will explain about the search method a bit later, but for now this will work as a test equiualent.

    # python:
    r = (re.search(r"regexp", "someString") != None);

Well, a test is a fine start, but a regexp is often used for real searching. And while you would expect that I will now tell you more about the search method, you will be disappointed :)

Next, we are going to search for all ( using GLOBAL flag ) occurrences of a regular expression in a string, but with a different method. If you have noticed, I’ve put an extra accent the GLOBAL word because the match method in javascript returns different information whenever the global flag and groups are used. Example:

    // javascript:
    "dork bork fork zork".match(/(b|z)ork/g) == [ "bork", "zork" ]
    "dork bork fork zork".match(/(b|z)ork/) == [ "bork", "b" ]

From this snippet you can see that match omits groups and only entire matches are returned when global is on and shows group information when g is on.

On the other hand python is “more” consistent with return values. It doesn’t omit groups, instead it ONLY returns them. Which means that if you want to have a simple array of all matches, groups SHOULD be uncaptured ( by using ?: after parenthesis ).

    # python
    import re
    re.findall(r"(?:b|z)ork", "dork bork fork zork") == [ "bork", "zork" ]
    re.findall(r"(?:b|z)ork", "dork") == [ ]

Please also take a look at the return value of the last call. When no match is found empty array is returned and NOT NULL like in javascript.

UPDATE: In python an empty array evaluates to false, which means you can use the if construct:

   # python
   if []: 
       print "Will never be called"

Forgotten uncaptured groups provide us with different results:

    # python:
    import re
    re.findall(r"(b|z)ork", "dork bork fork zork") == [ "b", "z" ]

See? This result has only groups in it and not an entire match.

Sometimes I use a workaround which gives me more powerful version – wrap entire regexp in a group and it will give the whole match as a first item in your tuple. Since it’s a quirk there is also a normal way of doing this in python, but I will tell about it later. First, the quirk example:

    # python:
    import re
    re.findall(r"((b|z)ork)", "dork bork fork zork") == [('bork', 'b'), ('zork', 'z')]

That’s fun, isn’t it, javascript has no direct mapping to such an extended result, you could achieve the same with replace, but that’s a different story. Still there are a couple of methods to go.

The next question is, how would you, in a pythonic way, get groups and the whole match result. Let’s start with a simple, non global version. In javascript it’s a matter of taking away the ‘g’ flag, right?

    // javascript:
    var result = "dork bork fork zork".match(/(b|z)ork/);
    result == [ "bork", "b" ];
    // full match of the regexp
    var match  = result[0]; // equals "bork"
    var group1 = result[1]; // equals "b"
    // var groupN = result[N];

In python you would use search as an equivalent. There is also the match method, which is similar to search, but it’s slightly limited. You can read more about it here

    # python:
    import re
    result = re.search(r"(b|z)ork","dork bork fork zork")
    # result == MatchObject instance
    # full match of the regexp
    match  = result.group(0) # 0 can be omitted  - result.group() will do the same
    group1 = result.group(1)
    # groupN = result.group(n)
    re.search(r"(b|z)ork","dork") == None

While you are used to working with arrays of strings in javascript, python gives you access to the MatchObject itself. This object has a lot of extra information which you can use when doing regexp matches, just read the manual.

I think your next question is, what is a pythonic way of doing this for all matches? As you know javascript doesn’t have one and often the replace method is used for such situations.

    // javascript :
    "dork bork fork zork".match(/(b|z)ork/g, function(match, group1 ...groupN, pos, full_str) {
        // use position, group information, etc
    });

To achieve all group matches in python you can use the finditer method, which will return an iterator with MatchObject instances.

    # python:
    iter = re.finditer(r"(b|z)ork", "dork bork fork zork");
    for result in iter:
        match  = result.group()
        group1 = result.group(1)

Okidoki. The basics are covered. Now for the last part: flags, where do you put them and how do you use them.

Normally, regexps in python are compiled before being used. I haven’t used this feature ’cause I wanted examples to be as close as possible to the javascript ones. When regexps are compiled they have the same methods which I’ve already covered.

    # python
    import re
    p = re.compile(r"(b|z)ork", re.IGNORECASE)
    p.search("dork bork fork zork")

That finished my introduction. Before I go, I would like to give some advice about the findall method. Despite the fact that it’s easier to map it to your javascript knowledge, I would recommend that you use finditer instead of findall. First of all, you will save yourself time by not fixing captured groups all the time and the second reason is that finditer is much more powerfull and can be used for a broader scope of problems.

Thank you for your attention.

Links to read:

$

, ,

Do you also keep searching for JS terms to find out what Python API to use? I use this article as a reference guide of the javascript to python API.

Prologue

After constantly working with javascript for more than seven years I’ve decided to explore another programming language. Python became my language of choice.

Since I’m not doing python coding fulltime, I keep diving into the same docs of python again and again, in order to recall how to do simple and basic stuff. For example: looping through the different data types or searching in a string for a pattern.

My long-running relationship with JavaScript only makes the process of learning even more difficult. Every time I’m trying to do something in python i’m searching for the equivalent of javascript API in python. However it can take a long time before the answer is found. For example, how would you do charCodeAt in python? I have to say it took me a while to find an answer to this question, but then, time passes by and I forget it again.

For this reason I wrote this short reference guide. Though it only contains stuff which differs from the javascript perspective. This means I haven’t done a mapping for methods which are the same in both languages.

One piece of advice. In the python REPL you can execute the help function and pass any object to it. The help function will show you documentation regarding the passed object e.g.,

    help([])

will return documentation about arrays.

Global stuff

escape

Syntax: escape(x)

import urllib; 
urllib.quote(x)

unescape

Syntax: unescape(x)

import urllib
urllib.unquote(x)

parseFloat

Syntax: parseFloat(x)

float(x)

parseInt

Syntax: parseInt(x)

int(x)

Note: Be carefull with this one, since it might other thing than you expect. Often parseInt is used to parse any string ( with int or float in it) to an integer. In case you try to parse a float or non-valid number it will throw an error. This means that, stuff like:

int("123.456")

will break in python, but is still valid in javascript.

String

charAt

Syntax: “string”.charAt(index)

"string"[index]

charCadeAt

Syntax: “string”.charCodeAt(index)

ord("string"[index])

indexOf

Syntax: “string”.indexOf(“searchValue”,[fromIndex])

"string".find("searchValue", [fromIndex])

fromCharCode

Syntax: String.fromCharCode(charCode)

chr(charCode)

lastIndexOf

Syntax: “string”.lastIndexOf(“searchValue”,[fromIndex])

"string".rfind("searchValue", [fromIndex])

match

Placed inside RegExp object

replace

Placed inside RegExp object

slice

Syntax: “string”.slice(startIndex)

"string"[startIndex:]

Syntax: “string”.slice(startIndex, endIndex)

"string"[startIndex:endIndex]

split

Syntax: “string”.split(delimiter)

"str".split(delimiter)

substr

Syntax: “string”.substr(start)

"string"[start:]

Syntax: “string”.substr(start, [length])

"string"[start:start+length]

Note: In javascript substring expects length and in Python an endIndex. The comparable function in javascript is slice

substring

Syntax: “string”.substring(start, end)

"string"[start:end]

toLowerCase

Syntax: “string”.toLowerCase()

"string".lower()

toUpperCase

Syntax: “string”.toUpperCase()

"string".upper()

RegExp

RegExp support in python is pretty BIG and is much more extended than in javascript ( IMHO: mostly like anything in Python ). That’s why I have dedicated a separate article to this subject. So if you are going to use regexps intensively I recommend you read that article as well.

Also match and replace are part of the String object, I specify it here in order to emphasize that searching and replacing in Python is not the same as it is in JavaScript.

test

Syntax: var r = /regexp/.test(“string”)

import re
r = (re.search(r"regexp", "someString") != None)

Note: search doesn’t return boolean value, but None if no match is found.

replace

Syntax: “string”.replace(/regexp/, “newSubStr”)

import re
re.sub(r"regepx", "originalString", "newSubStr")

*Syntax: “string”.replace(/regexp/, function(str, p1…p2, offset, s){})

import re

match

Syntax: “string”.match(/regexp/g)

import re
re.findall(r"regexp", "import”)

Note: Please note that only match with the GLOBAL flag is presented here. The reason for that is explained in “Introduction into Python Regexp” as a follow up article.

Date

One of the difference between Python and JavaScript is that Python works with seconds while JavaScript with milliseconds.

Getting Date object of now

Syntax: var now = new Date()

import datetime
now = datetime.datetime.now()

Creating date object based on year, month, etc

Syntax: var d = new Date(year, month, date)

import datetime
datetime.datetime(year, month+1, date)

Note: The month in python is from 1<=12 and not from 0 like in javascript

Creating date object based on epoch

Syntax: var d = new Date(epoch)

import datetime
datetime.fromtimestamp(epoch)

getDate

Syntax: dateObject.getDate( )

dateObject.day

getDay

Syntax: d.getDay()

d.weekday()

getFullYear

Syntax: d.getFullYear()

d.year

getMonth

Syntax: d.getMonth()

(d.month - 1)

Note: That month in python is from 1<=12 and not from 0 like in JavaScript

getHours

Syntax: d.getHours()

d.hour

getMilliseconds

Syntax: d.getMilliseconds()

(d.microsecond * 0.001)

getMinutes

Syntax: d.getMinutes()

d.minute

getSeconds

Syntax: d.getSeconds()

d.second

getTime

Syntax: d.getTime()

import time
time.mktime(d.timetuple())

Math

random

Syntax: Math.random()

import random
random.random()

round

Syntax: Math.round(number)

int(round(number))

Note: round in Python always returns a floating number, while in JavaScript an integer and keep that in mind.

abs, ceil, floor

# All the other methods of math are mostly equiualent to Math in javascript  
import math 
math.abs()
math.fabs(x)
math.ceil(x)
math.floor(x)

Array

push

Syntax: arr.push(item)

arr.append(item)

Note: Python has a different return value, so if you need the length of the array wrap it in a len function

len(arr.append(item))

shift

Syntax: arr.shift(item)

arr.insert(0, item)

unshift

Syntax: arr.unshift()

arr.pop(0) # different return

length

Syntax: arr.length

len(one)

slice

Syntax: arr.slice(begin)

arr[begin:]

*Syntax: arr.slice(begin, end)

arr[begin:end]

concat

Syntax: arr.concat(secondArray)

arr + secondArray

Note: concat is making a shallow copy of an array

When doing a new copy of an array in javascript you do this:

[].concat(x)

But in python you can use this syntax:

x[:]

join

Syntax: arr.join(delimiter)

delimiter.join(arr)

Note: As you can see, the method for joining an array is sitting inside the string class and not in the array class as in javascript

Yesterday I came across two interesting JavaScript behaviors. They gave me different results based on the browser. The first one was only reproducible in IE and the second one only in Firefox.

First, lets see the IE code:

var get = function() {
    return function bla() {
        alert( bla.property );
    }
}

var fnc = get();
fnc.property = "Hello There!";
fnc();

If you think that this code alerts “Hello There!” you are half right. It does in all browsers, except the IE.

The second one also interesting, this is for the Firefox :

var get = function(flag) {
    if (flag) {
        function it() {
            alert( "Flag is true" );
        }
    } else {
         function it() {
            alert( "Flag is false" );
         }
    }
 
    it();
};
 
get( true );

When I typed it, I thought it would alert me “Flag is true”. Well, the problem is, my thoughts were correct, but only for the Firefox browser. In all other browsers it alerts “Flag is false”.

If you had the same thoughts as me, I advice you to read this great article : Named function expressions demystified

There is always something to lear in JS.

, ,

Experiment, test, analyze. Experiment again, test again, analyze again. This is the process of learning the environment, the language and the tools I work with. Taking things apart, looking inside, diving deeper and building a picture of understanding. I think JS is a language with a lot of hidden corners and this time I’ve decided to dig into timers and intervals of the JavaScript. This experiment grew into a browser-based activity monitor of JavaScript execution and I would like to share my experience about it, with you.

How it all started

As you all know, timers in JavaScript get triggered at the moment when the browser is idling. This is described very well in one of the John’s articles at http://ejohn.org/blog/how-javascript-timers-work/ : “Since all JavaScript in a browser executes on a single thread asynchronous events (such as mouse clicks and timers) are only run when there’s been an opening in the execution.”

This information gave me a pretty absurd idea: Is it possible to determine the active/idle state of the browser by using the “opening” behavior of the timers? I thought – yes. But the question is – how? If we start looping “setTimeout” with scheduled time of zero milliseconds, we could collect an interval between the timers and identify the current browser’s state ( active/idling ) based on the interval’s info. Something, like the picture below shows:

timeout works

To prove for myself that this craziness had at least a small rational kernel, I built a small prototype. I injected it into a heavy ajax-based application and I was quite happy with the results. All the results I received had a common pattern in them, indicating that the calculated interval is a reliable source for tracking the browser’s activity. I do agree, that maybe this approach can’t be used for precise profiling of an application, but I still think that it could be used to get the global picture of the browser’s execution flow for the ajax driven applications.

Path into the experiment

To quickly proceed with this experiment, I started with pretty simple code. Collect the difference between the current time and time of the previous timer call, save all the values into an array, and I have everything I need for now. In the first place the code looked like this:

function start(){
    var timer_start = (+new Date()),
          timer_end,
          stack = [];
    
    (function collect() {
        timer_end = (+new Date());
        stack.push( timer_end - timer_start );
        timer_start = timer_end;
        setTimeout( collect, 0 );
    })();

    return stack;
}

// Example of the stack array
// [ 10, 11, 10, 11, 10, 11, 14, 19, 17, 16, 15, 
//    15, 13, 13, 13, 12, 17, 13, 10, 10, 11, 10, 
//    11, 10, 11, ...]

In all the tests I’ve done so far, there was one thing bothering me. Even when the browser was idling, there were almost no zero values in an array, but two digits were continuously repeating. For example: in Firefox (mac) these were 10 and 11. You can see that also also in the example above.

It was clear to me that these two values represent a kind of “baseline” for browser’s idling state. In Mozilla Developer Network (MDN) it’s described as a timeout clamping https://developer.mozilla.org/en/DOM/window.setTimeout ( at the bottom of the page ). Summarizing: clamping is the minimum amount of time between any interval or timer. I also tested different browsers in diferent OS’s ( Windows, Linux, OSX ) and almost none of them got zero values at the moment of idling. Besides that, these clamping values varied between all the browsers.

The funny thing about the timers clamping is that this interval is not just one static number, but two numbers, repeating in turn. These two numbers I called the “baseline”. Let’s look at some of them in different browsers.

Browser “Baseline”
Firefox 3.5.11 ( osx ) 10, 11
Safari 5.0 ( osx ) 10, 11
Chrome 5.0.375 ( osx, win ) 4, 5
IE 7.0 ( win ) 15, 16
Opera ( win ) 10, 11

Table: the baseline for different browsers

Despite the fact that the MDN claims that there is always a delay between timers, this was not the case. Sometimes the interval values were lower than the clamping interval, even dropping to zero value. Digging deeper sheds some light on this weired behavior. I’ve discovered that the dropped interval happened only at the moments of non idle state, when the browser was busy with really heavy execution flow. This gave me an idea that the timers are executing in two different cases.

Case one: The browser is idling. It periodically checks for the suitable timer/interval inside the timer’s and interval’s queue. This period is exactly the clamping moment, which is described in the MDN. At the moment when the browser finds an interval or a timer to be executed – fire.

Case two: Browser is executing JS code. Periodic checks are stopped to prevent timers and intervals being executed at the moment of other code execution. This means, the browser is waiting for an “opening” now. When the execution is finished, the browser starts checking the timers’ queue, without waiting for clamping offset. It controls if the execution of the timer was not far away in the past/future from the current moment and if not the browser executes it. This case also explains why my prototype code gave as a first value – zero. Because there was nothing else to execute and browser could pick up the scheduled timeout.

I do not claim, that this is actually what is happening, but by analyzing from the outside, it appeared to me so.

Tests with simple dump tool

Well, enough of raw data. Users need a GUI and I also needed some representation of the collected data. For this reason I made a first prototype version of a dumping tool. As an input it receives the array with values and as an output it produces some “very” simple graph like the one bellow.

This graph has two sates: “activity” and “no activity” state. They are represented by high level and low level of the bar, respectively. As you’ve noticed the high bar consists of red and black areas. In this way duration and type of the activity was represented.

Let’s start with the red part. The longer the red bar is, the longer the browser stays active. It becomes red, only when the activity interval is longer than the “baseline”. At the moment when the activity goes below the baseline, it becomes a small black stripe.

Because of the visual graph, you can analyze data much faster than with the raw array. Faster analysis, more intensive tests. More conclusions. And the first conclusion which I made was that, it is almost impossible to trace activity, if it is less than the clumping interval. But still, here comes the nice part, web pages nowadays are all heavily event driven, and even a small event often executes longer than the clumping interval. Take for example a typing event, resizing a window, etc. Typing event in an text-area triggered this so well, that I could easily see this in the graph.

Image : Firefox Typing activity

Image : Chrome Typing activity

Or, scrolling. I scrolled a couple of times and I think, this is quite fascinating to see, that graph shows you this four scrolls I made.

Image : Safari scroll activity

Last activity as an example is based on resizing of the Firefox window:

Image : Firefox resize activity

Another conclusion I made was that based on the examples you can see that the timers depend not only on the JavaScript execution of the code, but also on the internal parts of the browser, like moving of the window, or opening a new tab. So, keep this in mind :)

Besides all the graphs of event driven behavior, I also came across another interesting aspect in Firefox when it was “doing nothing” and checking the idle state. Firefox when idling still has some activity peeks. I also looked at Chrome and Safari, but they are all stable as statues. These browsers showed no sign of activity at all, in idle state. First, I thought that it’s just some crazy late running timer, but when I checked the Activity Monitor of OSX I found that there are also the same small peaks of the CPU usage for Firefox processor.

Image : Firefox small idle peaks

From here, I can draw two conclusions: 1. Firefox is really doing something all the time (which is reflected in the CPU usage) or 2. Firefox just has inaccurate timers.

More ?

I could not resist and not to build some kind of runtime activity monitor.

First thing which I did was to check the response of this monitor to the activity. The fastest way was to fire up native Activity Monitor of OSX and compare the peaks of both. It was a surprise to see peaks in the browser monitor first, and only after that in OSX. :)

Image : Firefox and Activity Monitor

Because runtime monitor gives you a global overview of the activity, it was really nice to play with it in a different browsers and compare how they react on different kinds of events/execution. It gave me an instant coverage of the places where browsers spend much time and of the places where they “fly”. For example, I used the test code like this

var arr = [];
for (var i=0;i<16099;i++) {
    var div = document.createElement("div");
    arr.push( div );
}

and I got these results :

Images: Execution of test code : Firefox (win), IE (win), Chrome(win)

Another thing which I noted is the way IE behaves. Its activity always stays at "zero" level when it's idle, a really "silent" browser. Also in the image above you can see that IE gave only the activity of the JS execution, but nothing else. I assume that it has to do with the clamping interval. It has the highest interval between all the browsers, which means that the activity bellow 15ms will always stays invisible to us. Sad. At least we can track resize of the window, with ease :)

Image: Resizing IE

The source of it you can find source at github.

Epilogue

While I was busy with timers I found another interesting article about timers and intervals. I did a small experiment with that too and it appeared that the argument which Firefox passes to the timeout function is equal to the sum of the calculated interval + the baseline. It's not always the same, but in most situations it is. I did not perform any further tests in other browsers, but if you are interested feel free to fill this gap.

This experiment gave me some interesting thoughts. This monitor can actually help you to look at the application from a different angle. It can show you the way the application performs and interacts with the browser. It can show you that the clicking on a button in one browser triggers a more complicated wave of the execution than in the other browsers. It helps to see you your web application as a whole piece and not as a bunch of separated code regions.

As usually, a playground is available for everyone who is interested in it :

http://nemisj.com/src/amonjs/

Known issues: In Linux in Firefox calibration of the baseline sometimes is not working the first time, so you should recalibrate if it behaves strangely.

, , ,

Previous Posts

Theme created by thememotive.com. Powered by WordPress.org.