My live notes from John Hann’s 25 August 2010 presentation on modern JavaScript frameworks to the New York JavaScript meetup.

Modern JavaScript frameworks rock! Dojo, jQuery, MooTools, Prototype… alleviate us from browser quirks so we can concentrate on coding awesome web sites. But none of these offer any guidance whatsoever—and hardly any tools—for building enterprise-worthy, ultra-rich web applications. It’s just too easy to create inflexible, unmaintainable spaghetti code.

A few Javascript-based, in-browser Model-View-Controller endeavors have popped up to help provide solutions. Most of these are simply rehashed server-side MVC frameworks. They just don’t get it. MVC sucks for web development. The bigger the project, the worse it gets.

Cujo.js was specifically designed to eliminate these inter-dependencies. Yes, it’s an MVC framework, but it’s different…

The above slides are from a presentation on Cujo.js, but are not the slides to this presentation.

cujo.js: A sneak preview

John Hann
@unscriptable
lifeIMAGE, Inc.

cujo is about building ultra-rich web applications.

What is an ultra-rich web app?

  • Feature-rich
  • Single-page app (“spa”)
  • Desktop-like
  • You “live” in the app

Examples: lila Inbox, meebo, Gmail, Google Docs, Facebook

Why would anybody want to build a spa?

  • Responsiveness
  • Mobile (HTML5 apps, Phonegap)
  • Cross-platform
  • Vendor-agnostic
  • Auto-update
  • Offline
  • More responsiblity to client (more clients), less for server (fewer)

The rise of the JS libraries

  • Prototype
  • Dojo
  • jQuery
  • Mootools
  • Mochikit

Why JS libraries?

  • Browser abstraction
  • Language abstraction
  • Plugins, components, widgets

All the node-wrangling tools to build all ultra-rich applications.

However, 5,000 lines of tangled JavaScript later, what the heck happened?

It’s your nodes, dumb-ass. Stop fiddling with your nodes! Building an ultra-rich app requires software engineering.

We’re building desktop applications on the web.

Why can’t I just fiddle with my nodes?

  • Bigger app
    • More complexity
    • More code
    • More coders
  • Complicating factors:
    • Customization
    • il8n/L10n
    • Authorization
    • Animation

How to uncomplexify?

  • Modularization: “Think tiny”
  • Encapsulation: Don’t touch my coadz
  • Loose coupling: I won’t touch your coadz
  • Reuse: Don’t repeat yourself
  • Separation of labor: Mind your own biz

Does $() help?

It doesn’t

3rd-party solutions help Dojo and YUI do more than jQuery, but not enough.

Don’t believe me?

Does $().fn help modularize my CSS?
Does dojo.connect() protect my code?
Does $().live respect my widget’s personal space?
Does $.extend help me reuse HTML?
Does $.animate coordinate nicely with my CSS designer’s CSS files?

Animation is not behavior—belongs with designer (CSS3 transitions)

Cujo is built on Dojo.

Dojo MVC?

models, views, controllers…

Why is cujo.js moar?

Data flows magically between nodes & server.
Template languages disappear (and so does the ID attribute!)
Views invoke the …

Dojo 1.6 data stores are hawt!

Data stores are data models. Most handle client-server communication so you don’t:

  • json
  • json-rest
  • couchdb
  • flickr
  • google
  • csv
  • xml
  • atom
  • etc

Data binding provides the “last mile.” (Dojo 1.6 will provide data binding). The end result: “live” data. As live as you want it, anyway.

What template language?

Why use a {{template language}}? HTML5 data-* attrs FTW!

inheritance: data-cujo-override
loop*: data-cujo-iter
conditional*: data-cujo-if

“oohtml,” anyone?

The “holey” web trinity

oojs + oohtml + oocss => cujo.mvc. View complete module, yet still overridable.
my/HawtWidget.js (aka “view-controller”):
dojo.provie(‘my.HawtWidget)
cujo.requireCss()…

Ancient browsers grok CSS2.1 & CSS3

Once you take control of the stylesheets, the sky is the limit.

Ever wish this worked in IE6?

  • Two selectors (chained) on an element: .myWidget.selected
  • child selectors
  • Transitions

Moar modularization

JS, CSS and HTML as a single unit is easier to create, test, maintain and extend.

