(Lessons From Creating the Meebo Bar) Presentation

advertisement
Building Fast 3rd-Party Webapps
Lessons learned from the Meebo Bar
Martin Hunt and Marcus Westin
O'Reilly Velocity
Web Performance and Operations Conference
24 June 2010
marcus@meebo-inc.com
martinh@meebo-inc.com
The Meebo Bar
A customizable site bar with real-time social interaction
Meebo Bar, a 3rd Party Webapp
JavaScript, CSS, Images & HTML
Interacts with the page
Loads on every page
How do we make it run fast?
How do we make it respectful?
3rd Party Webapps
The Challenge
Do
• Load lots of features
• Load features fast
Without
• Blocking rendering or onload
• Affecting User Experience
How?
3rd Party Webapps: How?
Tools
Techniques
• How to initialize a webapp
Asynchronous & non-blocking
o
• Defer Execution
Minimize impact when loading
• CSS and Images
Crush, Combine, Avoid
• Perceived Performance
Testing and psychology
Meebo Bar embed code
• executes in ~10ms
o no blocking network requests
o no dependency on our server
• less than 1200 characters
• gzips to about 700 bytes
• embedded directly in page HTML or JS
• executes even if our servers are not reachable
Initializing 3rd Party Webapps
Inline JS <script src="">
easy for publishers to add
blocks the page in all
browsers
Iframe <iframe src="">
load an HTML file in an iframe
Requires HTML file on the
hosting site
XMLHttpRequests
Asynchronous, nonblocking
same-domain in most
browsers
Script Tag
append a script tag using
JavaScript to the head of
the document
Commonly accepted,
but...
Accepted script loading code
var head = document.getElementsByTagName('head')[0],
el = document.createElement('script');
el.src = "http://www.myDom.ain/myScript.js";
head.appendChild(el);
good: cross domain (we're 3rd party content!)
good: doesn't block network traffic
Don't block the page!
Script Tag Append
can block scripts in Firefox!
blocks other scripts in Firefox
• scripts execute in order
• all scripts on the page block until the appended script
downloads and executes
• (defer attribute supported in FF3.5+)
blocks onload event in all browsers
are there alternative nonblocking
methods?
Iframed JS
1. Iframes load HTML, not JS
2. Cross iframe communication is
same-domain only (non-HTML5
browsers)
3. Window onload event fires
after all iframes load
Iframed JS - the solution
var iframe = document.createElement('iframe'),
doc = iframe.contentWindow.document;
doc.open().write('<body onload="appendScriptTag()">')
doc.close()
More About Iframes
iframe creation overhead?
Creating one DOM node
o Chrome < 1ms
o Firefox, Safari ~1ms
o IE ~5ms
Sandboxed JavaScript
• 3rd party code will not break webpage code
• Webpage code will not break 3rd party code!
for (var i in x) {}
Defer Execution
Defer Execution
Lots of stuff happens in a browser while loading a page
Then, relatively little happens... Take advantage of this!
Defer Execution Example
In-page sharing
Defer Execution Example
In-page sharing
Defer Execution Example
In-page sharing
Defer Execution Example
In-page sharing
Naive implementation
function makeSharable(elements) {
for (var i=0; i < elements.length; i++) {
var element = elements[i];
var metadata = lookupMetadata(element);
element.on('mousedown', startDrag,
metadata);
}
}
function lookupMetadata(el) {
do {
inspectElement(el)
} while(el = el.parentNode)
}
O(N*M)
O(N)
O(M)
Deferred implementation
function initShare() {
document.on('mousedown', function(e) {
var el = e.target || e.srcElement
if (!el.getAttribute('meeboSharable')) { return; }
var metadata = lookupMetadata(el);
document.on('mousemove', handleDrag, metadata);
document.on('mouseup', stopDrag, metadata);
});
}
Page finishes loading
O(1)
Modularize & Lazy Load
users don't need all features immediately
1-1 Messaging
connect to all the
IM networks
Social Networking
Broadcasting
publishers send new
content to users
receive updates about
your friends' activities
Sharing
Site Widgets
share site content to
Facebook, Twitter, Buzz,
and other sites
site-specific widgets:
videos, menus, navigation
tools, etc.
Modularize & Lazy Load
Also applies to
images and CSS!
Careful:
Loading images can create
a lot of HTTP requests
Loading Images
Spriting and preloading is hard
Still creates additional HTTP requests
Difficult to automate
Embed images into CSS instead
DataURIs and MHTML files
Details on the Meebo devblog
(http://mee.bo/cssimages)
Use Vector Graphics
Vector graphics are supported
in all major browsers
•
•
•
•
•
Firefox 3+
Opera 9.5+
IE 6+
Safari 3+
Chrome
With images
Without images
Tools - use them!
Profilers
• DynaTrace (IE)
• Speed tracer (Chrome)
• Firebug (FF)
• Safari 5/WebKit
Preprocess if possible
• if multiple clients are
doing the exact same
task, run it on the server
• generate content offline
Compilers
• Closure Compiler
Perceived Performance
Quick loading content on a
slow page appears to be the
cause of the slow page
Delaying interface drawing
can look slow or broken
Do not forget:
Even asynchronous loading
slows down a page.
Keep payloads minimal and
always monitor
performance!
Highlights
•
•
•
•
•
Always compress and minify content
Use an IFrame to load the main script payload
Defer execution until needed
Defer content download until needed
Remove HTTP requests by combining content
o Embed images into CSS
o Use vector graphics
Questions?
marcus@meebo-inc.com
martinh@meebo-inc.com
Download