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!

Tags:

The process of managing a virtual machine is heavily simplifed via the use of Vagrant. However, there is still a manual or a semi-automatic process involved for creating the base box itself. There are many tools designed to solve to this problem, the most recent one is Packer from @mitchellh, the very same man behind Vagrant.

Packer allows you to create a personal Vagrant base box easily. This means that you don’t need to rely anymore on some random ready-made boxes from the Internet. With Packer, you know what is being installed into your base box and hence the box can be more trustworthy. While Packer supports Vagrant, it can also be used to prepare a system for Amazon EC2, VMware, and many others.

Using Packer to create CentOS and Ubuntu boxes is not difficult. If you want to follow along, I have prepared a Git repository ariya/packer-vagrant-linux which contains all the necessary bits to create CentOS 5.4 and/or Ubuntu 12.04 LTS 64-bit boxes. Make sure you have the latest version of VirtualBox, Vagrant, and Packer installed properly in your machine before you follow these step-by-step instructions.

Packer works with a template file. In the repository mentioned above, there are two templates, each for CentOS and Ubuntu. As an example, if you want to build the base CentOS box, you need to invoke the command:

packer build centos-6.4-x86_64.json

This triggers the download of VirtualBox Guest Additions image and the actual CentOS 5.4 installation image. These two images will be cached, see the subdirectory packer_cache, so that any subsequent build does not trigger a full download again. Obviously, if you rather create a Ubuntu box, just replace the specified file with the one for Ubuntu.

Using the installation image, Packer will prepare a blank temporary virtual machine (clearly visible if you have VirtualBox Manager running as the machine is called packer-virtualbox) and install CentOS into that machine. Unless you are running it in a headless mode, a window will show up the actual installation process:

packer

For many sysadmins, unattended Linux installation may sound familiar: CentOS uses kickstart while Ubuntu uses preseeding. The configuration files for this automated installation are in the http subdirectory (served via HTTP to the installer). You can open the template file, centos-6.4-x86_64.json in the above example, to get the understanding of this unattended installation configuration.

Once the intended Linux distribution is installed, the template file tells Packer to do some basic provisioning by running several shell scripts (check the subdirectory scripts). After this provisioning step is completed, Packer will export the temporary virtual machine and create a Vagrant base box out of it. In this example, it will be stored in the build subdirectory. At this point you are ready to use your base box, it is a matter of using vagrant init with the path to the box in that build directory.

Now, who said packing can’t be fun?

Tags:

shape

Last week I started a new chapter in my professional career. I am now working for Shape Security, a cool startup in Mountain View focusing on the next-generation web content security.

I am pretty excited about the product, the team, and the technology. With a serious funding, along with an impressive array of investors, the journey has just started. Personally, I can’t wait to share with you some of the cutting-edge security systems we are working on!

Stay hungry, stay secure.

Tags:

html5devconf
With my new partner-in-crime Ann Robson, we had a presentation JavaScript Insights at the most recent HTML5 Developer Conference in San Francisco. In this talk, we discussed several important JavaScript code quality tools.

You might have seen my previous renditions of this theme (Fluent, Velocity, and a few others), yet those variants were quite jam-packed and too condensed. As Ann has written in her blog post, one primary objective of this new attempt is to make it "more palatable and practical".

The biggest challenge we experienced during the brewing process of the presentation is figuring out the right composition. We have enough materials to talk all day long about JavaScript language tooling, but we need to pack it in such a way that it can be thought-provoking enough and yet not too cliché. We covered topics such as multi-layer defense, pre-commit hook, code coverage, and cyclomatic complexity. There were also further discussion on tools to catch things like stray logging, Boolean traps, strict mode violations, polluting and unused variables, and nested conditionals.

If you missed this talk, enjoy the slide deck (download as PDF, 1.5 MB).
Update: Check also the 40-minute video.

Of course, feel free to send us your feedback, just hit @arobson and/or @ariyahidayat on Twitter!