Practicing Safe Specs with Widgets - Bitly

0 downloads 84 Views 2MB Size Report
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