dojo.provide('mgp.view.logo');
cujo.requireCSS('mgp.view.Logo');
cujo.requireHtml('mgp.view.Logo');
dojo.require('cujo.mvc.View');
dojo.declare('mgp.view.Logo', cujo.mvc.View, {…

Moar encapsulation

Self-contained, “black boxes”

Minimize cross-dependencies.
cujo.js mixins FTW!
cujo._Connectable limits dojo.connect()
cujo._Settable limits dijit’s set()

Moar loose coupling

It’s good to be loose and ignorant of your own parents! Cujo emphasizes:

  • doj.connect
  • dojo.publish/dojo.subscribe

Moar reuse

Just say no to copy-and-past coding practices.
Increase maintenance
cujo.js embraces OOJS and OOCSS.
Adds OOHTML
OOHTML enables OOCSS (automatically applies inherited classes)

Jon Hann gives a strong endorsement of OOCSS. Learn it

Moar separation of labor

$.css() and $.animate are the CSS designer’s job. Layout is also the CSS designer’s job.

Get over it.

Moar about view state

Classical OO inheritance: Descendant classes inherit attributes and behavior.

Pure prototypal inheritance: Descendant objects inherit attributes and behavior.

OOCSS: Descendant objects inherit attributes and run-time state.

When can I haz Cujo.js?

Cujo.js is in stealth mode while we test moar browsers, finish features, document and clean-up code. Release 0.1 on Github around 15 September 2010

http://cujojs.com/
http://twitter.com/cujujs

Q&A

Q: Some people think these frameworks proscribe too much.

A:Possibly went too far the other way. Can define and extend. Theming. Don’t want to use the templating language, can pull in your own.

Q: What is the performance overhead?

A: Two aspects: load-time. Actually processing CSS at load-time. Do a lot of feature detection, not browser-sniffing, so difficult to do that build time.

Q: You mentioned how Facebook was different in the beginning?

A: FB only loads 3KB of JS and that 3BK is responsible for loading and running the rest.

I woke up this morning to discover that Paul Irish had left a comment on one of my GitHub commits:

A user reported that this actually didnt work.. the ie=edge never jumped ie8 into standards mode..

did you see it succeed?

Hmm… this didn’t sound good. The error in question was on our HTML5 template for The Knot. We had wrapped the X-UA-compatible meta element with an IE conditional comment. I don’t remember exactly why we did this, but I think it had something to do with HTML validation.

Now, I know that HTML validation doesn’t matter (see also “The value of HTML validation”), but I do like using it as a lint tool (and yes, I prefer to just see a green favicon in the title bar). However, I also understand that pages don’t have to validate in the wild and I had never actually tested wrapping the X-UA-Compatible meta element with a conditional comment. I just assumed it would work, because, well, why shouldn’t it?

Damn. Once again, I learn the value of assumptions. It turns out that the way it’s coded doesn’t work. IE8 completely ignores the X-UA-Compatible meta element. Since I recently read about conditional comments blocking downloads, I was curious if this had anything to do with it and if the solution I had settled on for that problem would also help with this one. Voilà!

Since the download blocking also affects conditional comments around the body element and I wanted to avoid putting an empty conditional comment in the head, I moved the conditional comments to the html element. This solution also causes the conditional X-UA-Compatible meta element to be seen by IE!

UPDATE: There is one problem with this technique: it breaks Google Chrome Frame. Chrome Frame ignores IE conditional comments, so it never gets invoked. If you want your page to work with Chrome Frame and you want it to validate, send an HTTP header. If you can’t set the header, don’t wrap the meta element with conditional comments. Besides, validation doesn’t matter anyway, ;) .

<!--[if lte IE 6 ]><html lang="en-us" class="ie ie6"><![endif]-->
<!--[if IE 7 ]><html lang="en-us" class="ie ie7"><![endif]-->
<!--[if IE 8 ]><html lang="en-us" class="ie ie8"><![endif]-->
<!--[if !IE]>--><html lang="en-us"><!--<![endif]-->
<head>
	<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge" /><![endif]-->
</head>
</body>
</body>
</html>

Tests

  1. IE=7. Works!
  2. IE=edge. Works!
  3. IE=edge wrapped in conditional comment. Does not work!
  4. IE=edge wrapped in conditional comment with conditional comments around the html element. Works!

Notes from John Brooks’s (The Knot) presentation on the HTML5 WebSocket API to BK.js, the Brooklyn JavaScript meetup.

HTML5 WebSockets

Full-duplex communications channel that operates over a single socket and is exposed via a JavaScript interface in HTML5 compliant browser.

  • Stuff will change
  • I want stuff to change
  • I want changed stuff to be cheap

So it’s like Comet and Ajax.

Unlike WebSockets, Comet and Ajax are not native to browser and rely on maintaining two connections—one for upstream and one for downstream.

WebSockets are really simple.

Well, technically XHR is native to the browser, but with WebSockets, avoid headers and multiple requests.

Current state of things:

  • Polling

WebSockets will reduce traffic and overhead.

var webSocket = new WebSocket('ws://172.16.3.86:8080/time');
webSocket.onopen = function(event) {
     document.getElementById('element;').innerHTML = 'Waiting for socket';
     webSocket.send('start');
}
webSocket.onmessage = function(event) {
}
webSocket.onclose = function(event) {
}

What do you do when a browser doesn’t support WebSockets? Can fake it with Flash and Silverlight.

Current browser support for WebSockets: Chrome

Things are a little different on the server-side; server will need to become event driven. Node.js.

Questions and Answers

Chrome 6 broke backward-compatibility with Chrome 5 WebSocket support. Chrome 6 seems to be the reference implementation.

What is security? Port? Same origin policy? Port 80.

Firewall issue is why some people are pushing for TLS.

Google SPDY protocol brought up. Similar to HTTP, but a different protocol. Will it be blocked or dropped?

SPDY permits multiplexing, but faces the same problem as all protocols based on TCP/IP.

HTTP permits six connections and is faster on page load. SPDY gains performance on other issues (multiplexing and …)

The following answers are to the exercise questions at the end of “The history of the Internet and the web, and the evolution of web standards” by Mark Norman Francis, which is article two in Opera’s Web Standards Curriculum.

Question one: What browsers are available on the Internet today for users of Windows, Mac OS X and Linux? and question two: What percentage of web users use each browser?

I’m going to answer both questions at the same time by providing a table that lists the current “major” browsers, their version number, operating platform(s), Acid3 score and market share.

Browser Version Operating system(s) Acid3 score1 Market share2
Chrome 5.0.375.125 Windows, Mac OS X, Linux 100 7.22%
Firefox 3.6.8 Windows, Mac OS X, Linux 94 22.92%
Internet Explorer 8 Windows 20 60.66%
Konqueror 4.4.5 Windows, Mac OS X, Linux 89 <1%
Opera 10.60 Windows, Mac OS X, Linux 100 2.44%
Safari 5.0.1 Windows, Mac OS X 100 5.11%
1
Acid3 scores are out of 100. For more information on Acid3, see Wikipedia.
2
Market share for Q3 2010.

Question three: What browsers do mobile devices use when accessing web pages?

The top eight mobile browsers listed in order of market share:

  • Safari (iPhone, iPad)
  • Opera Mobile
  • Nokia Series 40 browser
  • BlackBerry browser
  • Android browser
  • NetFront
  • PlayStation Portable web browser
  • Polaris browser (Samsung)

How many “web standards” have the W3C published, and which are widely supported by browser manufacturers today?

A lot. Compared to the other three questions, this one is huge and I don’t really want to answer it. So, here is a partial answer of what I consider the “big” recommendations that are widely supported by browser manufacturers to be:

  • HTML
  • XHTML
  • XML
  • CSS
  • DOM
  • DOM events (but not in IE8- :( )
  • PNG (Alpha transparency not supported in IE6-)
  • SVG (Not in IE!)

A complete list of W3C standards and drafts can be found at http://www.w3.org/TR/.

References

  • Browser version, operating system(s) and Acid3 score retrieved from browser-specific Wikipedia pages on 7 August 2010.
  • Browser market share retrieved from NetMarketShare on 7 August 2010.
  • Mobile browser list compiled from StatCounter Global Stats and Wikipedia. Both documents retrieved on 7 August 2010.

I was reading about base64 encoding on Nicholas C. Zakas’s blog and I ended up running across his articles on what makes a good/interviewing a front-end engineer. Zakas expects a front-end engineer to know the following without any outside help:

  • DOM structure—how nodes are related to one another and how to traverse from one to the next.
  • DOM manipulation—how to add, remove, move, copy, create, and find nodes.
  • Events—how to use them and the major differences between IE and the DOM event models.
  • XMLHttpRequest—what it is, how to perform a complete GET request, how to detect errors.
  • Strict vs. quirks modes—how to trigger each and why this matters.
  • The box model—how margin, padding, and border are related and how Internet Explorer < 8 does things differently.
  • Block vs. inline elements—how to manipulate using CSS, how they affect things around them and your ability to style them.
  • Floating elements—how to use them, troubles with them, and how to work around the troubles.
  • HTML vs. XHTML—how they’re different, why you might want to use one over the other.
  • JSON—what it is, why you’d want to use it, how to actually use it, implementation details.

Reviewing this list, I felt pretty confident about most of the items, however Zakas also mentions he expects all answers to not involve using libraries. At this point, I realized that it’s been so long since I handled events or used the XHR API with pure JavaScript, that I probably couldn’t answer his questions. I mean, I remember that IE stores the event information in window.event instead of passing an event object to the handler and that it doesn't support capturing, but I don’t know how to register event listeners with it. Regarding DOM manipulation, I can find nodes using getElementById or getElementsByTagName, but there’s no way I could write Sizzle.

So, I decided it's time I revisit everything I know about HTML, CSS and JavaScript. And, while I do this, everything I learn will be posted here.

Notes from Andreas Grabner’s (dynaTrace evangelist) presentation on the new features of the upcoming dynaTrace AJAX Edition (DAE) 2.0. dynaTrace AJAX Edition is a free tool that provides full JavaScript, network, rendering, DOM and XHR tracing for Internet Explorer 6, 7 & 8. With the latest version, the Ajax Edition automatically analyzes best practices in the areas of browser caching, network resources, server-side activity, JavaScript/Ajax and also provides additional key performance metrics that are essential for tracking the end-user perceived performance of a web site such as time to first impression, time to onload or time to fully loaded.

NY Web Performance Meetup page

Please note these are my live notes and were published immediately after the presentation. Hopefully I’ll have a chance to clean up them up at some point in the future.

Presentation bottom-line: Coming ASAP.

dynaTrace was founded in Austria five years ago. Headquarters in Boston. Started on the server-side. Large clients moving to Web 2.0, so developed dynaTrace Ajax Edition as a free tool. Version 2.0 is in beta, but that is the one that should be downloaded.

Currently works with IE 6, 7 and 8 exclusively. Will hopefully support FF by the end of the year.

Eclipse RPC application. Can set run-time configurations. DAE will launch browser for you. Will replace IE logo in upper left corner. This is how you know it’s the session window. Installs two add-ons to IE.

Everything that is done on the page is recorded. Network activity, JavaScript execution, rendering. Does add overhead to page. If the JS is very heavy, will add more overhead. Variance to overhead: 5-20%. Can turn down the overhead by collecting less data.

Jeans page for Sears took 13-14 seconds from Keynote. Sears unable to reproduce (4 secs). Keynotes uses IE 7 for monitoring, Sears uses IE 8 internally. Accounted for the discrepancy.

blog.dynatrace.com, where Andreas collects these stories.

After collecting data, can switch back to DAE. At top left (under browsers) is the live session. DAE shows all the URLs. Also does ranking like PageSpeed.. Can upload your rankings to ShowSlow

  • Browser caching performance rank
  • Network request performance rank
  • Server-Side performance rank
  • JavaScript/Ajax performance rank

Tabbed interface to each of these ranks. Rank pages provide suggestions similar to PageSpeed and links to dynaTrace’s best practices techniques (also Google and Yahoo!). These are the standard things that most of the service providers do.

The JS tab is where the magic is. Profiler. Shows JS calls, invocations and total time (in ms).

The jQuery class selector is really bad in IE 6 and 7. A little bit better in IE 8. Profile highlights jQuery calls with yellow arrow. Most of the time is spent using jQuery class lookups. If have to do jQuery class selectors, faster to use a tag qualifier: element.className instead of .className.

The more DOM elements and the deeper the nesting, the more expensive the call. If there will be multiple look-ups for the same selector, cache the nodelist in a variable.

These are the keys to IE performance.

The profiler also includes back traces and forward traces. Can really dig down and see what exact calls and the actual JS script that is taking the most time.

The DAE timeline isn’t a network waterfall, but it shows you how long the JS execution took and how long the rendering took. Timeline is color-coded and has nice zoom features. If you double click on a timeline block, will get the pure execution path (“purepaths”). DAE captures the entire trace, which is far more than most profilers.

Everything yellow is DOM. Arrow to left, retrieving property. Arrow down is a method call. To keep the overhead low, doesn’t capture the method arguments and return values by default. If need it, can be turned on.

Various times: duration, JS, total, exec. Duration is the total time in asynchronous path, JS ???, total time is time spent in synchronous path, exec time that was exclusively spent executing. If the time is large, but the exec is low, then need to drill down into the sub-methods called by the original method.

Turns out that manually drilling down is doable, but the tedious way. When click on a node, the contributor node window will show all the contributing methods and can sort by most expensive of calls (sometimes 1,000s of calls). When you get low enough, will probably hit jQuery. The middle window shows the entire stack trace, so easy to move back up to find the call you made that caused the bad performance.

Cannot see into Flash, but can get the network time, rendering time and CPU usage. When you start to use the Flash object, though, it’s invisible unless it downloads more network content or interacts with the HTML page/JS.

In question and answer, turns out that to run DAE for IE and Firefox and to compare them, you’ll have to pay for it. Otherwise it will only support one browser.

Integration with Selenium.

To do a side-by-side comparison, either copy (easy to do) and paste into Excel or else open two performance report tabs and manually bounce between them. To automate it, there’s the commercial solution.

When the browser closes, the live session is moved to the stored sessions. Session name will default to the runtime config, but can re renamed via a right-click.

Can right-click on the timeline and easily access a number of different drill-downs.

Due to limited number of network connections, there can be a wait time before an asset can be downloaded. DAE shows that as well.

By default, doesn’t capture images. Captures the URL and uses a browser component to go out and retrieve it from the web. Captures all HTML, JS and CSS. However, can specify additional MIME types you want captured.

How were they able to capture all this information? A lot of reverse engineering of IE. The rendering information isn’t as detailed as the JS; more difficult to reverse engineer.

Uses a high-precision timer (also used on their server-side product).

In code view, the code is automatically un-minimized.

Resources

Mike Taylor from Tunecore's presentation on using JavaScript to give older browsers new fancy. Mike discussed the tenets of regressive enhancement and then demonstrated how to apply them using HTML5 forms and three jQuery plugins he wrote.

This talk is about the future of HTML and front-end development and ways in which we can plan for the future.

HTML5 (and friends)

  • New semantic elements
  • Canvas 2D context
  • Microdata
  • Cross-document & channel messaging
  • Forms
  • Web workers
  • Gelocation

Talk is not about progressive enhancement, but regressive enhancement. This "philosophy" embraces:

  • Build native experience
  • Feature detection
  • Back-port functionality for crappy browsers
  • Wait for your code to become obsolete

What's problematic about the new semantic elements?

Won't render correctly in older versions of FF and IE (6–8). There's a solution for this, but it relies on JavaScript (Remy Sharp's HTML5 shiv.

Print style sheets won't work in IE. The solution is IE Print Protector. This has been included in Remy Sharp's shiv.

What's problematic about the new HTML5 form elements?

[Mike does a quick demo of the new form elements. You can see that demo here.]

Mike shows the new placeholder attribute: <input placeholder="Ye olde placeholder" />. No need to do hacky script work-arounds anymore.

On to the presentation

Modernizr FTW!

A way to extend Modernizr [I missed the URL].

Mark Pilgrim's Dive into HTML5 has a "guide to detecting everything."

Back to the placeholder attribute. Mike shows some code he wrote to regressively enhance browsers that don't support the placeholder attribute. Uses jQuery to create and position labels off-screen. This does not replace the existing label element, but it adds another label element. The spec clearly states that placeholder is not a replacement for labels. [Would like to actually examine Mike's code (it's a jQuery plugin); I think he's going to post it or send it to the list. It's at Github]

A discussion about styling HTML5 elements. Some people think it's good to be hands-off here. A return to the debates around the file input.

Then Mike turns to the autofocus attribute. Simply a boolean attribute. <input autofocus /> He has a nice jQueyr plugin for this as well.

The last thing we'll be looking at is the datalist element. There are some interesting things necessary to make this work cross-browser. Webkit freaks out on naked option elements, so you have to wrap the options with a select. However, this causes IE to render a select. Gecko doesn's care either way.

Mike created a cool jQuery plugin for this as well. However… Safari 5 lies, because it says it supports the list element when it doesn't. This has broken Mike's working, cross-browser plugin.

But…

Regressive enhancement is kind of a hack. Things can get broken.

Mike's code is at Github

Dean Edwards has a JS library for HTML5 forms that does all of this. It's beta, so we're not supposed to talk about it, but it's a public link on Google Code, so I'm blogging it. Remy Sharp is working on a JS work-around for local storage.

A discussion ensues

Is this good in terms of code maintainability? Is it worth it to invest in this? Why not wait for all the browsers to natively support these things? Where are the big wins? Multiple background-images are win, but are the new semantic elements really worth it?

Actually, have to be careful with some of the libraries and some of our existing "hacks." Some CMS or framework hijacked the required attribute awhile ago and didn't do feature detection. Now that the attribute is part of the spec and is getting implemented, that CMS or framework has produced a broken website in modern browsers.

One advantage of using native browser functionality is that you don't need to test the new form elements in the new browser. The date picker input will just work.

A List Apart's third annual survey:

For the third year in a row, good citizens of the web, we ask that you take a few minutes to tell us about your professional skills, educational background, career prospects, job benefits, and more.

I took it! And so should you. The Survey for People Who Make Websites.

Hue reference chart

Inspired by Molly Holzschlag at Standards.Next, I created a simple hue reference chart for working with HSLA.