Как обходить слишком часто обновления Redux в приложении React?

1

У меня есть браузерное приложение с архитектурой React-Redux. В приложении происходит много событий (например, тайм-ауты, входящие сообщения через веб-сокет, сообщения веб-работников, ответы XHR и т.д.). Каждое событие генерирует действие Redux, которое изменяет хранилище Redux, которое вызывает рендеринг React.

Проблема в том, что события происходят так часто, что React не имеет достаточно времени для визуализации пользовательского интерфейса (например, событие происходит каждые 5 мс (или чаще), а React требуется 10 мс для визуализации пользовательского интерфейса). Это приводит к тому, что вся страница перестает отвечать на запросы, потому что процесс рендеринга не останавливается (у него всегда есть что-то для рендеринга), и у браузера нет времени рисовать DOM или обрабатывать событие DOM.

Каковы подходы или готовые решения для решения этой проблемы, учитывая, что я не могу уменьшить ни частоту событий, ни время рендеринга React?

  • 0
    Я не уверен, будет ли каждое обновление данных менять значение? Если это не так, может быть, вы можете попробовать memoization ? reactjs.org/blog/2018/06/07/...
  • 0
    @tekminewe Я использую React.PureComponent и имею в виду обновления, которые меняют значения. В любом случае, подход «уменьшить время рендеринга React» не всегда подходит.
Показать ещё 6 комментариев
Теги:
performance
redux

2 ответа

1

Когда вы обновляете состояние из сообщения веб-сокета, запишите время и делайте еще одно обновление, только если с тех пор прошло определенное время.

В этом примере состояние обновляется, только если прошло 1000 мс с момента последнего обновления:

client.onUpdate(data => {        
    if (!this.lastUpdate || 
        new Date().getTime() - this.lastUpdate.getTime() > 1000) {
        this.setState({ data });
        this.lastUpdate = new Date();
    }
})
  • 0
    Видимо, состояние хранится в компоненте React (не в хранилище Redux) в вашем примере. Но у меня есть идея, спасибо.
  • 0
    @ Изящество да, это для реагирования, а не излишней, но идея та же самая. Я также только что понял, что lastUpdate не должно храниться в состоянии, так как представление не зависит от него и оно асинхронно
0

Вы можете просто отменить ваш обработчик.

Функция debounce означает, что она может быть вызвана только один раз за X период времени.

Для примера я не буду реализовывать детали отмены функции, а использую lodash.

// function that handles the server update.
const serverUpdateHandler = (dispatch) => {
  dispatch({
    type: SERVER_UPDATE
  })
}
// create a new function that is debounced. aka - will invoke after 250 milliseconds after the lace invokation
const debouncedHandler = _.debounce(serverUpdateHandler,250);
// pass socket.io the debounced function
socket.on('server-update',debouncedHandler)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню