Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pitfalls and opportuniities of single-page applications, jQuery Conference San Francisco 2012

Pitfalls and opportuniities of single-page applications, jQuery Conference San Francisco 2012

Slides for my "Pitfalls" talk (jQuery Conference 2012). See also https://github.com/jzaefferer/pitfalls-examples

8ba7af140cf671c5cab61154d5ee19ef?s=128

jzaefferer

June 29, 2012
Tweet

More Decks by jzaefferer

Other Decks in Programming

Transcript

  1. Pitfalls and opportunities of single-page applications Jörn Zaefferer Friday, June

    29, 2012
  2. Friday, June 29, 2012

  3. Friday, June 29, 2012

  4. Friday, June 29, 2012

  5. “A single-page application (SPA) is a web application or web

    site that fits on a single web page with the goal of providing a more fluid user experience akin to a desktop application.” --Wikipedia, Single-page application Friday, June 29, 2012
  6. Friday, June 29, 2012

  7. Friday, June 29, 2012

  8. Friday, June 29, 2012

  9. Friday, June 29, 2012

  10. Friday, June 29, 2012

  11. Friday, June 29, 2012

  12. Friday, June 29, 2012

  13. Friday, June 29, 2012

  14. Simple application architecture Better user experience Super duper frameworks Opportunities

    Friday, June 29, 2012
  15. Friday, June 29, 2012

  16. Friday, June 29, 2012

  17. Hashbang sucks First page load sloooow Error handling Pitfalls Friday,

    June 29, 2012
  18. Good news: Code is available on GitHub for all examples!

    Friday, June 29, 2012
  19. Friday, June 29, 2012

  20. Classic page Friday, June 29, 2012

  21. Classic page Friday, June 29, 2012

  22. Classic page Friday, June 29, 2012

  23. Single Page Friday, June 29, 2012

  24. Single Page Friday, June 29, 2012

  25. Friday, June 29, 2012

  26. History API Friday, June 29, 2012

  27. Friday, June 29, 2012

  28. HTML5 history API history.pushState(..., fragment) history.replaceState(..., fragment) document.addEventListener("popstate", callback, false)

    Friday, June 29, 2012
  29. HTML5 history libraries history.js Backbone.history.start({ pushState: true }) simple-history.js Friday,

    June 29, 2012
  30. simple-history.js SimpleHistory.pushState(fragment[, state]) SimpleHistory.replaceState(fragment [, state]) SimpleHistory.start(callback) Friday, June 29,

    2012
  31. pushState example Friday, June 29, 2012

  32. $("a:not([href^=http])").click(function(event) { if (event.metaKey || event.shiftKey || event.ctrlKey) { return;

    } event.preventDefault(); SimpleHistory.pushState(this.href); }); Friday, June 29, 2012
  33. SimpleHistory.start(function(url, state) { var parts = URL.parse(url); var path =

    parts.path; var index = path === "/"; $(document.body).toggleClass("indexActive", index); if (!index) { var photo = photos.lookup(path); $("#photo img").attr("src", photo.src); $("#photo p").text( photo.description ); } }); Friday, June 29, 2012
  34. twitter.com/bassistance vs twitter.com/#!/bassistance Never available on server Only as fallback

    Not necessary, as we’ll see soon What about hashchanges? Friday, June 29, 2012
  35. pushState, not hashchange! Friday, June 29, 2012

  36. Friday, June 29, 2012

  37. Friday, June 29, 2012

  38. Server side rendering access API directly render templates share code

    with client Friday, June 29, 2012
  39. Friday, June 29, 2012

  40. server rendering example Friday, June 29, 2012

  41. // double client/server export var photos; if (typeof exports !==

    'undefined') { photos = exports; } else { photos = {}; } photos.data = [{ src: "/alligators/DSC_1165.jpg", description: "Not a crocodile" }, ...]; photos.lookup = function(url) { return photos.data.filter(function(photo) { return photo.url == url; })[0]; }; Friday, June 29, 2012
  42. serverside rendering, not slow first page load Friday, June 29,

    2012
  43. Friday, June 29, 2012

  44. Friday, June 29, 2012

  45. In space no one can hear you scream Friday, June

    29, 2012
  46. In browsers no one can hear your code scream Friday,

    June 29, 2012
  47. var up = new Error("omfg"); throw up; Friday, June 29,

    2012
  48. Friday, June 29, 2012

  49. Error handling Catch on client Send to server Aggregate Friday,

    June 29, 2012
  50. Error types SyntaxError TypeError Ajax Friday, June 29, 2012

  51. $("#breakz").click(function() { $.get("/not/exists"); this.does.not.exist(); }); Friday, June 29, 2012

  52. window.onerror = function(message, file, line) { window.onerror = function() {};

    logError("global", message, file + ":" + line); }; Friday, June 29, 2012
  53. $(document).one("ajaxError", function(event, xhr, options, error) { logError("ajax", error + ":"

    + xhr.responseText, options.url); }); Friday, June 29, 2012
  54. function logError(type, message, detail) { $.post("/errorlogger", { type: type, message:

    message, detail: detail }); } Friday, June 29, 2012
  55. Error handling example Friday, June 29, 2012

  56. Custom Analytics Aggregation options Friday, June 29, 2012

  57. function logError(type, message, detail) { _gaq.push(['_trackEvent', type, message, detail]); }

    Friday, June 29, 2012
  58. Friday, June 29, 2012

  59. Custom Analytics Airbrake, BugSense Aggregation options Friday, June 29, 2012

  60. Friday, June 29, 2012

  61. CATCH THEM ALL Friday, June 29, 2012

  62. Worth the trouble? Better user experience Good first impression Stable

    product Friday, June 29, 2012
  63. Further reading: https://github.com/jzaefferer/pitfalls-examples Short link: http://git.io/Hirx3Q Looking for your feedback:

    http://www.surveymonkey.com/s/2F63MML Short link: http://svy.mk/xtVS2F @bassistance - joern.zaefferer@gmail.com Friday, June 29, 2012