3

I wanted to make an object where you could not directly mutate the variables so I decided to create what is essentially a store with a reducer similar to redux. When I return the store with the get() function I am returning a copy of the store instead of the original store so it cannot be mutated directly. There are variables in the store that I want to remain untouched throughout the controller.

My question is are there any serious performance tradeoffs that I should be aware of when making a copy of the object vs returning the entire object. The get() function will be used a lot so many copies will be made. I also use it in a requestAnimationFrame function where the get() function will be called a lot back to back for each animationFrame. I assume that the old copy will be removed from memory when no longer in use but I am not for sure.

Here is a very simple example.

const reducer = (store, action) => {
    switch(action.type) {
    case 'SET_FOO':
        return {
        ...store,
        foo: action.payload
      }
    case 'SET_BAR':
        return {
        ...store,
        bar: action.payload
      }
    default: 
        return store
  }
}



const createController = () => {
    let store = {
    foo: 'foo',
    bar: 'bar'
  }
  
  const get = () => ({...store})
  
  const dispatch = (action) => (store = reducer(store, action)) 
  
  // A bunch of other irrelevant functions here
  
  return {
    get,
    dispatch
  }
} 

As you can see in the get() function I am sending a copy of the store back instead of the actual store. This way it is impossible for the person creating the controller to mutate the store directly. If I just returned the store you could do something like the following and directly mutate the store which I am trying to avoid.

const ctl = createController()

const store = ctl.get()

store.foo = 'baz'

console.log(store.get().foo)

// result would be 'baz'

But if you send back a copy of the store then they could not directly mutate the store but instead you would have to dispatch to the reducer to mutate it. But are there any serious performance concerns that I should take in consideration here. I know adding more objects can use more memory but I don't think it would make a huge difference.

Any insights would be appreciated. Thanks

user3331344
  • 728
  • 8
  • 23
  • 1
    Well, I don't really know how to answer this as you kind of answered it yourself. The more data, the more memory is required and the more time is needed for a copy. Depending on your definition of **more** and **serious** you can expect *serious* impacts on performance. It very much depends on your use case. Maybe [this thread](https://stackoverflow.com/questions/30194088/do-javascript-variables-have-a-storage-limit) will give you some insight. In most use cases it certainly won't matter. Sorry if that's not the greatest answer but I don't really have a better one. – Mushroomator Apr 28 '22 at 22:10
  • @Mushroomator I am most concerned in that it will be used in a `requestAnimationFrame` where the `get()` function will be called a lot back to back for each `animationFrame`. I'm assuming that the old copy will be removed from memory during each `animationFrame` but I am not for sure. I cannot see any huge issues in dev tools but that is my main concern. I will update the question with this info as well. – user3331344 Apr 28 '22 at 22:22
  • Yes, memory will be released when it is no longer needed. However that's not as easy a task as it sounds and it's not necessarily predictable. Maybe this article in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management) about memory management will give you some insight. – Mushroomator Apr 28 '22 at 22:32
  • 1
    As an alternative, you could cache a copy that has been frozen using [Object.freeze](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) and return that same object from your `get()` method. If you'd able to detect when the object is modified in some way, which it sounds like you are, then you could re-generate your frozen copy when that happens. This would let you save on the number of copies being created by reusing the same immutable copy. – Mark Hanna Apr 28 '22 at 22:54

0 Answers0