Tags:

Many JavaScript projects are using Mocha to run the unit tests. Combining Mocha with Istanbul and Karma, it is easy to track the code coverage of the application code when running the tests.

While Mocha has a built-in support for running the tests from the command-line via Node.js, in some cases you still want to verify your code with the real web browsers. The easiest way to do that with by using Karma to automatically launch the browsers, control them, and execute the tests. The repository github.com/ariya/coverage-mocha-istanbul-karma shows a simple example on how to do this. To experiment with it, simply clone the repository and then run

npm install
npm test

You should get something like:

Running "karma:test" (karma) task
INFO [karma]: Karma v0.10.8 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [launcher]: Starting browser Firefox
INFO [PhantomJS 1.9.2 (Linux)]: Connected on socket ASrZI0wwAgPFSaxNmDHI
INFO [Firefox 25.0.0 (Ubuntu)]: Connected on socket sBSK-fR9V5s-8pWWmDHJ
PhantomJS 1.9.2 (Linux): Executed 2 of 2 SUCCESS (0.327 secs / 0.023 secs)
Firefox 26.0.0 (Ubuntu): Executed 2 of 2 SUCCESS (0.446 secs / 0.002 secs)
TOTAL: 4 SUCCESS
Done, without errors.

The configuration file for Karma, shown below, specifies that the tests should run on PhantomJS and Firefox. Of course, it is also easy to add other browsers.

module.exports = function(config) {
  config.set({
    basePath: '', 
    autoWatch: true,
    frameworks: ['mocha'],
    files: [
      'sqrt.js',
      'test/*.js'
    ],  
    browsers: ['PhantomJS', 'Firefox'],
 
    reporters: ['progress', 'coverage'],
    preprocessors: { '*.js': ['coverage'] },
 
    singleRun: true
  }); 
};

npm test will run the tests by executing the right Karma task as mentioned inside Gruntfile.js. Note that Grunt is not mandatory here, running Karma directly is as easy as:

node_modules/.bin/karma start karma.conf.js

Just like in the previous coverage examples (using QUnit and Jasmine), the code we want to test is the following simple implementation of the square root function:

var My = {
    sqrt: function(x) {
        if (x < 0) throw new Error("sqrt can't work on negative number");
        return Math.exp(Math.log(x)/2);
    }
};

The tests for that function are in test/test.sqrt.js. In fact, it is also possible to run the tests manually with a web browser, simply open test/index.html file and you will see the report:

mocha

As an exercise, try to remove one test and see what happens as you run the test again. In fact, open the coverage report (look under coverage directory) and you will find the glaring warning from Istanbul, indicating the worrying level of coverage confidence.

coverage

Just like a good code coverage tool, Istanbul reports missing branch coverage. This is very important as looking only at the statement coverage may hide some latent bugs.

Now, if make it this far, you are very close to implement full enforcement of coverage threshold.

Tags:

PageSpeed Module from Google, available for Apache and nginx, is a quick solution to improve web application network performance. As a bonus, if we configure nginx as a proxy server, then it can also serve as a web acceleration solution.

pagespeedThere is a growing number of PageSpeed optimization filters, anything from a straightforward CSS minification to a sophisticated images recompression. If you are already using Apache or nginx, PageSpeed module is relatively easy to use.

A different use case for PageSpeed is as a proxy server which you use for your daily browsing, e.g. what @jedisct1 has implemented via Apache proxy module. In this blog post, I show an alternative setup by using nginx instead, mainly by following the steps described in the ngx_pagespeed project.

Rather that doing things manually, you can just use the automated setup using Vagrant with VirtualBox. Simply clone pagespeed-proxy Git repository and then you only need to run:

vagrant up

For this experiment, the virtual machine is based on Ubuntu 12.04 LTS (Precise Pangolin) 64-bit. If you tweak the configuration inside Vagrantfile to a CentOS-based Vagrant box, e.g. from Opscode Bento collection, it should also work just fine. Should you rather trust your own virtual machine, you can create a Vagrant box from scratch automatically, check out my previous blog post on Using Packer to Create Vagrant Boxes.

The provisioning script of the box takes care the step of downloading the latest nginx and compile it with Google’s PageSpeed module. When it is ready, the script will also launch nginx as a forward proxy at port 8000 (this port is also forwarded and hence the proxy is available for the host machine as well). The proxy will run two optimizations filters (as a starting point): HTML comment removal and JavaScript minification, this can be proved by looking at the provided configuration file nginx.conf:

http {
    server {
        listen 8000;
        server_name localhost;
        location / {
            resolver 8.8.8.8;
            proxy_pass http://$http_host$uri$is_args$args;
        }
        pagespeed on;
        pagespeed RewriteLevel PassThrough;
        pagespeed EnableFilters remove_comments,rewrite_javascript;
        pagespeed FileCachePath /home/vagrant/cache;
    }
}

