by @timplourde
This resource is inspired by this great talk by Ryan Niemeyer and my own experience in building non-trivial apps with Knockout. It's purpose is to identify common anti-paterns in Knockout-heavy apps and suggest ways to avoid them.
You should have a basic understanding of Knockout before proceeding.
Before we begin it's very important to emphasize the importance of unit testing. If you are not unit-testing your Knockout ViewModels with something like QUnit or Jasmine, just stop reading. Nothing is more vital to the long-term health of a JavaScript app than solid unit test coverage.
Knockout is great because it does one thing very well: data binding. After just a few hours learning Knockout, you be building complex apps and impressing your friends in no time.
The key to making sure those fancy apps are sustainable is to stick to the MVVM pattern. Don't worry if you don't have a PhD in MVVM. The main thing you need to remember is the ViewModel should not know about the View (HTML, CSS, DOM). This simple rule will help you build testable and maintainable apps.
Once your VM has any knowledge of the DOM then it knows about your View. This breaks MVVM, makes unit testing more cumbersome (because you need to set up / tear down DOM nodes) and yields brittle code. With Knockout binding handlers there is really no reason to have any DOM-related code in your ViewModels.
This is contraversial since it appears in the Knockout documentation. Avoid generating CSS class names from ViewModels if those class names have no semantic meaning and only exist for visual styling.
ko.applyBindings() binds the ViewModel to the DOM. You shouldn't call it from inside a ViewModel constructor function since it directly affects the DOM and should really only be run once if all your HTML is available at startup time.
Be prudent in your use of knockout's powerful observables. Too many subscriptions can lead to performance issues which can be tough to refactor in large code bases.
These may be more performance optimizations than patterns but if it results in better code then mission accomolished!
Every observable has a cost. If you're dealing with large objects or collections, make sure you are only observing things that will change.
Subscribing to changes, intercepting the value and setting the value again triggers unnecessary dependency tracking. Use extenders instead.
Be careful not to bind DOM events for every element in an array if it's not necessary.
Throttle computed's for easy performance wins.
HTML can't (practically) be unit tested, so reduce the amount of logic in the HTML as much as possible.
Move logic into ViewModels so it can be unit-tested.
This happens as application scope grows over time. Try to minimize the ammount of ko: if statements in your HTML.
Building rich "controls" can result in a lot of repeated code if you're not careful.