BosNaufal / vue-freeze

Simple state management whitout bloating API and Concept for Vue.js.
https://bosnaufal.github.io/vue-freeze
MIT License
74 stars 4 forks source link

NPM? #3

Open ghost opened 8 years ago

ghost commented 8 years ago

Why are you not publishing to NPM? This package looks great - love the simplicity. Please publish.

BosNaufal commented 8 years ago

Hey @chrismbeckett, Thanks for making it usefull! :grin: I've just published "vue-freeze" package on NPM. Check it out!

ghost commented 8 years ago

I did a lot of testing of vue-freeze last night and actually rewrote your code a few different ways to test out some various scenarios. Here is an updated snippet using a singleton Vue component to store state rather than copy it to every component.

    // create a new freezer
    const store =  new Freezer( opts.state, opts.freezer )

    // create a private vue component to maintain
    // a reactive singleton with our immutable state reference
    const vm = new Vue( {
      'data': {
        'state': store.get()
      },
      'created': function() {
        store.on( 'update', () => {
          this.$set( 'state', store.get() )
        } )
      }
    } )

    // expose a global $store property on all components
    // with custom dispatcher and reactive state
    Object.defineProperty( Vue.prototype, '$store', {
      'enumerable': true,
      'get': function () {
        return {
          'dispatch': ( ...args ) => {
            args.push( vm.$data.state )
            store.trigger.apply( store, args )
          },
          'state': vm.$data.state
        }
      }
    } )

You can see in this approach, that I am keeping an internal singleton Vue component with an updated immutable copy of the store data which I then inject into a single $store property in a component to provide both the dispatch and state (yes, the state provided like this is reactive, so bindings to $store.state.x.x recompute when the store changes).

The problem with both your implementation (updating a copy of the state on each component) and mine (a singleton copy of the state), is that every binding is recomputed on any change to any property in the store.

After researching some of the Freezer materials, it appears the preferred approach is that in each component you keep local state partials (only the references to the state you use). On the update event, you compare your local state to the new state, and if your sub-tree has not changed, you ignore it. In other words, there needs to be logic specific to each component to verify whether it needs to grab it's new state and re-render. One of the stated performance aspects of Freezer is that it does not change any parts of the sub-tree if they have not been modified during a change.

I am concerned that once you have dozens or hundreds of bindings on a page, that recomputing them all every time any property in the store changes may cause a lot of performance and rendering problems.

I am testing Vuex now to see how they handle it.

ghost commented 8 years ago

Confirmed - if you use VueX, only the bindings for the specific properties of the store that changed are recomputed, making the reactivity very efficient. To use Freezer properly as an alternative to Redux/Vuex, the Freezer documentation recommends that each component listen directly to the store update and evaluate whether the sub-tree state it uses has specifically changed.

BosNaufal commented 8 years ago

Thank you for helping me to find out about it :grin:

That problem was the cause why I didn't publish it to NPM. Cause I have tested it when I build Vue Mini Shop, and it makes all my component do "re-render" whenever state changed. So I decided to make vue-simple-store as an alternative.

I've posted a question in stackoverflow and nobody answer. Now, You give me the answer. thanks a lot, @chrismbeckett.

But, Honestly, I don't know where to start to solve this issue :grin:

ghost commented 8 years ago

Sorry for the misfirenon this. FYI - the new NPM rules only allow you to unpublish up to 24 hours after you publish. If you don't want people using this because of this problem then you can still unpublish.

I am still using Freezer-js, but I am injecting the store and listening to it directly in my components. I can share my code tomorrow.

kharysharpe commented 8 years ago

The README says its working now....but did you ever fix this? or should we be using vue-simple-store instead?

BosNaufal commented 8 years ago

Hi @kharysharpe, I'm sorry for that. But For now, use the vue-simple-store instead :grin:

kharysharpe commented 8 years ago

Cool np. Thanks

Em-AK commented 7 years ago

Hi @BosNaufal, I suggest you mention the current limitations of the lib in the README with a link to the issue :wink: