making things better, making better things

Friday, December 11, 2009

John Resig on JavaScript testing, performance analysis, and jQuery 1.4

John Resig, of jQuery and other fame, spoke tonight at the BayJax meetup in the Yahoo! cafeteria. His slides are probably online somewhere, but they are lucid, informative, illustrated with pictures and code samples, and written by someone who knows what he’s talking about, not to mention who was paying attention while writing them. (Update: Video on iTunes and not on iTunes.) If that’s not your bag, you’ll want to read my notes instead:

PART I: Testing JavaScript

javascript testing is different from desktop/server testing
- cross-browser issues

there are a lot of javascript testing frameworks!
- long tail
- it’s easy to write one

basic components for a testing framework
- the usual, plus async tests
- minimum: assertions
(‘glorified assertion-and-logging framework’)
- async tests
- pause (stop executing other tests) and resume

why write your own?
- a good way to understand what testing is for
- not too many cross-browser issues

popular frameworks:
- (none)
- JSUnit
- 2001, and looks it
- YUITest
- good code, supports async tests and event simulation
- (looks like nested contexts?)
- QUnit
- async testing, test timeouts
- no dependencies
- easy to use
- FireUnit
- firebug extension

- CommonJS: standard API across client and server environments
- including testing API, now adopted by QUnit (I think)

server-side testing of client-side code
- usually Java + Rhino
- Crosscheck (Java)
- Env.js (pure JS)
- BlueRidge (Env.js + Screw.unit + Rhino)

browser launching
- WebDriver (Java)
- Watir (Ruby)
- JsTestDriver (Java)
- Selenium RC (Java)

distributed (for scale)
- Selenium Grid – on Amazon servers
- TestSwarm – crowd-sourced

PART II: Accurately Measuring JavaScript

major use cases:
- same code, different platforms
- which browser is fastest?
- different code, same platform
- which framework is fastest?
- how should we implement this?

same code, different platform
- SunSpider (WebKit), V8 (Chrome), Dromaeo (Mozilla)

… statistics…

error rate
- faster tests => less accuracy
- faster *browsers* => less accuracy
- dromaeo/v8 test runs/sec instead of msec/run
- use harmonic mean to average

different code, same platform
- most solutions are bad
- few runs, inaccurate
- garbage collection
- use mode instead of mean
- less accurate than mean, but more consistent
- don’t discard “bad” results – GC is significant
- may reflect memory issues
- getTime() “very very imprecise”
- 15ms intervals on XP (except FF/Chrome)
- IE in Wine gives you precision, but it’s not IE on Windows

- browser tools
- Safari, Firebug, IE 8 profilers
- DynaTrace Ajax for IE 6-8
- Shark – watches internal function calls

PART III: jQuery 1.4
- complexity reduction
- bubbling change, submit, focus, blur
- required script loading

analyzing performance
- stop measuring absolute execution time
- improve code quality and flow

complexity analysis
- count function calls instead of seconds
- may indicate not slowness, but poorly written code
- remove() did a lot more work than it needed to
- and so did everything that used remove()

event bubbling in IE
- focus, blur, change, and submit don’t bubble
- alternative solutions: piggyback on events that DO bubble
- focus/blur: use focusin/focusout
- submit: watch for click… or ‘enter’ keypress…
- change: basically reimplement the whole event
- track previous value
- watch for keyup navigation, checkbox clicks
- beforeactive on radio buttons

- don’t try to load a script multiple times
- load synchronously if needed for dependent code
- load asynchronously if you can get away with it!

URL mapping
- require(‘ajax’) => ajax.js
- namespaces expand to URLs

PART IV: HTML 5 Elements in IE

problem #1
- unknown elements are unstyled, and “inner contents escape”
- fix: document.createElement(‘section’) makes section work
- html5shiv does that for all HTML5

problem #2
- unknown elements can’t hold other unknown elements
- even with html5shiv
- no fix

problem #3
- nodeName of unknown elements is treated as XML
- fix: don’t assume nodeName is uppercase

problem #4
- injecting unknown elements via innerHTML fails
- “fix”: parse HTML and build DOM in JS


… i zoned out…

Q: clojure?
A: framework… okay. compiler… pretty slick!
- but designed to compile your whole application
- can’t compile the framework separately

posted by erik at 11:39 pm  

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress