Stoyan Stefanov is all about the performance of web products. One small tool that gives you a bit of insight as to where you can optimize is a new bookmarklet he released today called statsy.
If you run statsy on a web site you get the following insights:
JS attributes (e.g. onclick) – this is the sum of all onclick, onmouseover and so on including the attribute names. So for example <a onclick="#"> is 11 characters (bytes) of JavaScript attributes code
CSS style attributes – the sum of all style="..."
Inline JS – the sum of all the contents of all script tags (excluding the tag itself)
Inline CSS – sum of all <style> tag contents
All innerHTML – this is document.documentElement.innerHTML.length, it should be close to the ungzipped size of a page, provided the page is not doing a lot of DOM manipulation
# DOM elements – the total number of elements on the page is counted simply using document.getElementsByTagName('*').length
We have posted about LABjs before, the library that aims to be able to effectively load any script resource(s), from any location, into any page, at any time. It loads them all as parallel as the browser will allow, but maintains execution order when you express the need to do so in the usage of the API, for keeping dependencies safe.
At JSConf.EU in Berlin, I saw Steve Souders and Kyle Simpson riffing on how to make LABjs follow the research that Steve (in his newest book) and Kyle have done.
Give it a whirl, and read the full post for details on performance and issues with flashing in before behaviour has been added... which leads us to the cavaet on jQuery and DOM ready.
Also, if you think that you should be just concat'ing all of the files into one, see why Kyle thinks you should potentially think again.
As I wrote this another library called NBL came in from "Berklee". He told us:
The other day I tasked myself with rewriting our company's website in HTML5 and I really wanted to improve performance all across the board. So after rewriting the HTML and CSS, I looked to JavaScript lazy loading to increase performance. After searching for a small library to do this and not finding anything not requiring jQuery, or unable to handle network timeouts, I decide to write my own non-blocking lazy loader.
It's called NBL and comes down to 1187 bytes minified. It runs stand-alone and has several options that I could not find in any other library:
1. It can load plugins for your JavaScript framework *after* the framework has been loaded (jQuery is considered the default, but you can override it with any other framework and keep this behaviour).
2. You can provide a callback function that fires when all scripts are loaded, or if you use jQuery, the callback will be fired by jQuery's document.ready() function (unless the page finishes before jQuery initialises, in which case it fires when all scripts are loaded).
3. In case of network latency (or faulty urls), NBL will fire the callback function after a timeout (by default 1200ms).
4. It does not need to be called, it can be configured completely from the script tag itself, like this:
Tutorialzine is a nice blog but I think sometimes it should should re-dimension chosen titles.
I have discovered only yesterday and thanks to my good old favorite Web related italian blog, a nice (or if you prefer another) jQuery lightbox style experiment.
The post is complete with examples and explanation over PHP, CSS, jQuery, and finally jQuery UI.
So what is the problem? The title: An Awesome CSS3 Lightbox Gallery With jQuery
At the end of the day, the total size of the demo is massive, compared with what it offers, plus the only piece of CSS3 in the stylesheet is a box-shadow and a rotation via -webkit-transform.
Is That It?
If we can define awesome a basic usage of CSS3 requiring both jQuery and jQuery UI to create a Gallery, included a server side language, how can we define my latest experiment realized in half an hour and without using JavaScript, PHP, or whatever programming language at all?
The answer is simple: CSS3 and we can read how I did it via the not-minified and hopefully well commented css file.
OK, agreed my page is dynamically fake and a proof of concept, but honestly, which title would consider appropriate for above example?
Thanks in any case to Tutorialzine for the interesting step by step explanation and to let me try above experiment which works with latest WebKit, Chrome, Safari, and somehow with Firefox, I've not tried the nightly, and Opera as well but in latter cases without transitions.
P.S. for those with poor computation performances like me, here there is a fluid concept variation ;-)
Andreas Ritter has managed to encode JPEGs in Javascript. This blog post explains how he did it, shows some benchmarks, and provides a demo and a downloadable library so you can play along at home.
It was surprising that it was that easy to get the first js-encoded jpeg displayed in the browser. Of course I didn't want to stop there. I wanted to optimize things as much as I could to make the encoder fast. This took me several days. I found optimized encoder versions for flash and haxe floating around the net (Faster JPEG Encoding with Flash Player 10) and tried the optimizations used there in my javascript version. As you can seen in the benchmarks below I was quite successful.
Another idea was to use the new web workers to do the heavy lifting in an separate thread, not blocking the gui. This is something flash can't do. So I created a version using a web worker for the encoding.
The API gives you a JPEGEncoder or an alternative JPEGEncoderThreaded. Usage is straightforward:
var JPEGImage = myEncoder.encode(CanvasPixelArray,[quality])
I think the results show that JavaScript is quite fast (at least in Safari and Chrome). A little over 4 seconds for the non-threaded version is a very good [sic] result, when compared to the 3,3 seconds the optimized flash jpeg encoder takes. Please note, that JavaScript has no static types, no byte array, no Vector-class and is not pre-compiled. Taking these facts into account Nitro and V8 are faster than the ActionScript 3 VM.
Comparing the different browsers Nitro and V8 are a magnitude faster than TraceMonkey. Firefox 3.6b2 shows some improvements, but it's still a long way. Probably the Mozilla guys should consider adopting Nitro or V8?
Phil Rabin of CBC Radio 3 has kindly written a guest post on his experience creating a fantastic Web interface for the station that uses Flash for audio, but a full HTML experience that maintains state from page to page.
CBC Radio 3 is a community, radio station and user-generated independent music library which is a small department of the Canadian Broadcasting Corporation. When the CBC Radio 3 web team was called upon to rebuild the site we were confronted with the technical problem of having an uninterrupted music experience for our users. The old design of the site (see image) achieved this by embedding a flash player in the body with the content being served through a statically positioned iframe in the center of the page. Radio 3's content offerings were outgrowing the design so we went with a full page 1000px-wide layout with the player resting in the page. This created an obvious hurdle being that with a fresh page load comes a bad listening experience like myspace where a single wrong click breaks the audio. Also, not having popup player was a design decision that was made to give the website a more integrated feel.
We decided to completely removed flash from the UI equation and went full html/ajax because we found that it offered more flexibility and play with the page. The hardest part was figuring out a way to maintain state on each page load while keeping the audio continuous.
We went with an old-school frameset to create a type of inter-frame communication with the top level frameset acting as the orchestrator/bootstrapper. The visible "UI Controller" frame is completely blown out with the stateful player frame hidden from view.
The stateful player frame contains hidden swfs to handle playing audio and connecting to RTMP for our live streaming. All the communication in and out of flash is handled by a couple gateway javascript classes to abstract out the flash from the rest of the application.
Here's an example of a communication gateway for wrapping the events coming to and from flash. The event objects are native flash event objects that get sent by Flash's ExternalInterface and come in as JSON that can:
An instance of the gateway has to be maintained by the player application because events coming from flash have no context. This way the application classes can subscribe to events coming from flash like this:
At the core, audio is always played by Flash. The swfs broadcast events, such as audio head position and download progress of mp3s, and connection, streaming, meta data events from RTMP. Those events get passed on the instance of the hidden stateful player.
Since the server frame is only loaded once when the site first loads, an instance of the stateful server player is instantiated for the entire session on the site. On each client frame page load, the server player instance is "injected" into the visible client UI controller by the "bootstrapper" top frame. State is maintained in that instance which allows for the controller to query the state of that object and reestablish everything like which track is playing, progress, time, thumbs up or down status, shuffle, play mode (stream or individual mp3 and playlists), etc. Everything had to be covered like if an mp3 was in mid-load when someone browsed to a new page, the loading progress had to pickup on the next page. Here's a example of the bootstrapper code contained in the frameset:
We used Prototype/Scriptaculous as the base for the entire site. All the AJAX communication is handled with asp.net web services with scripting enabled. ASP.NET takes care of all the serialization of DTO's (Data Transfer Object) into JSON which are specific to the player application.
All of the classes in the application are written using Prototype's Class/inheritance model. Most of the classes subclass from a base EventDispatcher much like AS3, which is adapted from Matthew Foster's example for Prototype and our own custom Event model. This allows for a nice separation of concerns and decoupled classes throughout the application and allows the UI Controller to add event listeners to custom events coming from the server player instance.
for(var i = 0; i <this.listenerChain[type].length; i++)
if(this.listenerChain[type][i] == listener)
this.listenerChain.splice(i, 1);
},
clearEventListeners:function()
{
this.listenerChain = {};
},
dispatchEvent:function(type, data, target)
{
var event = new CBCR3.Commons.Event(type, data, target || this);
this.buildListenerChain();
if(!this.hasEventListener(type))
returnfalse;
this.listenerChain[type].any(function(funct){
return(funct(event) == false ? true : false);
});
}
});
This also allows the UI Controller to unsubscribe from all events when the page unloads. This was key in memory management and so that we don't get orphaned references to instances of the UI Controller.
The most difficult part of the whole player project was re-establishing state of the controller on every page load. We hoped that we could implement some sort of state-pattern with no luck. In the end, the UI controller contains a couple monster resume methods that we haven't been able to abstract out of that class. We'd like to bring in some sort of MVC architecture that wires up the UI player view to a state object. Any suggestions would be welcome! Go check out the site and give us some feedback!
Dion: I then asked Phil about the CBCR3 library and he replied
CBCR3 is the base namespace for all th javascript controls and apps written for the site. Everything for the player is in CBCR3.Player, the concert calendar is CBCR3.Gigs, etc. We have a shared base lib which is in CBCR3.Commons.
An issue with Prototype that we had was some bug with including 1.6.1 in a frameset in Opera. So, right now the frameset is holding an older version of prototype while the frames have the latest. One thing that Prototype was seriously lacking was Date extensions. (like addDay, addMonth, addWeek) etc.
We ended up going with YUI's DateMath widget for that which really smoothed out working with dates.
Most of the issues we had cross-browser stuff was with IE6 (no surprise), which were almost all related to CSS rendering bugs, and IE DOM manipulation problems. A big one was upon the dynamic removal of items from lists. IE has a real hard time refreshing the positions of items. We had to write methods like
this would in effect "nudge" the browser and force it to update the position of the remaining DOM elements. In the end, we chose to drop IE6 support and to tell you the truth, we haven't heard a single complaint about it!
Node’s core APIs are pretty low level—it has HTTP client and server libraries, DNS handling, asynchronous file I/O etc, but it doesn’t give you much in the way of high level web framework APIs. Unsurprisingly, this has lead to a cambrian explosion of lightweight web frameworks based on top of Node—the projects using node page lists a bunch of them. Rolling a framework is a great way of learning a low-level API, so I’ve thrown together my own—djangode—which brings Django’s regex-based URL handling to Node along with a few handy utility functions.
Pretty simple, and gets a whole lot more interesting when he shows how to build a simple Comet server with this API. He also covers database access, where there's a good fit between server-side Javascript and the NOSQL servers that speak HTTP and JSON.
His article also provides a nice overview of Node itself, along with some straightforward install instructions.
At first glance, Node looks like yet another take on the idea of server-side JavaScript, but it’s a lot more interesting than that. It builds on JavaScript’s excellent support for event-based programming and uses it to create something that truly plays to the strengths of the language.
Node describes itself as “evented I/O for V8 javascript”. It’s a toolkit for writing extremely high performance non-blocking event driven network servers in JavaScript. Think similar to Twisted or EventMachine but for JavaScript instead of Python or Ruby.
Posted by Michael Mahemoff at 9:53 am Comment here
Brian LeRoux of PhoneGap/Nitobi fame, has taken a lighter couch outside as he announces Lawnchair that aims at being applicable for mobile Web usage (but can of course work anywhere else):
Features
micro tiny storage without the nasty SQL: pure and delicious JSON
clean and simple oo design with one db table per store
key/value store.. specifying a key is optional
happily and handily will treat your store as an array of objects
terse syntax for searching and therefore finding of objects
Normally we use CSS selectors to find and tear apart HTML. Sergey Chikuyonok's jujitsu move is to do the opposite. With Zen Coding you take a CSS selector like this:
Just in time for Thanksgiving is another SVG Web release. The SVG Web project's tradition is to name SVG Web releases after monsters from D&D just to increase the geek factor, so in that spirit their release name this time is "Gelatinous Cube":
The Gelatinous Cube is a truly horrifying creature:
A gelatinous cube looks like a transparent ooze of mindless, gelatinous matter in the shape of a cube. It slides through dungeon corridors, absorbing everything in its path, digesting everything organic and secreting non-digestible matter in its wake. Contact with its exterior can result in a paralyzing electric shock, after which the cube will proceed to slowly digest its stunned and helpless prey.
Fun times.
Highlights of this release:
Loads of important bugs fixed
Performance improvements
You can now dynamically create new SVG root tags
All the namespace aware functions now implemented: setAttributeNS, getAttributeNS, etc.
You can now clone SVG nodes (cloneNode)
You can now right-click on the SVG when using Flash to view the dynamic updated SVG source
Running getElementsByTagNameNS scoped to a particular node now works, such as myGroup.getElementsByTagNameNS(svgns, 'text')
SVG Web is a JavaScript library which provides SVG support on many browsers, including Internet Explorer, Firefox, and Safari. Using the library plus native SVG support you can instantly target close to 100% of the existing installed web base. SVG itself stands for Scalable Vector Graphics, an open standard that is part of the HTML 5 family of technologies for interactive, search-engine friendly web vector graphics.
Simon Willison snuck in a last-minute topic change, and is now going to give the server-side Javascript talk.
The news of the past 24 hours is ChromeOS. For the first time in years, someone's re-thinking how an OS should work. With Chrome, you turn on your computer and you're in the browser. What's really interesting is to contrast it to the introduction of the iPhone, where Apple's apps used native APIs while they expected developers to write web apps running in the browser with limited abilities. Here, Google's apps are using the same web platform...it's a level playing field.
Javascript combined with JSONP makes it real easy to write quick and dirty apps. An example of a quick app is Tweetersation Simon wrote with Natalie Downe. Simple app, 200 lines, written in an afternoon. At a larger system level, there's Google Moderator, which is essentially a pure-Javascript solution with a no-op in the noscript tag.
These pure Javascript apps are great for experimenting and prototyping. The problem with this style of development, though, is you're completely breaking web standards. The web Simon "felll in love with" is one where you point to a URL and you get content coming back.
With server-side Javascript, we can get the benefits of the things we like about Javascript, but without throwing away with the things we like about the web. Simon has been playing with node.js, and evidently the results were important enough to throw out the old talk and make this new one.
Take a step back and look at the interaction patterns with a web server. The conventional model is straightforward request-response, where the server tries to respond and disconnect as quickly as possible. But ... there's also the event loop model. As in Comet; it's generally considered to be more efficient, so why do web developers avoid it? Simon says traditional server-side languages aren't designed to deal with event-driven programming. It's more like "do A, do B, do C, exit". Javascript, on the other hand, is well suited to do callback-driven event programming.
Brave Simon now proceeds to live code with node.js. He shows a "Hello World" daemon, where the code looks like Ajax in reverse, and runs extremely fast. But where it gets really interesting - and useful - is with Comet. Another demo. The code is tiny and the benchmark looks good.
Simon's built his own framework on top of node.js: Djangode takes the best features from Django and sticks them on the server.
The more interesting example is Comet, which he's demo'd here.
Moving on to persistence, there's the NOSQL trend of the past 18 months, and he shows how simple it is to write CouchDB queries from node. It's easy to talk to CouchDB from Node.js apps. Redis is another interesting database, which could lead to pages being rendered very quickly, given its performance benchmarks.
Posted by Michael Mahemoff at 12:41 pm Comments Off
Jake explains no-one likes waiting, and people are multi-threaded (except when they have to sneeze). Yet, we're stuck with a single-threaded language for the most part; and we still face the legacy of a DOM standard from another era (DOM Level 1 - 1997). This talk provides some optimisation tips, backed by Jake's cross-browser experiments.
Jake explains the importance of speeding things up where it really matters.
Doug Crockford has pointed out that in Javascript, bitwise operations aren't close to the hardware, which stands in contrast to other languages. In fact, if you look at it, bitwise operations can still be faster than alternative operations; Jake shows an example where bitwise parsing of hex codes is faster than bitwise. The question is, how much faster? In many cases, such as this example, your energy is better spent on optimising big things.
Avoid eval() Where Possible
Jake says avoid eval() where possible. Thinking about what functions eval, here's a brain teaser: what will the following output?
Wait for it ... the answer is "undefined". Javascript does look ahead and create space for the local variable. So during the running of the function, there's no need to allocate space for the variable and the browser can optimise for that, but if you use "eval", the optimisation goes away. So avoid eval().
Prefer innerHTML to DOM
Jake shows a comparison of innerHTML versus DOM Level 1. In IE, DOM manipulation is much slower, because of the sync process between the two. The differential gets even worse when creating elements. Webkit has optimised sync between HTML and DOM, hence less difference, so it's not as bad, but create example is still slower with DOM. So from a performance perspective, best practice is construct the HTML and use innerHTML.
Selectors
It's educational to look at the implementation of selector libraries. Jake shows a comparison - IE7 is vastly more slow in this case. It doesn't support getElementsByClassName, querySelectorAll, evaluate; and it does support getElementById, but that's not used by sizzle for this query. So getElementsByTagName is all that's left; and if you knew that, and the implications, you could have made the query much faster.
Todd Kloots is talking accessibility and ARIA, with examples showing how YUI nicely supports these techniques. He explains how to improve in three areas: perception, usability, discoverability.
Can We Do ARIA Today?
Yes.
Firefox and IE (he didn't say which version) have really good support for ARIA. And Opera, Chrome, and Safari. Likewise for the screenreaders - JAWS, Windows Eyes, NVDA - also have good support. An the libraries - YUI, Dojo, JQuery-UI - all have good support baked in, one of the benefits of using ARIA is automatic support.
Improving Perception - ARIA and Screenreaders
Websites can have problems in perception when rendered with a screenreader; it's hard to get the big picture about what the words refer to. With ARIA, we can close the gap in perception. This is another example of progressive enhancement - augment the item by adding properties, markup or Javascript if required:
node.role = "menu"// alternative introduced by IE8. IE-only, so don't use!
Improving Usability - Keyboard Focus, ARIA, and YUI support
Keyboard access. For some people, it's a necessity, and for others it's still an option or preference (think Vim). To support it, you must be able to tab to the element to get focus, so you should control tabbing with tabindex. A good application of controlling tabbing is, amazingly enough, moving through tabs. Another is modal dialogs; the browser doesn't "know" it's modal, so we have to control focus to make sure it doesn't slip out of the thing that's the only thing users should be able to click on!
Todd shows us just how many steps are required to perform a task in a complex application like Yahoo! mail, using just tabs to navigate through - 19 steps in this example, walking through the toolbar; and even more, when you consider the wider picture of entering the app in the first place. To help with this, he introduces a pattern whereby tabIndexes are updated dynamically to control what comes next, as you move through a toolbar. A negative tabIndex will ensure the element is skipped over.
You can also use the "focus" pseudoclass to ensure focus appearance is consistent for all elements. But, and it's a big one, it's not very well supported; even IE8 doesn't support :focus on <a>, for example. Doing it manually with Javascript has problems, in particular performance. Fortunately, PPK has worked out how to handle focus and blur with event delegation, so that it's much more performant, and the resulting technique is built into YUI3.
Device-independence with markup was also advocated to further improve accessibility:
Essentially, this is about "random access" and keyboard shortcuts; jumping straight to areas in this page and activating them. The key ARIA feature here is "landmark roles" to identify particular points on the page. This is still something where users aren't aware of the feature, and Todd points out it's not surprising as most screen reader users are self-taught (just under 75% according to the study he showed). Also, not every user is a geek, and the same applies to screen-reader users.
Stuart Langridge introduces us to some of the up-and-coming features we're getting with current and future browsers, a nice complement to Robert Nyman's talk, which covered the advanced features of "mainstream" (IE6-compatible) Javascript. After introducing the features that are there today, he also talks about how we can deal with the browser many of us are still having to support.
The Goodies
Here are some of the things we can look forward to. (Having been part of the large crowd who charged the pub across the road at lunch, I was a bit late getting back, so I missed one or two of these.)
list.filter()// find elements in the list that pass the function
list.map()// apply function to each item
It takes a mental shift to start taking advantage of features like this. "Certain browsers" *cough* don't yet provide these conveniences, but you can take advantage of them straight away. Or another example is the base2 library - use it now and you'll be ready for the time when it's present in all browsers.
Getters and Setters
As our Javascript apps get increasingly bigger and more complex, we need to borrow principles, patterns, and techniques from "real programming". Getters and setters are the kind of thing we'll need more of. More generally, we'll need to be in the mindset that we're building APIs to components, which others might use; not just an individual making a one-off web app. Stuart shows a couple of techniques for getters and setters: (a) manually defined; (b) using
Storage
We can now do global storage - globalStorage works similarly to cookies. "Like cookies turned up to 11".
You can use these features now if you're in a single-browser environment that supports them: app for one mobile; Air app; intranet app (where you've amazingly got Firefox exlcusively on your intranet); HTA. This isn't the sinful act of coding to weird proprietary APIs; it's coding to browsers that happen to support the technologies of tomorrow, today.
The libraries help us get to the future today, as long as they can support APIs compatibly across all the browsers. But it's all a little difficult when the market leader doesn't play ball. Hopefully, Dean Edwards will continue working on Base2 to plug the gaps, but we still have the problem. Around a year ago, it felt like the anti-IE6 might be at a tipping point, but that's died down a bit, and it's not clear how much longer we'll be held back.
What can you do then with IE6? If a number of major websites really held back and stopped supporting IE6, Stuart reckons corporations would upgrade. Imagine what would happen if Google stopped working on IE6...immediate upgrades. Show of hands indicates perhaps 20% of the audience would agree to mass dropping IE6 on their public sites. In Q&A, Stuart later clarifies he's not really proposing an IE6 shutdown switch, more like a helpful suggestion to upgrade.
Silverlight and Flash. Proprietary, not open. If everyone started using Flash, the future is Adobe's future. Let's make it our future instead - we're building the open web. A call to arms for showing strength in numbers.
PPK talks up the excitement of mobile web development, then brings the mood down a notch by listing the overwhelming array of browsers to be targeted! Quirksmode says it all. This talk is about quirks in mobile development, and some of the solutions out there.
Mobile CSS Quirks
So many platforms. Take just WebKit; there's iPhone Safari, Android WebKit, Bolt, Iris, different versions, etc. "If someone says my 'app should work in WebKit', laugh in their face. There are just too many versions of WebKit, so as PPK says it, there really is no "WebKit for mobile".
That said, it's good that things are starting to converge towards WebKit. As for the others: Blackberry browser "is dead" as they'll be switching to WebKit; Mozilla is very late to the game; NetFront "is not very good". Windows Mobile 6.5 is a big improvement on 6.1, and with an improved browser, but it's still IE6 based. ('Nuff said.)
There's also a large legacy share, and if users are used to it already, that may be what they want to keep using.
Landscape versus profile mode is an interesting one for those of us desktop developers whose users don't flip their heads around on a regular basis. NetFront has some very surprising and idiosyncratic ways of dealing with it.
The modes don't stop there. There is also mobile versus desktop mode in some browsers; sometimes users can switch these in some obscure corner of their mobile browser preferences. Again, some surprising things happen in Opera and Android. Perhaps of more concern is the difficulty he had diagnosing the situation at first, when Android was showing three divs of the same width in one mode, and not in the other.
@media to the Rescue
Okay, what can we do about all this? Media queries are extremely useful and fairly well supported in modern mobile browsers.
max-width and min-width have subtle issues which PPK is currently researching, but max-device-width and min-device-width give more reliable results. orientation, aspect-ratio, and dpi (also needs research).
Mobile Javascript
Performance-wise, IE Mobile and Blackberry extremely slow. iPhone is middle ground. The really fast browsers are Opera on Samsung and N97, and S60 on Nokia E71 and N97. The bottom line is take your time with mobile Javascript development; you generally can't expect it to "just work"; you'll have to optimise. Also, don't use iframes - they're major performance hogs.
Mobile Connections
Tempting fate, PPK informs us that if someone in the room starts downloading movies, the network gets slower for the rest of us.
Fortunately, browsers give us events to determine when user is going online and offline. Unfortunately, they're doing it wrong. Only Firefox automatically detects offline; all the others require the user to explicitly say "I'm offline now"!
W3C Widgets
In general mobile development, best practice is to put all the core files on the moble phone, and only download the data. But how can we do that with web apps, where the code comes down with the data? W3C widgets offer a solution. You just create a single HTML page with the CSS, Javascript, and images you need; add an icon and config; zip it up; and deploy. PPK reports it works in practice, and works in a "write once, run many" fashion. There are still problems to be sure, but he says it's the best interoperable solution we have today. But still many outstanding platforms: Blackberry (already talking about it), Nokia Maemo, Palm Pre, Android, and of course, iPhone.
Device APIs
Security risks mean critical device APIs will generally remain off limits to general websites for a while. Widgets have a better model, because they're more self-contained and can be verified, although not perfect either.
Posted by Michael Mahemoff at 7:58 am Comment here
Robert Nyman walks through some of the more subtle low-level features of Javascript, and some of the idioms that have emerged.
Comparisons: Understanding identity (===) versus equality (==).
Boolean expressions: Understanding how short-circuit logic (if a && b won't eval b if a is false);
Types: Type coercion ("1"+2+3); "falsey" (false, null, 0) versus "truthy"; the importance of using operators like parseInt and instanceof.
Functions: Anonymous functions; self-invoking functions - function() { })() ; using the arguments collection to get all arguments to the current function, important to note it's not a real array with all the array methods, and using arguments to overload arguments.
Objects: Using object literal notation { a:b, c:d } instead of setting up properties individually; equivalence of ben.arms and ben["arms"], and how useful it can be to use the latter in conjunction with a function argument, ie let the caller pass in a variable which will be set; using "in" to check if a property exists (if "arms" in ben).
Inheritance: Using the prototype chain for inheritance from subclass to superclasses up to Object. There are various implementations - e.g. Resig, Edward's Base, Dan Webb; if you understand these implementations, then you understand Javascript. However, Robert's arguing for the native way of doing it - as Doug Crockford says, "I now see my early attempts to support the classical model in Javascript as a mistake".
Global scope: Avoid using global scope where you can. For example, nesting functions. R
obert later points to the Yahoo! module pattern.
Binding this: Using call and apply; these are useful for setting this and also can pass arguments through from the current function to another one without having to manually copy them out.
Sugaring: Adding syntax sugar, e.g. extending String.prototype.
Currying: As illustrated by Doug Crockford's curry implementation.