To verify the operation of the optimizing proxy, run these two commands (on the host machine) and observe the different outcomes:

curl http://ariya.github.io/js/random/index.html
curl -x localhost:8000 http://ariya.github.io/js/random/index.html

The second one pipes the original HTML content through the enabled optimization filters, comment removal and script rewrite, and thereby it will result in a smaller page. This is definitely just an illustration, feel free to play with a number of other PageSpeed filters and observe the impacts.

Obviously, it is also possible to setup your web browser to use the proxy at localhost:8000. When looking at the same URL given above, it will result in something like the following screenshot. Again, compare it with the case where you view the page without using the proxy.

optimized

For a more practical usage of the proxy, stay tuned!

Tags:

In the third part of this JavaScript kinetic scrolling series, the so-called snap to grid feature is demonstrated. The implementation is rather straightforward, it is a matter of figuring out where the scrolling should stop and then adjusting that target position to the intended location.

snaplist
The second part of the series discussed the scrolling deceleration technique by using an exponential decay concept. With a flick list, this means that the list will slow down and stop at some point, depending on the launch velocity at the moment the user releases the grip. It turns out that this also becomes the important key to implement snap to grid.

Note that the exponential decay curve permits us to know about two things (1) when the scrolling will stop (2) where it will stop. As soon as the launch velocity is known, these two values can be computed analytically. This is very powerful, in particular since the final stop position can be adjusted right away. For a quick live demo, go to ariya.github.io/kinetic/3 (preferably using your smartphone browser), flick the list, and see how it always stops to align the color entry to the overlaid slot.

The following diagram illustrates the concept. Without any snap to grid, the curve of the scrolling position as a function of time is depicted in the gray line. Let us assume that the final position will be at 110 px. If we know that the snapping grid is every 25 px, then that final position needs to be adjusted either to 100 px or 125 px. Since the former is the closest, that will be the ultimate final position and the deceleration will follow the curve colored in blue.

decay

The relevant code for this feature can be seen in the repository github.com/ariya/kinetic. Really, it is not much different than the code shown already in the previous second part. The new addition is this following fragment:

target = Math.round(target / snap) * snap;

The variable snap here stores the row height of each item (it is computed once during the initialization). If you already familiarize yourself with the exponential decay implementation, target contains the final scrolling position when the deceleration finishes. Without snapping feature, we don’t tweak this value. When we want to adjust the final scrolling position to be magnetically anchored to nearest snapping location, then we simply change this value.

Also, observe that there is no requirement that snap has to be a constant. A list with non-uniform row height can still enjoy snap to grid feature. All we need is an array of possible values for the final position and every deceleration target must be modified to the closest value. In case you study physics, this is quite similar to the idea of discrete packets of electromagnetic energy in quantum mechanics.

In some libraries which implement kinetic scrolling, snap to grid is implemented by continuously tracking the scrolling position. When it is about to stop, then the position is adjusted to move to the closest possible position based on the grid distance. Not only this results in a more complicated code, such an approach has a major drawback. In some cases, the list can overshoot before it bounces back and therefore it does not demonstrate a smooth scrolling effect at all. With the analytical technique described here, this awkward effect will not happen at all. As always, a proper solution often comes with the cleanest implementation!

What will be shown in the fourth part? Let’s keep it as a surprise!

Tags:

winter2013

It is getting colder, it starts to feel like winter. Right when it will be warmer again slowly, it is time for me to give another round of tech talks.

My first stop is Atlanta, for DevNexus 2014, February 24-25 (follow @devnexus to get all updates). It is not in California, so I expect a true end-of-winter experience. For DevNexus, I’ll have two talks on Tweaking CSS3 for Hardware Acceleration and JavaScript API Design Principles.

If you can’t be in Atlanta, I plan to give another Design Strategies for JavaScript API presentation for the evergrowing Fluent 2014 in San Francisco, March 11-13. I spoke at this wonderful conference twice already, every year was wonderful. Follow @fluentconf for more information on this 2014 edition. If you decide to attend it, it is also packed with other awesome talks.

Last but not least, EclipseCon NA 2014 will be held in Burlingame, March 17-20 (make sure to track @eclipsecon). This time, I will use the opportunity to continue my campaign for a better development experience with the talk titled Next-generation JavaScript Language Tooling. There is a healthy growing front-end developers using Eclipse and expect to see more talks related to JavaScript at this conference.

If you plan to be in Atlanta, San Francisco, or Burlingame, let’s have a chat!

jqcon
Update: I will be also at jQuery Conference 2014 in San Diego, Feb 12-13. At this conference, my presentation will be about Dynamic Code Analysis for JavaScript. This will be my first jQuery event and I’m pretty excited about that.

Tags:

