-
-
Save jakelazaroff/6122988 to your computer and use it in GitHub Desktop.
code delimiters: <% %> | |
# keynote | |
- your business logic will live longer than your interface | |
- stateless | |
- no "spaghetti state" | |
- application should be able to reflect any combination of data | |
- views should transparently reflect models | |
- backbone patterns | |
- custom model methods | |
- don't treat models as just deserialized json | |
- anything with a reference to the model can call custom methods | |
- [a.k.a. business logic goes here!] | |
- example: "share a book with one user" <% user.shareWith(me) %> | |
- custom collection methods | |
- example: search models in a collection by string <% accounts.search("Joe Brooklyn") %> | |
- filtered collections <% documents.published() %> | |
- method 1: define filter functions that return an array of values you need | |
- method 2: create another collection that listens to events on the original, only picks models matching a certain condition | |
- harmonizing with garbage collection | |
- remove references you no longer need | |
- events are references! clean them up! | |
- don't create references you don't need to create | |
- have shorter-lived entities listen to longer-lasting ones, not vice versa | |
- lazy loading | |
- used deferred objects (promises) | |
- example: lookup function either returns the local object, or fetches it from the server | |
- relations <—> objects | |
- entities probably won't exactly mimic your database schema | |
- timing | |
- debounce a method (such as rendering) <% _.debounce() %> | |
- render in chunks so as not to block the UI thread | |
- subclassing models | |
- <% Account = Backbone.Model.extend({ ... }); Publisher = Account.extend({ ... }) %> | |
- global events | |
- from Backbone 1.0, events is mixed in to the Backbone object <% Backbone.on('switchuser', ...) %> | |
- model snapshots | |
- models can represent hypothetical or previous states | |
- keep them on the client side | |
- example: undo <% this.on('change', function () { changes.push(this.previousAttributes() }) %> | |
- example: <% draft = model.clone() %> | |
- virtual sub-models | |
- just because something is represented together on the server doesn't mean it should be the same model on the client | |
- model on the client doesn't have to correspond to the server | |
- q&a | |
- mediator (two views "talking" with no model in between) | |
- an event is still a reference | |
- just create a reference between the two | |
- listening to events on nested models | |
- plugins! | |
- or, model has a collection with references to submodels | |
# tools & ptterns for building large-scale Backbone applications | |
- talk | |
- slides: https://speakerdeck.com/backbonerails/little-opinions-big-possibilities-the-tools-and-patterns-for-building-large-scale-backbone-applications | |
- library | |
- marionette.js | |
- what is a large-scale JavaScript application? (generally) | |
- non-trivial | |
- significant dedicated developer effort | |
- most work on the browser | |
- tip: devote significant time to planning/modeling | |
- case study: rdio | |
- collections of songs | |
- changing sort order, filtering | |
- push state to update URL | |
- etc. | |
- characteristics of large-scale apps | |
- multiple routers | |
- view management | |
- nesting | |
- cleanup | |
- complex events | |
- lots of state changes | |
- many entities (models/collections) | |
- specialized objects | |
- [Application] | |
- objects that should be globally accessible | |
- example: current user | |
- [App Modules] | |
- [Router] | |
- [Controllers] | |
- [Specialized Views] | |
- [Components] | |
- take specialized behavior out of views | |
- "decorators" | |
- example: forms | |
- example: spinner | |
- [Mixins] | |
- [Entities] | |
- shared namespace for models/collections | |
- [Config] | |
- [Modules] | |
- [Messaging Bus] | |
- [Request] | |
- [Command] | |
- [Pub/Sub] | |
- give views a standard set of events and methods | |
- example: 'onRender', after the view has been rendered | |
- controller | |
- keep views thin | |
- delegate responsibilities to controllers | |
- specialized views | |
- ItemView | |
- related to a single model | |
- CollectionView | |
- iterates through a collection, creating ItemViews | |
- Layout | |
- keep track of subviews | |
- folder organization | |
- backbone | |
- app.js | |
- apps | |
- playlists | |
- playlist_app.js | |
- list | |
- show | |
- edit | |
- new | |
- playlist_songs | |
- playlist_songs_app.js | |
- list | |
- currently_playing | |
- currently_playing_app.js | |
- show | |
- config | |
- entities | |
- components | |
- mixins | |
# test-driven development | |
- talk | |
- slides: https://speakerdeck.com/landau/test-driven-backbone-development | |
- code: https://github.com/landau/tddbackbone | |
- libraries | |
- mocha | |
- chai | |
- sinon.js | |
- jasmine | |
- writing a test | |
- assert | |
- accepts a boolean value and an error string | |
- if the boolean is false, throw an error | |
- describe | |
- accepts a string and a function | |
- string indicates what we're testing | |
- nest describes <% describe('Todo View', function () { describe('.initialize', function () { ... }) }) %> | |
- before/after | |
- actions to set up/clean up tests | |
- example: instantiating a collection, etc | |
- it | |
- assertions live in these functions | |
- example: <% it('should be a list tag', function () { assert(app.Todo.prototype.tagName === 'li') }) %> | |
- spy (sinon.js) | |
- check whether a function is called, parameters, etc | |
- stubs (sinon.js) | |
- functions with preprogrammed behavior | |
- can return known data (dependency injection) | |
- running the tests | |
- automate tests | |
- grunt.js | |
- continuous integration | |
- what not to test | |
- third-party code | |
- integration testing | |
- q&a | |
- code coverage tools? integration testing tools (with node)? | |
- code coverage | |
- jscoverage | |
- integration testing | |
- selenium | |
- karma | |
- recommended grunt packages | |
- grunt template | |
- grunt connect | |
- DOM testing recommendation: jsdom | |
- tip: render views in memory, don't insert into DOM | |
# breakout session: developer power ups! | |
- writeup: http://caliper.io/blog/2013/backboneconf-tooling-and-services-session/ | |
- errors | |
- loggly | |
- sentry raven | |
- catcherize | |
- errorception | |
- crashlytics | |
- dependencies | |
- npm | |
- requirejs | |
- requirejs-rails | |
- browsify | |
- testing | |
- selenium | |
- sauce labs | |
- venus | |
- qunit | |
- phantom | |
- (not great for stack traces) | |
- mocha | |
- poltergeist | |
- capybara | |
- cucumber | |
- continuous integration | |
- travis | |
- jenkins | |
- teamcity | |
- circleci | |
- deploying | |
- (s)ftp | |
- fabric | |
- puppet | |
- capistrano | |
- grunt | |
- chef | |
- monitoring | |
- new relic | |
- mpulse | |
- miscellaneous | |
- yoda | |
# dependency injection for fun and profit | |
- what is it? | |
- pass dependencies into constructors and check for them | |
- easy to test | |
- constructors | |
- "plans" for application | |
- namespace blues | |
- don't rely on globals | |
- requrejs/commonjs | |
- modules help organize your constructors | |
- dependency injection helps organize your instances | |
- keep module system and instance management separate | |
- two dependency graphs | |
- the constructors that form your app blueprint | |
- dependo | |
- the instances of which your app is composed | |
- refactoring | |
- altering structure while keeping behavior intact | |
- refactoring without tests is just changing stuff | |
- patterns | |
- application view | |
- check dependencies during instantiation | |
- tests enforce the contract of dependencies | |
- single point of entry to access instances | |
- apps should be accessible to the outside world (e.g. console) | |
- SOLID (object-oriented) design principles | |
- single responsibility | |
- a class/method should only be responsible for one thing | |
- if it does two (or more), split it up! | |
- open / closed | |
- classes should be open for extension, closed for modification | |
- liskov substitution | |
- objects should be replaceable with instances of their subtypes (a.k.a. polymorphism) | |
- interface segregation | |
- many client-specific interfaces are better than one general-purpose one | |
- make functions responsible for less | |
- dependency inversion | |
- depend on abstractions, not concretions | |
- example: don't poll a model, listen for change events | |
- modules | |
- use them | |
- fight with your manager | |
- long-lived section views | |
- components are the future | |
- aura.js | |
- shameless plug: backbone.js in action | |
- promo: MLBBJSCO | |
q&a | |
- why expose your application to the window? | |
- console access | |
- closer checks for dependencies than just for existence? | |
- type | |
- properties/methods | |
# domain-driven web applications using Backbone | |
- talk | |
- slides: http://bobholt.me/bbconf-bos-2013 | |
- domain-driven design | |
- it's a book! go buy it! | |
- domain | |
- the application's "world" | |
- example: for a stock application, the trading floor, stocks, people, etc | |
- domain model | |
- image of the business logic that exists in the head of an expert | |
- conceptual model; has nothing to do with software (yet) | |
- process | |
- discovery | |
- consult with experts, project managers, etc | |
- ubiquitous language | |
- terminology everyone who touches the project uses (including clients) | |
- modify the model to accommodate new constraints | |
- iteratively change the model throughout the process | |
- layers | |
- interface layer | |
- accepts and responds to user input (presentation) | |
- application layer | |
- transactions, activities, creates/access/deletes domain objects (application logic) | |
- domain layer | |
- the state and behavior of the domain (business logic) | |
- infrastructure layer | |
- supports the layers on top: servers, repos, etc | |
- organization | |
- app | |
- domain | |
- framework | |
- pages | |
- services | |
- widgets | |
- express the model in software | |
- clarify relationship between objects | |
- entities | |
- has an identity (id) | |
- example: airline seat (each is unique and assigned) | |
- value objects | |
- commodity objects | |
- passed as parameters, attached as attributes, etc | |
- example: bus seat (not uniquely assigned) | |
- services | |
- "actions" | |
- repositories | |
- centralizes management of domain objects | |
- retrieves from cache or server as necessary | |
- returns existing objects | |
- factories | |
- creates domain objects given attributes | |
- takeaway | |
- don't start coding right away | |
- q&a | |
- tip: incorporate all the key stakeholders (designers, programmers, clients, etc) in the discovery phase | |
# geologic time scale | |
- talk | |
- slides: https://speakerdeck.com/mwunsch/the-geologic-time-scale-of-gilt-dot-coms-view-layer | |
- stratigraphy (layers) | |
- technology layers continue to build up | |
- end result: technical debt | |
- asynchronous javascript and xml | |
- fundamental piece of the modern web experience (yup!) | |
- old approach | |
- <% GET /add_to_card?sku=12345 %> | |
- not idempotent | |
- not RESTful | |
- append returned markup directly to DOM | |
- new approach | |
- client-side templating | |
- push state | |
- always be scrolling | |
- http://tumbledry.org/2011/05/12/screw_hashbangs_building | |
- optimizing for robots | |
- make sure data is available for search engines, et. al | |
- server-side rendering still needed for SEO | |
- templates | |
- different client-side and server-side templates for same thing? | |
- solution: use (or build) template parser for both | |
- https://github.com/mwunsch/handlebars.scala | |
- flexibility vs. maintainability | |
- maintainability | |
- no intrinsic value to users or business | |
- enables velocity; enables the programmer to create more value | |
- flexiblity | |
- allows the developer to add flexibility "ad hoc" | |
- the future | |
- "Backbone.js is the kernel for modern web development" | |
- more and more frameworks will be written on top of it | |
- mobile and desktop will converge | |
- http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/ | |
- with dynamic typing, test coverage is essential | |
- a statically-typed language enforces API contracts | |
- TypeScript: a typed superset of javascript | |
- q&a | |
- handlebars vs. mustache at gilt? | |
- mustache is logic-less | |
- pro: language agnostic | |
- con: no logic | |
# building Reflow | |
- talk | |
- slides: http://kristoferjoseph.com/Building-Reflow-BackboneConf-2013/ | |
- the problem | |
- difficult to design responsive websites | |
- often multiple PSDs | |
- using web technologies in a native app | |
- framework? | |
- onboarding | |
- easier to point people to Backbone documentation than homegrown framework | |
- pink wheel syndrome | |
- it's not better just because you made it | |
- prototype like you mean it | |
- write as if it were final, shippable code | |
- work til you can't scale, then refactor | |
- write tests for your prototype | |
- prototype the things you don't think are possible | |
- modularity | |
- RequireJS | |
- namespace events to prevent dependencies | |
- multiple inheritance | |
- functional mixins | |
- http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins | |
- views | |
- Backbone.LayoutManager | |
- Marionette | |
- templates | |
- _.template | |
- use as little logic in templates as possible! | |
- underscore templates are faster when not using "with" | |
- testing | |
- test-driven from day zero | |
- "you simply cannot make quality software without test-driven development" | |
- "you can't refactor without tests" | |
- sinon.js | |
- squire.js | |
- sonar | |
- code coverage | |
- graphs! | |
- topcoat | |
- http://topcoat.io | |
- q&a | |
- why and how did Reflow ship as a desktop application (not a web application)? | |
- why? | |
- cater to the current design workflow | |
- how? | |
- team at adobe is dedicated to adding features to webkit | |
- chromium | |
- developed in the browser | |
- CEF (chrome embedded framework) | |
- loading/saving | |
- decide on a strategy early | |
- vs. native | |
- working prototype in a week | |
- demo-able prototype in three months | |
- finished in sixty weeks | |
- DOM or canvas? | |
- performance tips | |
- debounced | |
- requestAnimationFrame | |
# growing up with Backbone | |
- talk | |
- slides: http://tbranyen.com/talks/growing-up-with-backbone | |
- source: https://github.com/tbranyen/growing-up-with-backbone | |
- build step | |
- makes code more portable | |
- structure | |
- separate your code from third-party code | |
- make your JavaScript as small as possible and still debuggable | |
- enable source maps (fundamental for development) | |
- modules | |
- easier to test and maintain | |
- organize modules so the template, JavaScript and CSS are all together | |
- package managers | |
- makes third party code a higher class citizen | |
- build only what you reference | |
- decouple loading the configuration from loading the application (RequireJS specific) | |
# advanced architectural patterns with Backbone and cujoJS | |
- problems with many script and link tags | |
- blocking/synchronous | |
- dependency management? | |
- globals | |
- identifier conflicts | |
- no clear dependencies | |
- JavaScript modules | |
- loaders are non-blocking | |
- organize code better | |
- explicit dependencies | |
- too many dependencies | |
- need to mock or stub each dependency to test | |
- inversion of control | |
- dependency injection | |
- components don't deal with own dependencies; another entity provides them | |
- use constructors to inject dependencies | |
- problem: main module is huge | |
- solution: composition plans | |
- describe components and their lifecycles | |
- components have own view, HTML and (potentially) CSS | |
- aspect-oriented programming | |
- decorate methods of a component to provide additonal behavior | |
- mediator | |
- "meld" | |
- before/after actions | |
- DOM manipulation | |
- lots of code | |
- difficult to test | |
- solution: OOCSS | |
- DOM should reflect application state | |
- CSS defines visualization of state | |
- toggle classes instead of directly manipulating DOM elements | |
# becoming a control freak with controllers and promises | |
- promises | |
- background | |
- serialize asynchronous operations | |
- supported by Backbone and jQuery | |
- <% doSomething.then(doSomethingElse) %> | |
- everything should belong somewhere | |
- controllers | |
- MVC is well-known | |
- drain your routers | |
- controllers are "finite" | |
- they can be paused (if not displayed) | |
- they can be destroyed | |
- monogamous components | |
- components should only interact with one application layer | |
- expand your component toolbox to what fits | |
- component toolkit | |
- ViewModel | |
- exports array of properties (passed to view) | |
- no events, just reflects the model | |
- DataStore | |
- model factory method | |
- RouterMap | |
- PageController | |
- enables a dependency graph of every page | |
- mobile constraints | |
- less memory & CPU power | |
- less screen space | |
- higher cost of requests | |
- page bundle (bundle of all the javascript for one page) | |
- concepts | |
- make extension easy | |
- mixins | |
- helpers (not member functions) | |
- helper modules, just add as a dependency | |
- create/document hooks | |
- pre/post route | |
- pre/post render | |
- small, unintrusive changes | |
- avoid branching and merging | |
- modify in place | |
- train release model | |
- train leaves every day (code is released) | |
- if you're ready, hop on the train (push a commit) | |
- otherwise, catch the next train (push to the next release) | |
- the frontend has a backend | |
- models are "backend" | |
- views are "frontend" | |
- think slowly | |
- Backbone's friends | |
- Fiber (inheritance) | |
- Q (promises) | |
- FastClick (touch events) | |
- Venus (test runner) | |
- AMD (module pattern) | |
# soundcloud breakout session | |
- waveforms | |
- generated on the server | |
- served to the client as JSON | |
- rendered using canvas | |
- views | |
- ID passed to the constructor | |
- instantiate models themselves | |
- models | |
- identity map to keep track of instances | |
- override the constructor | |
- if ID is found in custom store, return reference | |
- if not, fetch from server | |
- no relationships | |
- reference counting (to keep identity map from growing too big) | |
- custom store | |
- identity map | |
- iterated through once a minute | |
- models with a reference count of zero are removed | |
- play button | |
- uses a global event bus to propagate through application | |
- remote refresh | |
- client polls server every set interval | |
- used to force clients to update | |
- CSS | |
- loaded by component using require | |
- added as a style tag | |
- SEO | |
- no rendering on the server | |
- possibly putting information in a noscript tag | |
# i like my jQuery plugins warm and toasty | |
- talk | |
- slides: http://johnkpaul.github.io/presentations/backboneconf/2013/toasty-plugins/ | |
- Backbone views can be used to encapsulate widgets | |
- Backbone views | |
- widget initialization | |
- event binding | |
- organization | |
- Backbone view + jQuery plugin? | |
- old and busted: throw everything into initialize! (or render) | |
- new hotness: use defaults for plugin options | |
- design pattern: facade | |
- a simple interface that abstracts a more complicated process | |
- which parts differ between instances? | |
- does it need external configuration? | |
- hide plugin-specific parameters | |
- view's configuration should abstract the plugin | |
- does it need external control? | |
- expose methods on the view that call the plugin's methods | |
- does it need proxied events? | |
- bind jQuery plugins' events to methods on the view | |
- law of demeter: principle of least knowledge | |
# beyond jQuery widgets: JS UI library design | |
- talk | |
- slides: http://slid.es/pamelafox/js-ui-library-design | |
- jQsuery plugins | |
- standard to write UI libraries | |
- not perfect | |
- depend on jQuery | |
- inconsistent/non-existent architecture | |
- hide private functionality | |
- closures! | |
- idempotent constructor | |
- save instantiation info in the DOM | |
- customization | |
- parameters for widget options | |
- if instantiated on same element, take new options | |
- clear defaults | |
- declarative | |
- data-elements for specifying options in the DOM | |
- data-elements for construction | |
- observable | |
- should emit events developers can listen for | |
- AMD compatible | |
- should work with or without AMD | |
- dependencies | |
- jQuery (DOM manipulation) | |
- LucidJS (events) | |
- Q (promises) | |
- underscore (helpers) | |
- testable | |
- mocha | |
- jsdom | |
- chai | |
- sinon | |
# enterprise and the mobile web | |
- enterprise | |
- slow to adapt | |
- long-term view | |
- Backbone is closest to snap-in solution | |
- most popular framework | |
- plenty of plugins | |
- modularity | |
- built into Backbone's philosophy | |
- if you deleted all the view-related code, the library would still function | |
- extract reusable functionality into base classes | |
- composition can be used to resolve inheritance issues | |
- caching | |
- data stores | |
- local storage | |
- 5mb limit | |
- webSQL | |
- deprecated standard | |
- better support (for now) | |
- indexedDB | |
- transactional database | |
- key/value store | |
- polyfill | |
- asynchronous queries | |
- cacheable models | |
- name property to indicate bucket | |
- transaction to retrieve from cache | |
- fetch latest data from server | |
- offline | |
- offline actions should be synced to server when connection is restored | |
- override sync functions | |
- write model to local storage or server, depending whether or not online | |
- ask for write permission from database (serial instead of parallel transactions) | |
- what to write to the server when client comes back online? | |
- special bucket for unsynced actions | |
- only trigger success callback once event has fired twice (once locally, once to server) | |
- <% success = _.after(options.success, 2) %> | |
- create a cursor that loops through the store, syncing all the actions | |
- conflict resolution | |
- strategies | |
- client always wins | |
- if there's a conflict, server copy is overwritten | |
- server always wins | |
- if there's a conflict, client copy is overwritten | |
- custom resolution | |
- security | |
- keys | |
- app secret key | |
- create new user | |
- API granted key | |
- graduated levels of permissions | |
- q&a | |
- why override individual model sync functions instead of core Backbone ones? | |
- what if another model doesn't need the overridden version? | |
- functionality that is specific to a particular method | |
- tip (from someone who works at Simperium): use Simperium for syncing! | |
- why do conflict resolution client-side? | |
- enterprises want "data integration apps" | |
- all the data won't be in one silo | |
- APIs might not have built-in conflict resolution | |
- how to sync multiple items at once? (batch request or serial XHRs) | |
- depends on the backend | |
# Backbone at Disqus: a postmortem | |
- pre-Backbone | |
- inconsistent product experience | |
- CSS arms race | |
- overly-specific selectors | |
- !important | |
- difficult to introduce new features | |
- brittle, buggy | |
- ran a lot of code on the host page | |
- conflicts | |
- security and privacy issues | |
- user identity rendered on DOM in host page | |
- publisher can extract visitor information | |
- iframe | |
- Same-Origin Policy prevents access from parent | |
- can't be modified or inspected | |
- no more conflicts | |
- XSS vulnerabilities are contained | |
- not typical web application | |
- no address bar or permalinks | |
- loaded repeatedly, potentially multiple times per page | |
- short-lived | |
- backbone refactor | |
- project start: december 2011 | |
- beta: may 2012 | |
- release: june 2012 | |
- hurdles/solutions | |
- iframe | |
- problems | |
- no reference to the parent page | |
- doesn't resize to fit content | |
- doesn't know viewport size, URL, document fragment | |
- solution: Backbone + postMessage | |
- use postMessage to trigger events on message bus | |
- content-security policy | |
- http://benvinegar.github.io/csp-talk-2013 | |
- instance wrangling | |
- problems | |
- models appear multiple times, in different collections | |
- some models are "fresher" than others | |
- solution: Backbone.UniqueModel | |
- wraps the constructor of a model | |
- model is always unique | |
- later models are canonical | |
- event proxies | |
- problems | |
- instance replacement | |
- example: replacing different user models (guest, logged in user) on authentication | |
- solution: proxy model | |
- session is a model that contains a user | |
# resources | |
- http://backplug.io | |
- a searchable archive of Backbone plugins | |
- http://ricostacruz.com/backbone-patterns | |
- a list of Backbone patterns | |
- http://backbonerails.com | |
- series/screencasts on building apps with Backbone and Rails |
Thank you, good read!
Thanks! Here are just the links from the notes:
https://speakerdeck.com/backbonerails/little-opinions-big-possibilities-the-tools-and-patterns-for-building-large-scale-backbone-applications
https://speakerdeck.com/landau/test-driven-backbone-development
https://github.com/landau/tddbackbone
http://caliper.io/blog/2013/backboneconf-tooling-and-services-session/
http://bobholt.me/bbconf-bos-2013
https://speakerdeck.com/mwunsch/the-geologic-time-scale-of-gilt-dot-coms-view-layer
http://tumbledry.org/2011/05/12/screw_hashbangs_building
https://github.com/mwunsch/handlebars.scala
http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/
http://kristoferjoseph.com/Building-Reflow-BackboneConf-2013/
http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins
http://topcoat.io
http://tbranyen.com/talks/growing-up-with-backbone
https://github.com/tbranyen/growing-up-with-backbone
http://johnkpaul.github.io/presentations/backboneconf/2013/toasty-plugins/
http://slid.es/pamelafox/js-ui-library-design
http://benvinegar.github.io/csp-talk-2013
http://backplug.io
http://ricostacruz.com/backbone-patterns
http://backbonerails.com
Thanks all, backboneconf rocked! Already making plans for next year's!
Thanks for this! :D
Awesome! Much better note-taker than I am. Thanks a lot for sharing!
Brilliant notes, thanks! Hope you keep it up tomorrow ;)