Yomguithereal / baobab

JavaScript & TypeScript persistent and optionally immutable data tree with cursors.
MIT License
3.15k stars 115 forks source link

question on immutable in production #476

Open shenbin04 opened 7 years ago

shenbin04 commented 7 years ago

in the readme regarding immutable, it reads

immutable boolean [true]: should the tree's data be immutable? Note that immutability is performed through Object.freeze and should be disabled in production for performance reasons.

What does this mean by should be disabled in production? Do we need to do anything specifically for production?

Thanks

Yomguithereal commented 7 years ago

This means that if you developed with immutable set to true, there is no danger to switch to false when in production (unless you do really strange things with your code) to increase performance for your users.

shenbin04 commented 7 years ago

@Yomguithereal thanks. So here is the follow up from my understanding: 1) what baobab does is preventing other calls from mutating the object get from baobab tree directly via freezing. 2) if I use baobab set api to make the changes, baobab takes care of immutable change so that it complies with the policy.

Essentially, I should not mutate the data get from baobab tree directly, rather use update api provided by baobab. Correct?

Thanks.

Yomguithereal commented 7 years ago

Essentially, I should not mutate the data get from baobab tree directly, rather use update api provided by baobab. Correct?

That's correct. The fact is if you try to mutate the objects given by the tree with immutable on it won't work anyway since the objects are frozen. But since it has a cost to freeze them, you can disable this in production because you don't need the "safeguards".

shenbin04 commented 7 years ago

@Yomguithereal Thanks. Another followup question:

    const tree = new Baobab({ hello: { world: 123 }, apple: { pie: 456} });
    const initialState = tree.get();
    tree.set('hello', { world: 123 });
    console.log(initialState === tree.get());
    console.log(initialState.hello === tree.get('hello'));
    console.log(initialState.apple === tree.get('apple'));

For the sample code above, I tried to set the value of tree using the same equal value. I got logs of false, false, true. Seems baobab is swapping the reference even if the value itself is equal. I'm trying to integrate this into react pure rendering, so optimally I will expect the reference is unchanged if the value itself remains the same.

Is this expected behavior of baobab or we didn't take care of this case? Thanks.

shenbin04 commented 7 years ago

a followup finding: if I use tree.set(['hello', 'world'], 123);, the result will be true, true, true

Yomguithereal commented 7 years ago

Yes, this behavior is to be expected because Baobab cannot tell whether your { world: 123 } values are the same without performing costly diff operations. So, whenever possible, i.e. with scalar values, the tree can know if the update is a no-op. But in some other cases, it won't compute the differences for performance reasons.