appendChild HTML or iframe ... HTML, CSS, and JavaScript for use on another person's website. "I don't ... other- div {
Practicing Safe Specs with Widgets
Howard Rauscher / @howardrauscher
TL;DR You don't have control over other people's websites Give customers a script tag to paste in site Helps your product development be flexible Don't use document.write node.appendChild HTML or iframe JavaScript should be library independent Follow standard performance guidelines
WTF is a Widget
HTML, CSS, and JavaScript for use on another person's website "I don't know how to describe a widget. But I can recognize one when I see it" e.g. like, tweet, digg, maps, ads, third party content, pretty much anything on a blog...
The Problem You don't have control over other people's websites Examples Library: you- Prototype vs. other- jQuery Box model: you- Standard vs. other- Quirks Markup: you- id="box" vs. other- id="box" CSS (not going to talk about this...but it sucks) you- div {margin: 0; } other- div { margin-bottom: 5px;background-color: red } You don't know, what you don't know
Solutions Delivery mechanisms* Copy and paste iframe Script node also, ..Flash e.g. Youtube players not going to talk about this
*In reality you use a mix of all three
Copy and Paste The "it's not my problem" method You provide CSS, HTML, and JavaScript in a and they copy and paste Good for sharing examples, not good for products Pros Minimal support costs (let other devs fix their own problems) Cons Hard/impossible to push updates Too much support You'd be surprised by how few resources your customers have ...or how bad of a coder you are
iframe bits, > requests) Cross frame communication & styling annoying
Script Node // JavaScript - widget.js var ifr = document.createElement('iframe'); ifr.src = 'http://awsmsite.com/widget?acnt=2800000&poll=1'; var div = document.createElement('div'); div.innerHTML = '...this is awesome...'; var frag = document.createDocumentFragment(); frag.appendChild(ifr); frag.appendChild(div); var self_script = document.getElementsByTagName('script'); self_script = self_script[self_script.length - 1]; self_script.parentNode.insertBefore(frag, self_script);
goto: https://gist.github.com/919744
Making a Widget Recommendation Use script to deliver widget Follow performance best practices i.e. Don't be an ass Other devs won't want to use you product if it's slow Don't use document.write Weird side effects when doing XHR in iframes Bad for performance Personally don't have evidence, but everyone says so
Things to consider Can widget be used more than once on a page? Can widget be modified by customer (e.g. CSS, additional functionality)?
Example Mass Relevance Widget
Example: Pros Mass Relevance Widget Script node used to deliver widget I wouldn't have been able to make improvements easily if we didn't
Example: Cons Mass Relevance Widget: December 2010 document.write*
* it is going to get much worse
Example: Cons Mass Relevance Widget: December 2010 First doc.write: complete content Can't embed multiple b/c JS depends on static element ID in content It's f'ing huge
https://gist.github.com/9e9a05a6b13fa512a3df#file_content.html
Example: Cons Mass Relevance Widget: December 2010 Second doc.write: polling script Umm...includes Google Ajax API Google Ajax API loads jQuery Just 1% of jQuery used 150 line plugin to do setInterval Also, F'ing huge Dependency on specific jQuery version "When this code is on the page it loads jquery 1.3.2 from google, which appears to kill our jquery 1.4.2 that we already have on the page, and kill all the plugins that we use on the page. Is this a known problem or is there a work around?" - Dev employed by customer
https://gist.github.com/9e9a05a6b13fa512a3df#file_poll.html
Needed Improvements Remove document.write's Allow multiple to be embedded at one time Remove jQuery dependency Be extensible Increase performance Split up into reusable and cacheable pieces
remove document.write's https://gist.github.com/ae56db332a33bd8cf1bd
Needed Improvements ✓ Remove document.write's ✓ Allow multiple to be embedded at one time Remove jQuery dependency Be extensible Increase performance Split up into reusable and cacheable pieces
Remember why it currently sucks Includes Google Ajax API Ajax API loads jQuery Just 1% of jQuery used Plugin to do setInterval Also, is HTML file not a JS file
remove jQuery dependency goto: https://gist.github.com/4e8d87d27fc6b8ef0f24
remove jQuery dependency
Needed Improvements ✓ Remove document.write's ✓ Allow multiple to be embedded at one time ✓ Remove jQuery dependency Be extensible Increase performance Split up into reusable and cacheable pieces
be extensible https://gist.github.com/ebdf52f8206c9838cd15
be extensible https://gist.github.com/8ca31a3e81af59a51cf7
Needed Improvements ✓ Remove document.write's ✓ Allow multiple to be embedded at one time ✓ Remove jQuery dependency ✓ Be extensible Increase performance Split up into reusable and cacheable pieces
increase performance http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309/ref=ntt_at_ep_dpi_1
increase performance https://gist.github.com/311148e72a15c6ae38be
Needed Improvements ✓ Remove document.write's ✓ Allow multiple to be embedded at one time ✓ Remove library dependency for basic functionality ✓ Make extendible by customer Increase performance (only like 75% complete...Varnish sucks at gzip, need to combine scripts, etc.)
✓ Split up into reusable and cacheable pieces
Random Thoughts (I couldn't find a place to put these)
Resource loaders Tons of them Pick on the one that works for you https://spreadsheets.google.com/lv?key=tDdcrv9wNQRCNCRCflWxhYQ
CSS namespacing e.g. '.tr-status' instead of '.status' Must do it if you are including CSS You don't want to screw up other sites
Cross-domain communication Tricky to do cross domain communication and ajax http://alexsexton.com/?p=154
Random Thoughts (I couldn't find a place to put these)
My suggestions are not the only way to embed Some widgets require you to load code then place the widget itself e.g. widget.appendTo('mydiv'); We will probably move to this method
My suggestions might not pass ADSafe or Caja These systems help prevent 3rd party JS from doing evil Most sites don't use these
process.end(); Mass Relevance is hiring.... Stack Rails/Ruby Node.js Redis Amazon AWS Things we do Real time systems Machine learning: language detection, sentiment analysis, geotagging