sinnede
sinnede

Reputation: 93

Optimize updating redux state

I have a web application that received an update from websocket, like 100 messages per second.

I am using immutable helper and tried this

const parentIndex = action.payload.data.findIndex( i => i.id===action.id)
if(parentIndex !== -1) {
  const childIndex = action.payload.data[parentIndex].child.findIndex(c=>i.id===action.childId)
  if(child !== -1) {
     const lastChildIndex = action.payload.data[parentIndex].child[childIndex].lastChild.findIndex(l=>l.id===action.lastChildId)
     return lastChildIndex=== -1
     ? update(state, {   // insert
         data: {
           [parentIndex]: {
             child: {
               [childIndex]: {
                 lastChild: {
                   $push: [{
                      parentId: action.id,
                      childId: action.childId,
                      lastChildId: action.lastChildId,
                      price: action.payload.price
                   }]
                 }
               }
             }
           }
         }
       })
      : update(state, {   // update
         data: {
           [parentIndex]: {
             child: {
               [childIndex]: {
                 lastChild: {
                   [lastChildIndex]:{
                     price:  { $set: action.payload.price},
                     isUpdated: { $set: true}
                   }
                 }
               }
             }
           }
         }
       })
  }
}

Example Data:

data = [
  {
    parentId: 123,
    itemName: 'John Doe',
    child: {
      childId: 456,
      childName: 'I am child one',
      lastChild: {
        lastChildId: 789,
        price: 143  
      }
    }
  },
  {
    parentId: 321,
    itemName: 'John Wick',
    child: {
      childId: 654,
      childName: 'I am child wick',
      lastChild: {
        lastChildId: 987,
        price: 44  
      }
    }
  }
]

This seems to be work with 5 array of data at least but when the data is more than 15, the browser seem to be slow, memory leak and soon crashed..

Finding an index everytime there is a message that being pushed to the app will kill the browser.

I am using redux-thunk as middleware.

If you can recommend me something that will update/insert faster, better way and seamless. That would be super cool.

Upvotes: 3

Views: 618

Answers (3)

markerikson
markerikson

Reputation: 67567

Three observations:

  • You probably don't need to be updating the UI 100 times per second. You should throttle or batch the websocket updates so that there's fewer updates to the state, and thus fewer updates to the UI.
  • Rather than using immutable-helper for immutable updates, I'd encourage you to use Immer. It's much simpler and easier to use. Even better, use our new Redux Starter Kit package, which has Immer built-in.
  • as @Aleks said, you should try to normalize your state shape so you aren't dealing with as much nested data.

Upvotes: 1

Doug
Doug

Reputation: 6497

First address this:

a web application that received an update from websocket, like 100 messages per second

You should throttle or debounce these so you are not updating the state for every message. Or reduce the amount of messages if you can. Or both.

Once you get this out of the way, the app should probably work fine. But you could still make some improvements:

Given this action:

{
  payload: {
    parentId: 123,
    childId: 321,
    lastChildId: 555,
    price: 50
  }
}

Your reducer will look like this:

const { parentId, childId, lastChildId } = action.payload;
const childItem = state[parentId][childId][lastChildId];
const newState = {...state}
newState[parentId][childId][lastChildId] = {...childItem, ...action.payload};

return newState;

If I know I will need to be finding the specific item like you are doing here, I choose a map instead of an array.

Upvotes: 3

Aleks
Aleks

Reputation: 984

How about ditching arrays and making a store like this.

    {
     id: {
           childId:{...data,etc..},
           childId2:{},
           ... 
         },
     id2: {...},
     ...
    }

You can access ids with store.data[id].child[index]

In short that would be

if(store.data[parentIndex]&&store.data[parentIndex][childIndex]){
  !!!
}else{
  :(((
}

Upvotes: 0

Related Questions