In the second part of this series of JavaScript kinetic scrolling example, the inertial effect is implemented. This is done by tracking the movement while the user is still dragging the view and then automatically scroll the view until it stops at some point.

The first part already covered the basic drag-and-scroll technique (if you have not read it yet, please do so because the concept will be reused here). Before we add the kinetic effect, let us see first what happens to the scroll offset of a list view as the user taps, drags, and releases his finger.

tracking

The shaded area in the above diagram is when the user still manually controls the list, he scrolls up and then down and then up again. Right when this user finally releases his finger, the list starts to enter the automatic scrolling mode. During this mode, the list starts moving at a certain speed but then it slows down and then eventually it comes to a halt. To carry out the automatic scrolling, it is important to figure out the initial velocity right at that release moment. This is done by tracking the finger position and computes the velocity, this happens between the tap and release.

kinetic
If this kinetic scrolling is implemented properly, what we would get is something depicted in the following animation (GIF, forgive the quality). Should you want to play with the live demo, go to ariya.github.io/kinetic/2 with your favorite modern smartphone. Pay attention to the smooth scrolling as you flick the list. Note that it does not have edge bouncing feature yet, we will cover this in some future episode.

How to track the velocity while the user is still dragging and scrolling the list? A simple approach, among a billion possibilities, is to use a periodic timer. When the timer fires, retrieve the current position and use it to compute the velocity. Empirically, tracking the position 10 times per second (a timer interval of 100 ms) proves to be sufficient.

This tracking activity shall start as soon as the user initiates the tap, hence we modify our tap() function implementation to look like the following. The key here is that the function track() which will be invoked repeatedly as long as we still want to track the velocity.

function tap(e) {
    pressed = true;
    reference = ypos(e);
 
    velocity = amplitude = 0;
    frame = offset;
    timestamp = Date.now();
    clearInterval(ticker);
    ticker = setInterval(track, 100);
 
    e.preventDefault();
    e.stopPropagation();
    return false;
}

The code for track() is quite short. The idea is to compare the current position and time to the previous recorded position and time, frame and timestamp, respectively. From this delta, the instantaneous velocity v is easily obtained. The last line acts as a simple moving average filter, this protects us from any wild variation, either from the user’s own erratic movement or from other input noise.

function track() {
    var now, elapsed, delta, v;
 
    now = Date.now();
    elapsed = now - timestamp;
    timestamp = now;
    delta = offset - frame;
    frame = offset;
 
    v = 1000 * delta / (1 + elapsed);
    velocity = 0.8 * v + 0.2 * velocity;
}

The track() function plays its role during the manual dragging (the shaded part in the previous diagram). Once the user releases his finger from the touch device, the situations changes dramatically. Now we have to use the computed launch velocity to decide the next move, as evidenced from the implementation of the following function.

function release(e) {
    pressed = false;
 
    clearInterval(ticker);
    if (velocity > 10 || velocity < -10) {
        amplitude = 0.8 * velocity;
        target = Math.round(offset + amplitude);
        timestamp = Date.now();
        requestAnimationFrame(autoScroll);
    }
 
    e.preventDefault();
    e.stopPropagation();
    return false;
}

Compared to the original code (in Part 1), there is additional block to trigger the automatic scrolling, autoScroll function. The threshold speed of 10 pixels/second is used to prevent any automatic scrolling if the velocity is too low. The launch velocity is used to compute where the scrolling needs to stop, this is the purpose of the amplitude variable. The factor 0.8 is tweakable. If you want to make the list feel "heavy" reduce the number. Consequently, a higher factor will give the illusion of a smooth and frictionless list. Updating the scroll offset is the responsibility of autoScroll() function. Note how this is trigger using requestAnimationFrame for a jankfree animation.

kinetic-differential

A typical flick list has a deceleration that is a form of exponential decay. In other words, the deceleration system is just an overdamped spring-mass system. Fortunately, it is a standard differential equation and its solution is rather straightforward (ŷ is the target position, A is the amplitude, t is the current time, τ is the time constant).

The math may look scary but the actual code is not that complicated. As long as this autoScroll() function still needs to move the list by more than 0.5 pixel, it will be repeatedly invoked. In fact, the following lines of code (it is indeed quite short, isn’t it?) is the heart of this well-known deceleration effect.

function autoScroll() {
    var elapsed, delta;
    if (amplitude) {
        elapsed = Date.now() - timestamp;
        delta = -amplitude * Math.exp(-elapsed / timeConstant);
        if (delta > 0.5 || delta < -0.5) {
            scroll(target + delta);
            requestAnimationFrame(autoScroll);
        } else {
            scroll(target);
        }
    }
}

The value of timeConstant here is quite important. If you want to really mimic iOS (in its UIWebView, decelerationRate normal), the suggested value is 325. This corresponds to a time constant of 325 ms. Math geeks may also realize that with the animation interval of 16.7 ms (from 60 fps), this automatic scrolling effectively reduces the scrolling velocity by a factor of 0.95, which is Math.exp(-16.7 / 325), until it barely moves and therefore the scrolling is stopped completely.

