skip to Main Content

I understand that one of the distinctions between useEffect and useLayoutEffect is as follows:

  • useEffect triggered after paint
  • useLayoutEffect triggered before paint and block the browser paint process

However, why does the following useEffect trigger before paint?

  1. useEffect triggered before paint
performance.mark('start')
const App = () => {
  useEffect(() => {
    performance.mark('end-useEffect')
    performance.measure('useEffect triggered', 'start', 'end-useEffect');
  }, [])
  return (
    <div>123</div>
  )
}

enter image description here

  1. use useEffect and useLayoutEffect together: useEffect triggered after paint
performance.mark('start')
const App = () => {
  useEffect(() => {
    performance.mark('end-useEffect')
    performance.measure('useEffect triggered', 'start', 'end-useEffect');
  }, [])
  useLayoutEffect(() => {
    performance.mark('end-useLayoutEffect')
    performance.measure('useLayoutEffect triggered', 'start', 'end-useLayoutEffect');
  }, [])
  return (
    <div>123</div>
  )
}

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    I found an insightful article in explaining this with exceptional detail.

    https://jser.dev/2023-08-09-effects-run-paint/

    Short answer:

    useEffect() callbacks are run after DOM mutation is done. Most of the time, they are run asynchronously after paint, but React might run them synchronously before paint when it is more important to show the latest UI(for example when re-render is caused by user interactions or scheduled under layout effects), or simply if React has the time internally to do so.


  2. I found a helpful article that dives into this topic and provides insights, you can refer this- https://thoughtspile.github.io/2021/11/15/unintentional-layout-effect/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search