Ambient Light Web API

The ambient light sensor can now be accessed from a web page through the Ambient Light API.

I was able to access the ambient light sensor on a couple of my android devices from a web page through the new “devicelight” event listener. At the time of this post, only FireFox Mobile 15.0.1 supports this API.  I tested this on iOS 6 Safari, Opera 12.0.4, Chrome 18.0.1025308, and Browser 4.1.1-398337 as well.  None of them called the event.

My tests were successful on both my Google Galaxy Nexus (Samsung) and my Google Nexus 7 (Asus).  The values that the devices returned were significantly different for similar lighting conditions. This may make it difficult to build software that responds to certain light conditions. The polling interval is also inconsistent between devices.

My Galaxy Nexus gets values that range from 4 to over 50,000. The lowest value: 4 is achieved by covering up the ambient light sensor. On the Galaxy Nexus (and on most phones) it is located close to the ear speaker. Here is a list of values and the conditions in which I receive them:

Galaxy Nexus Sensor Value Nexus 7 Sensor Value Lighting Condition
4 0 Darkest Condition
30-40 20-60 Indoor angled away from lights
200-400 600-850 Indoor angled towards lights
1500-2500 untested Indoor angled towards sunny window
7780 11600 Outdoor angled towards an overcast sun
50,000 untested Outdoor angled towards an unobstructed sun

On the Galaxy Nexus, the event listener is called only when the value changes. If the ambient light is constantly changing, the listener will be called every 200 milliseconds. If the light doesn’t change the event does not get called.

On the Nexus 7, the event listener is called every 69-70 milliseconds. The light value changes constantly. There are times when it takes up to 450 milliseconds between event listener calls, but I attribute this to garbage collection or background processing. The reported light values ar constantly changing.

The good part is that the code couldn’t be easier. Here is mine:

window.addEventListener('devicelight', function(event) {

Posted in Uncategorized | Tagged , , , , , , , , , , | Leave a comment

JavaScript’s “this” Keyword

Angus Croll published a classic article on JavaScript’s this Keyword. I created a quick impress.js presentation to help communicate this to engineers. Check out the presentation or the code on github.

Posted in Uncategorized | Tagged | Leave a comment

Why use Cookieless Domain?

What is a cookieless domain? A cookieless domain is a domain like any other. It is used to serve assets that will not use cookies. It is common to serve images, styles, and scripts from a cookieless domain.

Setting up a cookieless domain is simple. For a site located at one might consider registering as a cookieless domain. The name of the new domain is not important. The new cookieless domain may be configured to resolve to the same place as the original domain. All of the static files that will not use cookies may then be served from the new cookieless domain by simply changing the source location of that asset.

The value of a cookieless domain may seem small. All of the cookies for a single site are typically less than 10 kilobytes combined. So why go through the work for such a small gain? Because the cookies are sent with every request for every asset. A quick look at popular online news outlets showed an average of 150 requests were made to load the home page. One of the sites,, made 265 asset requests in order to load the main page. If 10 kilobytes of cookies were sent with every one of those requests, user’s browsers would be uploading more than 2.5 megabytes of cookies to request assets that would never use those cookies.

Uploading data that will never be used is particularly bad because client requests are not compressed like client responses. Server responses can be compressed to an average 25% of their original size. And many users have asymmetrical internet connections that provide download speeds that are up to 20 times greater than upload speeds. When these circumstances are stacked, 150 kilobyes of upload can take longer than 5 megabytes of response data.

The HTML 1.1 specification limits the number of connections that a browser can establish to a single domain to two connections. Most current browsers disregard this limit and allow for between four and eight connections per domain. Cookieless domains allow browsers to download twice the number of assets simultaneously by adding the extra domain.

Its cheap, easy, and improves the site performance. Win, win win.

Posted in Uncategorized | 4 Comments

Using Your Phone as a Game Controller

I was trying to come up with a presentation demo that would show off the iOS gyroscope api.  At first the best that I could come up with was a scrolling marquee.  I thought that it would be cooler than it actually was.  You know those spinning LED toys that you pick up at county fairs, amusement parks and sporting events.  Something like that.  The plan was to show text far larger than could fit on the screen.  As the screen moved the text would essentially stay in place.  So waving a device back and forth should show the entire message.  Problem: sliding horizontally does not register on the gyroscope.

My second plan was a little better.   I could use the device as a remote control for a web bowling game.  The iOS gyroscope and accelerometer data together could provide a pretty decent bowling controller.  It would not be as accurate as a Wii or PS3 controller because those controllers have the benefit of an external camera that tracks their location.  But I could calculate a swing, rotation, and twist.  So I did it.  And it works.  The swing calculations could use some tweaking for sure, but here is the gyroscope and accelerometer code:

var ballGrab = function(e) {
  playr.orient = [];

  playr.btn.removeEventListener('touchstart', ballGrab);
  playr.btn.addEventListener('touchend', ballRelease);
  window.addEventListener('devicemotion', record);
  return false;


var ballRelease = function(e) {
  playr.btn.addEventListener('touchstart', ballGrab);
  playr.btn.removeEventListener('touchend', ballRelease);
  window.removeEventListener('devicemotion', record);
  socket.emit('release', calcSwing());


var record = function(e) {
  var acl = e.accelerationIncludingGravity,
  rot = e.rotationRate;

    ax: acl.x,
    ay: acl.y,
    az: acl.z,
    ra: rot.alpha,
    rb: rot.beta,
    rg: rot.gamma

I have left out some bits of code here. The trimSwing() function goes backward through the orientation data to dump all except the data for the last forward swing. Then the calcSwing() turns the swing data into four basic values: power, acceleration, rotation, and twist.

The values are sent via to a Box2Djs front end that throws the ball into the pins. Box2Djs is equally cool. I will save that for another post. If you would like the complete code, you can find it on .

Posted in Uncategorized | Leave a comment

Studies On Site Performance

A couple of recent blog articles on different ways to improve site performance led me to go dig up some less recent studies on the impacts of performance (or the lack thereof).  I threw some of the data into some graphs.  When the data is brought together it is compelling.

Greg Linden presented some data stating that 100 milliseconds of site delay cost 1% in loss of sales in his presentation entitled Make Data Useful.

Eric Schurman of Amazon and Jake Brutlag of Google presented the following data from  It demonstrated drops in distinct queries, query refinement, revenue per user, any clicks, and satisfaction.

Schurman and Brutlag also showed that increased site delay caused an increased user interaction delay.

They showed that Google experienced reduced site traffic even with very small site delays.

The impact of the site delays grew worse over time.  After six weeks of slower performance the damage had doubled.

Even after removing the artificial delay, searches per user did not return to original levels.

A summary of a Aberdeen Group study entitled “The Performance of Web Applications: Customers are Won or Lost in One Second” claimed that Web Applications experienced similar user response from slow performance.  The summary alleged that a one second increase in load time resulted in:

  • 11% fewer page views
  • 16% decrease in customer satisfaction
  • 7% loss in conversions

Many other web performance related resources can be found at the strangeloop web performance optimization hub.

Posted in Uncategorized | Tagged , , , , | Leave a comment

The Open Web Platform

The Open Web Platform. That is what you call it now. You may have called it something different before. Most people did. Here are some of the common (and not so common) labels:

  • HTML5
  • Ajax
  • Rich Internet Applications
  • Single Page Applications
  • Service Oriented Front End Architecture (SOFEA)
  • Service Oriented User Interfaces
  • Native Web Development
  • JavaScript Client Controller Architecture
  • JavaScript UI

But it is settled now. It is called the Open Web Platform. It may not be the be the most descriptive or marketable label, but it is the one that stuck.

Posted in Uncategorized | Tagged , , , , , , , , , , | 3 Comments

Google Chrome Decides to Lead


Ian Fette, Alex Komoroske, and Alex Russell presented at Google I/O on “HTML5 and What’s Next”.  The presentation was an insightful step-by-step tour of the future of Chrome and likely the web.  Google has obviously decided that waiting for standards bodies or other browser vendors to determine the future of the web is neither timely nor in their best interest.

Due to the lack of immediate project applicability, many of my peers dislike (and even avoid) these type of presentations.  Their grumbling disapproval is often accompanied by comments alleging new features’ lack of availability until 2015.  But the rate at which browsers implement new features is not where it was in 2005.

Here are my notes on the presentation.  I have the times in parenthesis on the right so that you may quickly jump to sections that are of particular interest.

Filesystem API (4:00)

  • Introduced in Chrome 8
  • Applied to Chrome Apps and Extensions
  • Chrome 13 will extend API to all web applications (5:54)

Offline Storage (6:10)

  • 5MB is not adequate
  • New quota system: (6:55)
    • Temporary Storage (7:32)
      • Will not prompt the user
      • Space is managed by the browser
      • Data may be evicted when space is needed
    • Persistent Storage (8:49)
      • Will prompt the user
      • Space is managed by the browser
      • Data may be evicted when space is needed

Web Sockets (9:50)

  • Multiplexed

3D (10:50)

  • WebGL
  • CSS Transforms

Cognitive overhead and complexity (15:00)

CSS Refactoring (16:58)

  • Variables

CSS Mixins (18:45)

  • Style groups
  • Macro (?)

CSS Nesting Hierarchy (22:30)

  • Shortens sub-rules
  • Works with variables and mixins
  • Shrinks CSS

JSConf mentioned (23:55)

CSS Animations and Transitions (24:43)

  • New animation syntax (27:42)
  • “interrupt: reverse” backs out animation

CSS Customization and Calculation (29:24)

JSConf & NodeConf mentioned (31:53)

Other CSS Improvements (32:21)

JavaScript improvements and Traceur (33:20)

Model-driven view (34:13)

  • Templates and databinding
  • Template element (36:03)
  • (Looks like Mustache syntax)
  • ECMAScript Harmony proxies (37:00)
  • Listening on data changes
  • Model property added to all elements (37:37)
  • Recursive template example (38:24)

Available today via prototypes (42:15)

Call to Browsers (42:30)

  • Implement early (extensions)
  • Standards will follow

Questions (43:45)

  • App engine channel API? (44:05)
  • When is the DOM updated by templates? (46:06) Template disconnect issue!
  • How does filesystem interact with HTML5 Audio? (47:38)
  • Microphone and Camera access? (49:46)
  • SEO issues with templates? (52:00)
  • (inaudible) Platform vs. libraries? (53:19)
  • Programmatic description in the templates? (54:10)
  • Status of IndexedDB? (55:13)
  • Background pages vs. web workers? (56:31)
Posted in Uncategorized | Tagged , , , , , , , , , | Leave a comment