Browser

Google's love/hate approach to JavaScript

For a company that claims to be a champion of online and the web platform, Google's approach to JavaScript is far from consistent.

Take a look at the non-search products that Google has launched over the years: Docs, Chrome, Chromebooks, Maps, Android, the list goes on. The intent of these products is clear: get users to increase their web usage so Google can sell ads to them. When internet usage increases, Google's revenue increases due to its AdWords behemoth.

There can be no questioning the speed with which Google's Chrome browser can render and run web pages and applications. Google knows that for the web to work as a platform, it must approach native code performance to such a point that the lay-user cannot tell the difference in terms of execution speed. The foundation of this speed is not so much in the WebKit browser engine, so much as it lies in Chrome's v8 JavaScript engine.

So successful and efficient is v8, that it has been taken server-side and is used as the core of the event-driven Node.js server.

Google should rightly be applauded for accelerating the execution of JavaScript and provoking other browser makers to up their game to keep pace with Chrome.

Firefox has been Chrome's chief rival in the performance stakes, but last week I noticed that the Mozilla browser had rediscovered an old habit of attempted, and often successful, domination of my machine's memory; an issue that I thought had been killed off long ago by the Mozilla team. As is tradition, I immediately pinned the blame on that old resource consumer called Flash.

But this was one of the rare occasions where Flash was not responsible for the memory hogging. A glance at Firefox's about:memory page fingered the culprit immediately: Google+'s +1 button.

Over a gigabyte and a half of memory was allocated to Firefox, of which over half was used up by the JavaScript engine, and of that the leading comsumer of memory was Google's ironcally named +1 fastbutton. The fastbutton is that little button with the count of +1s a page has. The secret to how this one button could own so much memory lies in the widely panned redesign of Google Reader.

As someone that browses Google Reader in the expanded view, this means that for every RSS item that is rendered on my screen during the course of a day -- a number in the hundreds, if not thousands -- a separate +1 button call is made for each and every story. The end result being that over a quarter of my browser's total memory usage is taken up by a little-used sharing widget.

Just how much code is used for the +1 button? Here's the source of it:

<!DOCTYPE html><html lang="en" dir="ltr"><head><base href="https://plusone.google.com/"><link rel="stylesheet" href="/_/apps-static/_/ss/plusone/ver=aqcig3g6irmd/am=!YruxszVef6JWgwXF/bf=BA/r=O"></head><body class="c-Hv-Pe-Tza"><div id="root"><script type="text/javascript">window.__SSR = {c: 1.0 ,at:'AEIZW7QA\/ehGTQ1zoq\/VWNXexgcyzbET2yWIG9qwsHSt2ho2kGles5BkYhyEntZqoGqo\/QfKVJtKTd1lLUBwaGif6z+MVs6kN2z7Z95+DgUwGDf0KePz00s\x3d',ld:[,[2,1,[]

,,0]

]

,s:'widget',id:'http:\/\/www.techrepublic.com\/blog\/australia\/fetching-64-bit-mozilla-builds-for-linux\/287', is:0};<div id="plusone" dir="ltr" class="Uu"><table cellpadding="0" cellspacing="0"><tr><td><div class="t5"><a href="javascript:void(0);" id="button" class="s5 JF Uu" title="+1" role="button" tabindex="0"></a></div></td><td><div class="KN"><table cellpadding="0" cellspacing="0"><tr><td><div class="uW"></div></td><td><div id="aggregateBubble" class="sW" ><div id="aggregateCount" class="tW">1</div></div></td><td><div class="vW"></div></td></tr></table></div></td></tr></table></div><script type="text/javascript">window['__P1_XP'] = {"UC":true,"UH":true};</div><script type="text/javascript">window.__GOOGLEAPIS = {googleapis: {versions: {pos: 'v1'}}};<script type="text/javascript">window['__P1_BASEURL'] = 'https://plusone.google.com/'; window['__P1_LOCALE'] = 'en_GB';

var _DumpException = function(e) {

e['errsource'] = e['errsource'] || 'api_widget';

throw e;

}

<script type="text/javascript">window['___jsl'] = window['___jsl'] || {}; window['___jsl']['ci'] = [{"gwidget":{"parsetags":"explicit","superbatch":false},"iframes":{"sharebox":{"params":{"json":"&"},"url":":socialhost:/:session_prefix:_/sharebox/dialog"},"plus":{"url":":socialhost:/:session_prefix:_/pages/badge"},":socialhost:":"https://plusone.google.com","plusone_m":{"params":{"count":"","url":"","size":""},"url":":socialhost:/:session_prefix:_/+1/fastbutton"},"card":{"params":{"style":"#","userid":"&"},"url":":socialhost:/:session_prefix:_/hovercard/internalcard"},"plusone":{"params":{"count":"","url":"","size":""},"url":":socialhost:/:session_prefix:_/+1/fastbutton"}},"googleapis.config":{"methods":{"pos.plusones.list":true,"chili.people.list":true,"pos.plusones.get":true,"chili.people.get":true,"pos.plusones.insert":true,"pos.plusones.delete":true,"chili.activities.list":true,"chili.activities.get":true,"pos.plusones.getSignupState":true,"chili.activities.search":true},"requestCache":{"enabled":true},"versions":{"chili":"v1","pos":"v1"},"rpc":"/rpc","root":"https://www.googleapis.com","root-1p":"https://clients6.google.com","sessionCache":{"enabled":true},"transport":{"isProxyShared":true},"xd3":"/static/proxy.html","developerKey":"AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQ","auth":{"useInterimAuth":false}}}];<script src="https://plus.google.com/_/apps-static/_/js/widget/googleapis_client,iframes_styles_bubble_internal/rt=j/ver=Tdfx_nYpXjo.en_GB./sv=1/am=!W_gXXLnZrrYgVlks/d=1/"></script><script type="text/javascript">var params = {};params['height'] = 24.0 ;iframes.ready(params, {'canAutoClose': function() {var f = window['__CAN_AUTOCLOSE_BUBBLE']; return f ? f() : true;}});<script src="/_/apps-static/_/js/plusone/p1b,p1p/rt=j/ver=dpsyOqdMQIE.en_GB./sv=1/am=!YruxszVef6JWgwXF/d=1/"></script></body></html>

