jQuery Conference '09 @ Microsoft Cambridge: Strategies for Optimizing JavaScript Performance

Table of Contents

Background

jQuery Conference '09 @ Microsoft Cambridge, Boston MA http://speakerrate.com/events/172-jquery-conference-2009 #jqcon

Presentations are available at

http://conslides.org/jqcon09/

http://delicious.com/jwalsh/jqconf

Outcomes

The following should be considered as separate Strategic Technology projects in Q4.

Use data()

Use live()

Use metadata()

Upgrading to 3.x for performance should be a priority

There are no simple answers for performance improvements

Build a front-end infrastructure

Get involved in the community

Day 1

10:00 AM Welcome Welcome and Intro by John Resig (@jereig)

CAMBRIDGE/jquer912

https://members.oreilly.com/account/login Jason Walsh <jquery09@jwalsh.net>

Free copy of books.

10:45 AM Session 1 Recent Changes to jQuery's Internals by John Resig (@jereig)

Description

http://speakerrate.com/talks/1399-recent-changes-to-jquery-s-internals

The construction and build of jQuery has changed considerably over time - even within the past year has the nature of jQuery changed rather dramatically (with the release of jQuery 1.3, 1.3.1, and 1.3.2).

Notes

This is mostly about 1.3.3.

Sniffing and Support

No more browser sniffing; jQuery.browser is now deprecated.

"Deprecated" means a bad practice; not going to be removed immediately but no schedule set.

jQuery.support now offers workarounds associated with MSIE:

  • leading whitespace removal
  • opacity support
  • cloning permanently binds the events making it a "conjoined twin"

The test: A temporary div that that has several quirks for rendering that need to be worked around.

The question: "Do you do this the right way?", if not then do it the IE way.

Can be added as a new support properties associated with the test. jQuery core only has test that they care about.

All of the tests in support aren't lazy loaded since it only takes 4ms to load.

This mechanism for determining the capacity of an individual browser are more complicated than simple browser sniffing; see the documentation.

TODO Modularity and mobile

Now reflects the breakdown in the documentation.

Should make it easier to dyn load other portions of jQuery as needed.

TODO: querySelectorAll w/ find() http://www.w3.org/TR/selectors-api/

Mobile devices would be limited in the types of selectors and filtering that could be applied.

The use of $.getScript() would continue to use async load of modules with function invocation via the callback.

pdk has a mobile chart; conversations between the mobile device providers and jQuery: "Is getElementsByTagName()" required?"

What are the tradeoffs betwen dependency management and being explicit with imports

Is concat the best option for mobile? Almost certainly for desktop.

TODO: cache limits associated with iPhone 3 + Android + Palm

Embedding of jQuery in the browser likely not needed with the proliferation of the use of CDNs that manage the selection of the libraries and stable versions.

TODO Performance

Sizzle uses an optimal approach to finding the particular selection rather than just relying on the right to left browser selection pattern.

TODO: jQuery Stack Profiler http://github.com/jwalsh/research/issues/#issue/21

TODO: FireUnit profile for CMO to determine top load for page.

ECMAScript 5

Look at the requirements for

No anon functions.

Require the use of constructors (i.e., new String; new RegExp)

FF3.5 and Safari support for JSON parsing or the library support of JSON2.js (Crockford).

TODO Unified Syntax

This could be used for how CMO structures the code. Some of the modules may look better than others.

There would now be a coherent set of test that are used for Function and Array (but with some reduction in the checks used for MSIE).

TODO: .selector / .context rsch

look at jQuery.fn.update as an example case.

  • jQuery("div") == jQuery()

Rather than requerying for the document the find() is cached as the root.

  • .first() & .last()

filter(":last") would be much slower than .last() .

  • .data() now provides a coherent dump of all of the data.
  • Document order is now enforced

Performance hit but one of the few libraries are

  • Heights are now assumed
  • $("#id").find("div") is still faster than $("#id div")

This is just just give the speed of the selector in

Check for any use of something like $("div", "#id") which is just weird.

  • append() caches

