xaviergonz / mobx-keystone

A MobX powered state management solution based on data trees with first class support for Typescript, support for snapshots, patches and much more
https://mobx-keystone.js.org
MIT License
554 stars 25 forks source link

Unnecessary loops causes low performance, how to optimize the performance #527

Closed hardylab closed 1 year ago

hardylab commented 1 year ago

I am developing an outlining note-taking tool based on react and mobx-keystone, and I encouter a problem: when the outline tree grows too large (with about 2000 nodes), every action handled by mobx-keystone is rather slow, I debug it via "chrome performance", and locate the slow part of mobx-keystone as follow:

// 'coreObjectChildren.ts'

const updateDeepObjectChildren = action((node: object): DeepObjectChildren => {
  const obj = getObjectChildrenObject(node)!
  if (!obj.deepDirty) {
    return obj
  }

  const data: DeepObjectChildren = {
    deep: new Set(),
    extensionsData: initExtensionsData(),
  }

  const childrenIter = obj.shallow.values()
  let ch = childrenIter.next()
  while (!ch.done) {
    addNodeToDeepLists(ch.value, data)

    const ret = updateDeepObjectChildren(ch.value).deep
    const retIter = ret.values()
    let retCur = retIter.next()
    while (!retCur.done) {
      addNodeToDeepLists(retCur.value, data)
      retCur = retIter.next()
    }

    ch = childrenIter.next()
  }

  Object.assign(obj, data)

  obj.deepDirty = false
  obj.deepAtom.reportChanged()

  return obj
})

Each action will trigger the loop 'while (!ch.done)', in a 2000-nodes model tree, the loop count can be up to 50000 times.

according to the above information, how can I optimize the performance ?

xaviergonz commented 1 year ago

could you please provide some example code that shows this behavior?

xaviergonz commented 1 year ago

Closing due to lack of info, feel free to reopen