3

So I have a method that takes a while to finish (>20 seconds), its doing a bunch of math and CPU heavy stuff, that's why it takes so long. While it is running, it calls setState several times and the state correctly updates and render() is called. However, the component isn't rerendered on the web page, but it does rerender after the method finishes.

I'm fairly sure that the method is pegging the CPU and React is not rerendering because of that. Is there a way to pause the execution of the method for a little bit in order for the webpage to rerender? Or is there a way to force the page to rerender?

class FibonacciPage extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      n: 0
    }
    // compute to 1000th place
    this.nth = 1000
  }

  fibonacci(nth) {
    console.log(nth)
    this.setState({
      n: nth
    })
    if (nth < 2) {
      return 1
    } else {
      return this.fibonacci(nth - 1) + this.fibonacci(nth - 2)
    }
  }

  componentDidMount() {
    this.fibonacci(this.nth)
  }

  render() {
    console.log("RENDER")
    return ( <p> {this.state.n} </p>
    )
  }
}

ReactDOM.render(<FibonacciPage />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>

This snipped may not show its point in the browser because it uses console.log and I don't know if you can see that.

6
  • 2
    Might be worth looking into webworkers if it's computationally heavy as those generally block the main thread, that would allow the main page to stay responsive. Commented Dec 15, 2020 at 15:50
  • Have you set the key? Sometimes React thinks there have been no changes so it does not redraw items. Setting the key will make it rerender. Commented Dec 15, 2020 at 15:50
  • 2
    I find it very odd (and difficult to believe) that render is being called while your function is running; that would suggest React was calling it during setState, which it doesn't to my knowledge. Please update your question with a minimal reproducible example demonstrating the problem, ideally a runnable one using Stack Snippets (the [<>] toolbar button). Stack Snippets support React, including JSX; here's how to do one. Commented Dec 15, 2020 at 15:52
  • @T.J.Crowder render() is definitely being called as I have console.log lines everywhere. I will update my question in a bit. Commented Dec 15, 2020 at 16:52
  • 1
    Thanks for the MRE. When I run that (with a smaller number) I don't see any logging for render until the end. I see the ones in fibonacci, but not the one in render. Commented Dec 15, 2020 at 17:53

1 Answer 1

1

It's not that it's pegging the CPU (though of course it could be pegging one of the cores), it's that there's only one browser thread used for running your JavaScript and updating the page display. As long as your method is running, the browser can't update the display of the page.

Is there a way to pause the execution of the method for a little bit in order for the webpage to rerender? Or is there a way to force the page to rerender?

To do that, you have to:

  1. Break your function up into chunks and run each chunk separately, using setTimeout or similar to schedule the next chunk. By doing that, you let the thread exit your JavaScript code and get used by the browser to repaint the page.

    or

  2. Move your computationally-heavy code to a web worker (spec, MDN), so it can run in parallel with page updates, keeping your page responsive even though the method is doing heavy computation.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, the hint about the web worker was all I needed!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.