Optimizing Knockout / TKO - Alpha3

2019-03-13 17:24发布

In the process of modernizing Knockout for version 4.0 (now live at the monorepo tko), I've hit some performance issues.

Among other changes, some inner-loop things have been converted to ES6 classes, and it's causing some major performance problems. I'd rather not undo that effort as it adds quite a bit of clarity to some key code, so I'd like to solicit some input on how to improve the ES6 code.

I've set up some simple samples for profiling here:

Knockout Alpha2 - 349ms

Knockout Alpha3 (prerelease) - 622ms

The code in the jsFiddles is as follows, and it's prototypical of the slowdowns being experienced across a number of bindings.

HTML:

<div id='x'>
  <strong>{{ count }} / {{ time }} ms</strong>
  <custom-component></custom-component>
</div>

<div id='cc-template'>
   cc
   {{# unless: finished }}
      <custom-component></custom-component>
   {{ /unless }}
</div>

Javascript:

let count = ko.observable(0)
let time = ko.observable(false)
const start = performance.now()
const ITERATIONS = 1000

class viewModel {
  constructor () {
    this.finished = count() > ITERATIONS
    count(count() + 1)
    time(performance.now() - start)
  }
}

ko.components.register("custom-component", {
  viewModel, template: {element: 'cc-template'}
})

ko.applyBindings({count, time}, document.getElementById('x'))

If you compare the Javascript profiles, the call trees are nearly identical (notwithstanding e.g. the ES6 changes). It looks like the extra time in Alpha3 is at the leaf calls, making them harder to identify, so I speculate based on the profile comparisons that the problem is a few fold, including:

  • some non-optimizing or de-optimizing happening
  • some loops replaced with slower, native calls e.g. Array.from
  • more intermediate minor garbage collections
  • less native optimization for ES6isms

In any case I haven't rooted out which, if any of these, is the problem yet – or where exactly they might be occurring.

I would be most grateful for insights and help identifying where we can make optimizations to get the performance back up to, or even above, par.

1条回答
太酷不给撩
2楼-- · 2019-03-13 17:55

To consolidate any answers, I've started an answer as a wiki:

  • Remove inappropriate & unnecessary dependency chaining with template and if/ifnot/unless/with/else and foreach bindings — 3074AA9
查看更多
登录 后发表回答