It's messy but comes in at only nine lines.

Look closer, though, and you will see that it is calling two other JavaScript libraries -- these files clock in at 333 and 128 lines each. That's approximately 500 lines of minified JavaScript to render a single button.

Depending on the structure of a site's feed, I can get up to six articles appearing on-screen in the expanded view -- that's 3000 lines of JavaScript to render only the +1 buttons, this is on top of the JavaScript used to control Google Reader itself.

For a company that is meant to evangelise the use of JavaScript as a first-class language throughout the web and beyond, it is quite the slap in the face.

It is directly because of this memory usage that I have had system crashes over the past couple of weeks. Starting a virtual machine should not be the start of a quickly tightening death spiral that is entered due to the host and guest OSes fighting over the little memory remaining when Google Reader has been open for a long period of time.

So far I have pointed out the problems with Firefox, mainly because it is my primary browser, but in a test of bug replication, I was also able to make Chrome chew up the available memory simply by reading RSS feeds. I will give Chrome some credit for being far more thorough and aggressive than Firefox in its memory clean-up procedures; it took a greater amount of time for Chrome to hit the heights of Firefox, but nevertheless hit them it did.

Solving the memory usage in Chrome was as simple as closing the Reader tab and reopening it, Chrome's tab-per-process architecture allows it to clean-up itself far better than the single process Firefox can. But this is far from a user-centric solution -- why should Jane user have to close her Reader tab simply to launch an application that requires a large amount of memory? It's simply not acceptable if the web is to become the application platform of the future.

The blame for this therefore falls not on the browsers but on the extra JavaScript added in the Google Reader redesign.

While Reader is the biggest offender in the Google stable of sites, spare a thought for some of the other offenders in memory usage.

Google Analytics has a new look that makes use of Flash to show a useful real-time visualisation of incoming traffic. Unfortunately, leaving that page running for a few hours makes Analytics approach half a gigabyte of memory. And Google+ itself is not lacking in memory requests, nor does Gmail or Google Docs, all three consistently hover between 30 to 50 megabytes each.

Keep in mind that Google is a company that is pushing the Chromebook, its version of the netbook form factor. A quick glance at the model specs shows that Chromebooks currently offer 2 gigabytes of memory. So if a user is browsing RSS, writing up a few documents, checking email and maybe even looking at their site analytics like Google intends them to -- it does not leave much memory for the browser itself or for Angry Birds or other flash games to fit into.

The v8 engine may be lightning quick, but running it on the slower Atom processor in a Chromebook with memory limited to 2 gigabytes would not be a pleasant experience.

This is why Google should be extra focused on optimising and reducing the overhead that its sites incur. If a user with a Core i5 laptop is having issues with performance, what must it be like for those who have taken a plunge with the Chromebook?

The best encapsulation of Google's newly found love of JavaScript verbosity must fall to Dart's JavaScript-compiled Hello World example, which weighs in at just over 17,000 lines of code. The comments attached to that example sum up the sentiment regarding Dart far better than words can.

Simply because Google produces the quickest JavaScript engine on the market, does not mean that it should forgo trying to get every millisecond of performance out of its website JavaScript: not only for users of Chrome but also for the majority of users that do not use Chrome and suffer a bigger loss when Google's JavaScript gets reckless with memory. The browser landscape is a more complex scenario than deciding to use the quickest browser -- if this were true we all would have switched to Opera back in the early 2000s.

There is only so long that a vendor can use a quicker platform to outpace the drawbacks of an increase in software bloat -- Microsoft turned the corner with Windows 7, Google would do well to learn from that lesson while the platform is still evolving.

About

Some would say that it is a long way from software engineering to journalism, others would correctly argue that it is a mere 10 metres according to the floor plan.During his first five years with CBS Interactive, Chris started his journalistic advent...

6 comments
nwallette
nwallette

Same story as always though. You can build the best tools on the planet, but when you optimize the platform, the code monkeys will just write sloppier code -- because they can. At least the rest of the web runs really fast! :-)

Professor8
Professor8

Yah, it's broken... probably by design. The "polls" don't work, either. But then so are Google and Javascript.

Dethpod
Dethpod

Cross browser. I bet that 1/2 of it is to deal with the 4 versions of that sack of suck known as IE.

spdragoo
spdragoo

I guess I won't be using this "+1" button feature.

nwallette
nwallette

That would reload your page on click. With AJAX, you can send HTTP data without a refresh. The downside is, you have to have client-side event handlers to update the displayed content based on the server's response to your button press. And error handling code in case it didn't work for whatever reason. That's a lot of code that would have been hidden on the server side.