Just to emphasize again, the chart of position as a function of time for this deceleration is depicted below, created using Google plot 150*(1-exp(-t/325)). You may have seen the tail (last part) of the first diagram showing this kind of exponential decay curve.

deceleration

Note that this kind of automatic scrolling also means that the scrolling will stop, regardless of the initial velocity computed earlier, after approximately 1.95 seconds (6 * 325). System theory tells us that after the duration of 6x the time constant, the position will be within 0.25% of the target position (mathematically, you can get that from calculating Math.exp(-6)). Thus, by choosing the time constant, you can make the list feel light or heavy, depending on your need.

How about the rest of the code? It is, surprisingly, still the same as the one presented in first part. There is no need to modify drag() function because the behavior is still the same. Also the helper functions need not change at all. Recycling always feels good!

kinetic-paint
To see the full JavaScript code (roughly 130 lines), check the repository github.com/ariya/kinetic/. It has been tested on Android 4.3 or later (Chrome, Firefox), Android 2.3 (Kindle Fire), and iOS 6 or later (Mobile Safari). Also, as I mentioned in the beginning of this series, treat this example code as an example, nothing more and nothing less (it is optimized for readability and less on performance). Use the basic knowledge to inspire you to write, implement, and tweak your own variant of kinetic scrolling. That said, it doesn’t mean that this particular code is really slow. With Nexus 4 and Nexus 7, there is no problem of hitting 60 fps most of the time. This can also be verified by looking at the detailed frame statistics (using Chrome Developer Tools). Obviously, the painting time HUD is also very useful in this analysis.

The physics effect has fascinated many developers since iPhone popularized the concept. In fact, the web-oriented implementation of this concept exists in various forms (virtually in all mobile-focused libraries), from the early PastryKit edition to a dedicated microlibrary such as FTScroller. If you are always curious about the math and the physics behind it, I hope my explanation above shows that there is nothing really mystical about it.

In the third part, an important feature will be shown: snap to grid.
Update: It is published, please enjoy Part 3.

Tags:

Nexus 5 is the most recent high-end smartphone with the authentic Google experience. With its amazing performance at the given price, Nexus 5 enjoys favorable reviews from The Verge, Ars Technica, ZDNet, Engadget, ComputerWorld, and many others. In term of web browsing experience, how does it compare to its older sibling Nexus 4?

The following basic performance analysis confirms the qualitative observation that Nexus 5 feels much much snappier then its predecessor. Obviously, the main reason behind this is the upgraded hardware subsystems. While Nexus 4 is armed with Snapdragon S4 Pro (quad core, 1.5 GHz), LG and Google boosted the fire power even further with the use of Snapdragon 800 in Nexus 5 (still quad core, 2.3 GHz). The memory system remains at 2 GB of RAM, but the graphics processor enjoys some minor speed bump as well, presumably to handle twice the amount of pixels (1280×768 px to 1920×1080 px). Speaking about pixels, Nexus 5 display (at 445 ppi) is simply gorgeous.

Running the default browser, which is Google Chrome, on Nexus 5 reveals the user agent:

Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/KRT16M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36

For day-to-day web browsing activities, DOM performance plays a very important role. Site interactivity and content handling rely on a smooth DOM access and modification. The following graph (longer is better) shows the difference between Nexus 4 (Chrome 30, Jelly Bean) and Nexus 5 (Chrome 30, KitKat) when running the DOM core tests from Dromaeo (full result).

n5dom

Because iPhone 5S is currently the hottest non-Android competitor to Nexus 5, I also included its result for this particular test. Unsurprisingly, this flagship smartphone from Apple (running Mobile Safari on iOS 7.0) is still miles ahead, presumably due to its powerful 64-bit ARM-based Apple A7 processor.

If we want to focus only on JavaScript performance, a good candidate is the fresh-from-the-over Octane 2.0 benchmark suite. The outcome of running this suite is depicted in this bar chart (again, longer is better). There is hardly a surprise there (I leave it to your imagination as to where iPhone 5S will be positioned there), it pretty much echoes the previous comparison.

n5octane

Need more evidence? Here is Kraken 1.1 benchmark result (shorter is better). If you are not familiar with Kraken, it is a set of benchmarks from Mozilla designed to account for future types of web applications. Again, the numbers won’t lie about the performance differences.

n5kraken

Last time I reviewed Nexus 4 performance, it did not show a refinement compared to Galaxy Nexus. This time however, LG and Google demonstrated a commitment to build a significantly faster browsing performance. And of course, there are other major improvements such as LTE support, high-resolution display, better camera, and many others. If you are currently using Nexus 4, don’t think twice and upgrade right away to Nexus 5!