Now uses fragment caching.

look at aching the same fragment then apply the ids with an attribute.

Caching for very small fragments (250 bytes): this would be something like $("<li>foo</li>").attr("id", "foo" + i).appendTo("ul")

12:00 PM Session 2 jQuery Anti-Patterns for Performance and Compression by Paul Irish (@paulirish) -

Description

If you've seen the results from TaskSpeed, you know that the sexy syntactical sugar of jQuery comes with a few performance disadvantages. jQuery makes it quite easy for you to write some pretty inefficient code, so we'll discuss how to develop in a terse style but with the best possible performance.

http://paulirish.com

Taskspeed was the basic metric; comparisons with other libraries showed that jQuery was the second slowest in 1.3.2.

However, it also took fewest lines of code to create the performance tests.

Recommendations

Standard mechanisms; cache selector, append to fragment outside of the loop.

Use an object literal rather than blocked anonymous functions with callbacks

var CMO = { ruhpInit: function() { }, profileInit: function() { }, }

Don't reselect an append() function for event binding

Use appendTo() with the initial selector then use chaining for the click() bind.

This is just to hold on to a single object. Be wary of not chaining.

Use .find() to reduce rather than context

This is just for readability.

Be aware of selector engines

http://paulirish.com/2008/javascript-css-selector-engine-timeline/

When not in a stylesheet be aware of the differences in the selector engine style; would affect the Souder notes.

Consider just using tag.class on the right side of the selector and just a tag or a class on the left unless the first selector item is an id.

If the first item is just an id consider using the hyper-optimized:

$("#id").find("div")

since this by-passes all of the chunker code and just uses naive browser support.

TODO Never use a universal selector

This is important for :radio without and input as well as $("div > *") for any case.

TODO Evaluate event delegation

If binding an event handler to more than three events consider using live() (contrast with livequery()).

register a selector on $(document).

TODO Remove items from the DOM when manipulating

TODO: jQuery.rule http://flesler.blogspot.com/2007/11/jqueryrule.html

  1. Grab a reference to the node
  2. Remove it from the DOM
  3. Manipulate it
  4. Add it back in

TODO: Determine how to convert this into a static rules for code review.

TODO Use the source as a reference
Make sure you check that there are elements operated on with a plug-in

Put boilerplate at the top of the plug-in definition:

if (!this.length) { return this; } ;

Use YUI compressor (or a compressor)

TODO: Check to see what the static module would want to run or how this is run with the site.

Compressors will really prefer to use consolidated var references:

var foo = 1, bar = 5, baz = "baz";

Would also be applied for things like constants.

var TRUE = true, FALSE = false, NULL = null, undefined, this = window;

This also minimizes the scope chain traversal (see the Yahoo!

Start with <html class="no-js"> to minimize re-flow

TODO: Determine how this could be a performance gain.

Review ternary operators

TODO: Determine why one would use these structures. Seems complicated for passing values from bound && or || checks or from ternary checks.

Rate your compression tool

Alternative: Extending jQuery by Cody Lindley (@codylindley)

Did not attend the presentation on

http://docs.google.com/present/view?id=ah9wk5hqbhww_50f2nb29f9

but it had a nice summary of the considerations when creating a plug-in.

  1. create a private scope for $ (http://jsbin.com/uculi/edit#html)
  2. attach plugin to $.fn alias (http://jsbin.com/uyehe/edit#html)
  3. add implicit iteration (http://jsbin.com/ilune/edit#html)
  4. enable chaining (http://jsbin.com/okifa/edit#html)
  5. add default options (http://jsbin.com/ekogu/edit#html)
  6. add custom options (http://jsbin.com/ulino/edit#html)

Extra credit: global custom options (http://jsbin.com/eliye/edit#html)

1:45 PM Session 3 jQuery UI Widget Library by Scott Gonzalez (@scottgonzalez)

Description

jQuery has changed the way we write and organize code by defining a sane, flexible API for the DOM. However, sometimes the "find elements, do something" pattern isn't what you're looking for.

Notes

$.widget() as a core support system
How do you initialize a widget with state that can be used

What is a widget:

  • something more than simply
  • something that maintains state
Nomenclature
  • Pass in the function name as a param

Use openDiaglog

  • Use prefixes for the UI object type
  • Use chaining
  • Use pure OO

This is available by default and has constructors but requires a call to _init() (though this will go away).

Question: how does the namespacing work with data().

TODO: Check how the data is getting stored with the constructors with the UI framework.

Create a new widget

Without defining any functionality, first set up all the options that need to be supported.

  1. Create the widget with the namespacing

cmo.timeline as an example.

  1. Set up defaults as an object literal
  2. Use metadata in class if required not with the constructor
  3. Modify the state of the data in the DOM with metadata

http://plugins.jquery.com/project/metadata

  1. Use the nomenclature of _ prefixing which is enforced
  2. Monitor the use of trigger()
How do you clean up all of the changes made as part of converting something to a widget?

destroy: function() {}

is called assuming that the removal originates from jQuery and invokes remove() in the same way as html().

Status

Should be fairly stable. New features are slated for the next released.

Looking at extending base classes to support OO style of development.

Documentation is available outside of the core wiki

http://wiki.jqueryui.com/

There are rules associated with the nomenclature that should reduce some stupidity in the way that objects are called.

Filesize and dependency issues are still being reviewed.

The widget factory is really just a OO factory for all of the default behavior but with bindings into jQuery and how to handle merging of options.

  • TODO rsch OAP as alt style for coding
  • TODO

3:00 PM Session 4 Scaling JavaScript Development with JavaScriptMVC by Justin Meyer (@justinmeyer)

Description

Developing complex JavaScript applications is a nightmare. Your application has to run on as many browsers as operating systems. Every additional line of code means a slower loading time for your users. Your front-end developers are wasting time waiting for the backend developers to catch up. JavaScriptMVC is a framework that has stolen the best ideas in JavaScript development and integrated them into a single package.

Notes

This is used with client work with Jupiter consulting for single page large applications.

Look at dependency management.

A standard discussion of documentation, using testing, reporting errors, separating functionality, maintainability, quality, CRUD functionality, fixtures (via JSON) parallel development.

This appears to only work in with Rails and CI for the compression.

Takeaway: may as well enforce some best practices even if it involves coordinated with multiple groups at CMO.

This system could never be integrated at CMO:

  • assumes single page site
  • limited to simple handling of requests for data
  • couldn't be fed into CI

3:45 PM Session 5 Extending Ajax Events for All Mankind

Description

Provided a mechanism for supporting multiple content types associated with Ajax requests.

Alternative

"Building ARIA-Enabled Widgets With jQuery" by Joe McCann

4:30 PM Session 6 The jQuery UI CSS Framework and ThemeRoller: An In-Depth Overview

Notes

Originally required extensive work for each of the widgets created or would need to use the existing Flora theme.

Only designed for widgets.

TODO: Get a simple theme for CMO without input from Creative. Do this as a non-spec project then roll in the integration.

jQuery UI 1.7 will have some simplified widgets. Would need to be rolled as apart of the project. This uses ThemeRoller 2.0.

Initial theme image support through Google CDN.

Themes only provide color but not position, float, padding, etc.

.ui-widget .ui-widget-header .ui-widget-content

States, overlay, etc. provide additional color and texture.

Uses sprited span classes.

See the .ui-corner-all for a general rounded corner support.

UI Tabs
  1. Define the namespace for widget

ui-cmo-timeline ui-cmo-timeline-nav ui-cmo-timeline-selected

This will only define the layout.

  1. Set up the color information

Bind the structural elements to layout components.

.ui-widget-header .ui-widget-content

Multi-scope themes

This is part of the advance selector on the theme builder.

5:15 PM Session 7 Understanding JavaScript Testing by John Resig (@jereig)

Description

Recommendations

JavaScript testing isn't about regression primarily.

Look for quirks in browser than are difficult to remember at all times.

Requirements

Writing own framework is relatively trivial.

  • Assertions

Most test suites can be fairly trivial in that it only requires an assertion system.

  • Tests

The next level of abstraction lives at the level of a test consisting of multiple assertions.

  • Async tests

This allows a queuing system for processing the tests.

Requires setting up the queue.

  • Suites
Considerations

Standalone or Runner

  • QUnit
  • JSUnit
  • Selenium
  • YUITest

are similar in popularity.

Types of testing

Unit

One method at a time.

  • QUnit

    There is a session tomorrow.

    Supports the core features noted above.

    See jqspec.

  • JSUnit

    Oldest framework and it feels like it.

  • YUITest

    Likely to be the most popular framework.

    Supports async and event simulations that may be better than QUnit which helps in testing UIs.

    Look at the YUI 3 syntax for the YUITest 3.

Behavior

Similar to unit but broken by task. Unconfirmed arguments about how the way someone writes behaviors or function assertions and the number of supported types.

  • JSSpec
  • Screw.Unit

http://pivotallabs.com/users/nick/blog/articles/433-screw-unit-a-new-js-testing-framework-version-0-1

Functional
Browser launcher

The newest entry:

WebDriver - http://code.google.com/p/webdriver/

See the notes for additional options.

Server-side

Look at Crosscheck via issue #24.

js-env has already been implemented at CMO.

Day 2

10:00 AM Session 1 Load JavaScript Faster by Steve Souders

Description

Scripts are the most painful resource to load in your page - they slow down the page more than images, stylesheets, even Flash. Why? Because when browsers start downloading a script, they stop rendering the page and downloading other resources.

Notes

Tools

Using both Page Speed and YSlow! is useful for various tests.

TODO Scripts and splitting

Parallel download now in ff3.5, chrome2…

The tools necessary to support the split are going to be a manual process: do this with the onload tests across all of CMO then apply the logic associated with Doloto:

http://research.microsoft.com/apps/pubs/default.aspx?id=70518

TODO MSN.com parallel scripts (script on element)

createElement("script") then check onreadystatechange.

Check that we're not using <script></script> invocations for ads that would block the parallel downloads in MSIE since this

TODO cmcdn.com blocking options for parallel downloading

Check the work provided by SS on the decision tree for the parallel downloading based on IFRAME or XHR requests.

The async requests could create problems if Web Developers aren't using the correct linkBuilder configuration to indicate the correct domains based on browser behavior.

Ensuring async correct load order

Example given was just for technique 5 in the deck: onloadDone.

$.getScript abstracts this functionality.

Preview release: WordPress optimization tool

Based on Even Faster Websites tool based on jQuery.

This is a sprite generation tool.

This updates the DOM on the fly

http://spriteme.org/

11:00AM Session 2 Query Refactoring by Jonathan Sharp and Brandon Aaron

Description

With the amount of jQuery code being written, this session takes a practical approach to best practices and patterns for refactoring existing code.

Notes

The example is a simple timer.

<div id=timer> updated by setInterval.

Requirement is to add a pause button.

The progression of the development is to begin to use a custom event and binding in setInterval to just trigger the update.

This uses the data() feature to create custom events and could be used for polling updates associated with widget chunks at CMO for CL or community feed updates.

TODO Apply setData for triggering event changes

Look at decoupling the presentation classes from the data-* classes.

data bound into the DOM with listeners for the particular events: data() triggers setData event as part of jQuery internals (TODO: check the jQuery cookbook).

Custom events are bubbled in 1.3 (part of the Widget Factory); will need to upgrade to a current version before Q4.

TODO onAction plug-in with apply to preserve this

Similar to Live.

  1. Create action classes

Assume that you have any action-foo

  1. Bind onAction

Use the plug-in to look for any event (click in the example) assocated with the class name.

  1. Provide standard action and callbacks for the plug-in

return callback.apply

to support the call to onAction() using $(this) to reference the clicked element.

Questions

Is there a risk when refactoring occurs to remove data specific classes (i.e., the "action-*" classes).

Should the html5 data attributes be used.

Alternative

Font loading, which is likely a low priority for CMO, has slides available at

http://outwestmedia.com/jquery-refactored/jquery-refactored-1.0.zip

11:45 AM Session 3 Get Involved by Brandon Aaron

Description

jQuery has the best JavaScript community around. I'm going to take you behind the scenes of jQuery and share my personal experiences in contributing to jQuery.

Notes

A general discussion of the structure of the jQuery organization.

http://jqueryui.com/about

Try to find the best way to create new features.

Key goal is to just publish something event without a full assessment of the requirements for unit tests, documentation, test support, or coding standards.

Any of the internal projects at CMO could be released assuming that it is solving some problem:

  • Bubbles
  • Data access for membership types

However, this also requires a deeper understanding of the

dimensions offset has had multiple revisions in order to make it more accurate than other libraries.

The key to survival when contributing is not to over-commit.

Work through the software releases iteratively: push to github, list on jQuery plugins, wait for bug reports.

Take a look at the jQuery Google English group as a first point to address questions that are relevant to the community: http://groups.google.com/group/jquery-en?pli=1 .

See also the jQuery IRC channel as one of the better locations for answering questions:

(setq erc-autojoin-channels-alist '(("freenode.net" "#jquery")))

TODO 1:15 PM Performance Discussion

Description

General discussion of loading options for scripts based on a review

http://labjs.com/

What does the API perform for browsers to limit the damage.

http://stevesouders.com/efws/

One of the issues with the YUI Loader implementation is that it has no knowledge of how to unblock the script loading.

What constitutes a win?

How to determine when to have the back-end proving the loader script?

This should be an extension

Look at dojo.requires (noted in http://github.com/jwalsh/research/issues/#issue/26).

Notes

Need to determine who has responsibility at CMO for finding the dependencies between functions and downloads in scripts across the site.

2:00 PM Session 5 Advanced jQuery Best Practices by Yehuda Katz (@wycats)

Description

Notes

javascripts/ structuring

Look at an overall application.js file; this would just be the global function or a loader.

Consider structuring according to the type of the application you're running.

  • REST

    Object type that needs the interaction.

  • MVC

    One per controller

  • Feature / client functionality
Concat

all.js: see the rules associated with how to determine what the load order is required.

  • Server-side

    Sockets, or Rails (scriptincludetag (includes cache))

  • Build-time

    Dojo is a good example but not recommended.

Closure at build time

Consider just pulling most of the files into the closure of

(function() { })(jQuery)

or whatever the required files.

Namespace

cmo.

Documentation

Look in particular for custom events.

TODO Configuration

Meta data:

Try this

jQuery(function($) {

});

for simplifying the closure.

Begin using the HTML5 for data structuring for having metadata: use the data- prefix attribute for elements.

Events

For example:

…live("click", function() { …trigger("activated.foo") } );

…live("activated.foo", function() {});

This should also be considered with namespacing.

Dumb server

What should be done for the Rhino parsing of the JSON response with the templating language

Performance

Noted issue with the cache breaking with a query string; won't work. Research already completed.

Split the asset hosts against the new cmcdn.com domain:

s%d.cmcdn.com and s%d.stg2.cmcdn.com

config.actioncontroller.assethost =

This may change the eventual configuration associated with the graphics.base.url to be an asset.host.url

3:15 PM Session 6 Building Evented Single Page Applications by John Nunemaker

4:15 PM Keynote: jQuery UI

Description

Look at jQuery UI Labs.

Ensure that the plugins created at CMO use the widgets plugin from jQuery IU core.

Notes

4:45 PM Keynote: jQuery

  • Acquiring a new CDN
  • Moving away from Google Groups
  • New plugins directory
  • 4 conferences next year
  • Moving to a non-profit status

5:15 PM Panel Q & A

Questions

Based on moderator.appspot.com.

Answers

documented number of developers actively developed tested actively tested readable

Author: Jason Walsh

j@wal.sh

Last Updated: 2025-07-30 13:45:27

build: 2025-12-23 09:11 | sha: a10ddd7