React Comlink Web Worker блокирует пользовательский интерфейс - PullRequest
1 голос
/ 28 мая 2020

Я запускаю длительный процесс через Comlink. Пока веб-воркер работает, обновления состояния реакции не приводят к немедленному обновлению пользовательского интерфейса, только с задержкой на несколько секунд, а затем внезапно все сразу "буферизуются".

Подробности:

onStartWalkForward запускается нажатием кнопки.

Проблема начинается уже при первом обновлении состояния:

this.setState({walkForwardLog: ["Starting WFO..."]})

Состояние немедленно обновляется, и немедленно вызывается функция WFOLog, которая получает состояние как свойство, пока все хорошо. Но UI обновляется не сразу. Только через 5-7 секунд. Кажется, что-то блокирует пользовательский интерфейс, потому что после этой задержки 5-7 se c в консоли внезапно появляется несколько строк журнала, говорящих мне, что функция WFOLog вызывалась несколько раз во время этой задержки.

Это то же самое поведение для следующих обновлений состояния, где используется обратный вызов writeWfoLog. Я могу сказать, потому что console.log("Revieved Text: " + text) и мой журнал функции журнала отображаются в консоли за 5-6 секунд до того, как пользовательский интерфейс показывает тот же текст. После задержки, как описано выше, в журнале консоли внезапно появляется несколько строк.

Может ли кто-нибудь объяснить мне, почему и что я могу сделать, чтобы улучшить это поведение пользовательского интерфейса?

Вот код:

index. js

  onStartWalkForward = async(percOos100, cycleCount, selectedStartDate) => {

    let dataLoaded = await this.onLoadWFOData(selectedStartDate)

    if(dataLoaded) {      
      this.setState({walkForwardLog: ["Starting WFO..."]})

      let samples = await wfUtils.getSamplesForWfo(this.state.wfoSets, percOos100, cycleCount)

      await wfUtils.startNew(this.state.selectedStrategyIndex, 
                    this.state.exposedStrategyProperties.map(p => {return {name: p.name, range: this.state[p.name].range}}),
                    samples, 
                    this.writeWfoLog)         
    }
  }

  writeWfoLog = async(text) => {
    console.log("Revieved Text: " + text)  

    let log = this.state.walkForwardLog;        
    log.push(text)     
    this.setState({walkForwardLog: log})
  }

wfUtils. js

export async function startNew(selectedStrategyIndex, exposedStrategyProperties, samples, writeWfoLog) {

    const obj = new WfoWorker()

    const wfoWorker = Comlink.wrap(obj);

    for (let i = 0; i < samples.length; i++) {
        await writeWfoLog(`Running Optimization ${i+1} of ${samples.length}...` )        

        await wfoWorker.optimize(
            selectedStrategyIndex, 
            exposedStrategyProperties,
            samples[i], 
            i+1,
            samples.length
        )            

        let bestCombination = await wfoWorker.bestCombination   

        let bestCombinationText = bestCombination.split(";").map(p => Number.isInteger(p) ? parseInt(p) : parseFloat(p)).join(";");    

        await writeWfoLog("BC: " + bestCombinationText)                
    }

    await writeWfoLog("Finished WFO.")
}
...