ractivejs/ractive — pull request #814 by martypdx (2014-06-14 20:25:37+00:00)
Title: Use prototype for defaults and performance improvements

Still a WIP, though all the tests are green.

TL;DR:
* `Ractive.defaults === Ractive.prototype`
* `Component.defaults === Component.prototype `
* Instantiating 100,000 empty new Ractive
* 4.0: ~15s
* current edge: ~17s
* this PR: ~ 7.5s
* ~600 < LOC and more to go ( I added 1800 last PR )

Having defaults same as prototype means less copying for extend and init (which are quicker because of it). While lookup can be slightly longer (~17%) to walk prototype chain, it's a small amount of very quick operation (basically 14ms versus 7ms for lookup of four keys 1M times!).

It also means defaults are "live" on the prototype chain, like registries are. So fixes issues like #805.

My motivation in bringing down the 100,000 instances is to make components usable in large numbers.

Biggest gain is not using `defineProperties` in init:
* Stopped using `Object.create(obj, props)` for extension (`Object.create(obj)` is ok, comparable to `new F() + copying keys`)
* Assigned "private" ractive properties like `ractive._patternObservers` directly to `ractive` instance. This does means someone can bork things by setting those props. However, we are moving those into their respective part (like `ViewModel`), so I think they will largely go away anyway off the `ractive` instance.
* Plugin repositories are also writable on the Ractive and Component instances, because in javsacript you can't set a property that's shadowed by a prototype that's not writable. So to avoid defineProperty in init, we have to not have the registries be non-writable.

I have some more code to remove that will help bring these times down a bit more. I also want to do more profiling with configuration data, not just empty instances.

Of course, this is just init, render is probably the bulk of time. But no reason to start off any slower than we have to!

Also, we might at some point may want to introduce a `lightWeight: true` option for components and instances that avoids things like assigning default `{}` repository values (which exist so you can change values dynamically) create guid's for instances (currently about almost 10% of total time). Will need to look at total time (init, viewModel, render, etc.) to see where blocks are.