Skip to content

Warn when suspending at wrong priority#15492

Merged
acdlite merged 2 commits intofacebook:masterfrom
acdlite:warn-suspense-priority
May 7, 2019
Merged

Warn when suspending at wrong priority#15492
acdlite merged 2 commits intofacebook:masterfrom
acdlite:warn-suspense-priority

Conversation

@acdlite
Copy link
Collaborator

@acdlite acdlite commented Apr 25, 2019

Adds a warning when a user-blocking update is suspended.

Ideally, all we would need to do is check the current priority level. But we currently have no rigorous way to distinguish work that was scheduled at user-blocking priority from work that expired a bit and was "upgraded" to a higher priority. That's because we don't schedule separate callbacks for every level, only the highest priority level per root. The priority of subsequent levels is inferred from the expiration time, but this is an imprecise heuristic.

However, we do store the last discrete pending update per root. So we can reliably compare to that one. (If we broaden this warning to include high pri updates that aren't discrete, then this won't be sufficient.)

My rationale is that it's better for this warning to have false negatives than false positives.

Potential follow-ups:

  • Bikeshed more on the message. I don't like what I landed on that much but I think it's good enough to start.
  • Include the names of the components that updated. (The ideal place to fire the warning is during the setState call but we don't know if something will suspend until the render phase. Maybe we could be clever and warn during a subsequent update to the same component?)

@sizebot
Copy link

sizebot commented Apr 25, 2019

Details of bundled changes.

Comparing: 89d8d14...95990bb

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js +0.4% +0.5% 818.8 KB 821.91 KB 186.62 KB 187.55 KB UMD_DEV
react-dom.development.js +0.4% +0.5% 813.21 KB 816.32 KB 185.06 KB 185.99 KB NODE_DEV
react-dom.production.min.js 0.0% -0.0% 103.7 KB 103.7 KB 33.15 KB 33.14 KB NODE_PROD
react-dom.profiling.min.js 0.0% -0.0% 107.03 KB 107.03 KB 33.99 KB 33.99 KB NODE_PROFILING
ReactDOM-dev.js +0.4% +0.5% 837.53 KB 840.83 KB 186.49 KB 187.47 KB FB_WWW_DEV
react-dom-unstable-fire.development.js +0.4% +0.5% 819.13 KB 822.23 KB 186.75 KB 187.7 KB UMD_DEV
react-dom-unstable-fire.development.js +0.4% +0.5% 813.53 KB 816.64 KB 185.19 KB 186.13 KB NODE_DEV
react-dom-unstable-fire.production.min.js 0.0% -0.0% 103.71 KB 103.71 KB 33.16 KB 33.15 KB NODE_PROD
react-dom-unstable-fire.profiling.min.js 0.0% -0.0% 107.04 KB 107.04 KB 34 KB 34 KB NODE_PROFILING
ReactFire-dev.js +0.4% +0.5% 836.72 KB 840.02 KB 186.49 KB 187.46 KB FB_WWW_DEV
ReactFire-profiling.js 0.0% -0.0% 337.72 KB 337.72 KB 62.36 KB 62.35 KB FB_WWW_PROFILING
react-dom-test-utils.production.min.js 0.0% 🔺+0.1% 10.56 KB 10.56 KB 3.89 KB 3.9 KB UMD_PROD
react-dom-unstable-native-dependencies.development.js 0.0% -0.0% 60.76 KB 60.76 KB 15.85 KB 15.85 KB UMD_DEV
react-dom-unstable-native-dependencies.production.min.js 0.0% -0.0% 10.69 KB 10.69 KB 3.67 KB 3.67 KB UMD_PROD
react-dom-unstable-native-dependencies.development.js 0.0% -0.0% 60.43 KB 60.43 KB 15.72 KB 15.72 KB NODE_DEV
react-dom-unstable-native-dependencies.production.min.js 0.0% -0.0% 10.43 KB 10.43 KB 3.57 KB 3.57 KB NODE_PROD
react-dom-server.browser.development.js 0.0% -0.0% 136.73 KB 136.73 KB 35.99 KB 35.98 KB UMD_DEV
react-dom-server.browser.production.min.js 0.0% -0.0% 19.14 KB 19.14 KB 7.22 KB 7.22 KB UMD_PROD
react-dom-server.browser.development.js 0.0% -0.0% 132.86 KB 132.86 KB 35.05 KB 35.05 KB NODE_DEV
react-dom-server.browser.production.min.js 0.0% -0.0% 19.07 KB 19.07 KB 7.21 KB 7.21 KB NODE_PROD
ReactDOMServer-dev.js 0.0% 0.0% 135.21 KB 135.21 KB 34.71 KB 34.71 KB FB_WWW_DEV
react-dom-server.node.development.js 0.0% -0.0% 134.81 KB 134.81 KB 35.6 KB 35.6 KB NODE_DEV
react-dom-server.node.production.min.js 0.0% -0.0% 19.93 KB 19.93 KB 7.51 KB 7.51 KB NODE_PROD
react-dom-unstable-fizz.browser.development.js 0.0% -0.1% 3.66 KB 3.66 KB 1.45 KB 1.45 KB UMD_DEV
react-dom-unstable-fizz.browser.development.js 0.0% -0.1% 3.49 KB 3.49 KB 1.41 KB 1.41 KB NODE_DEV
react-dom-unstable-fizz.browser.production.min.js 0.0% -0.2% 1.05 KB 1.05 KB 638 B 637 B NODE_PROD
react-dom-unstable-fizz.node.development.js 0.0% -0.1% 3.74 KB 3.74 KB 1.43 KB 1.43 KB NODE_DEV
react-dom-unstable-fizz.node.production.min.js 0.0% -0.1% 1.1 KB 1.1 KB 668 B 667 B NODE_PROD

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.6% +0.8% 557.39 KB 560.5 KB 121.75 KB 122.7 KB UMD_DEV
react-art.production.min.js 0.0% -0.0% 95.51 KB 95.51 KB 29.31 KB 29.3 KB UMD_PROD
react-art.development.js +0.6% +0.9% 488.34 KB 491.45 KB 104.34 KB 105.29 KB NODE_DEV
react-art.production.min.js 0.0% -0.0% 60.49 KB 60.49 KB 18.63 KB 18.63 KB NODE_PROD
ReactART-dev.js +0.7% +0.9% 497.45 KB 500.75 KB 103.41 KB 104.37 KB FB_WWW_DEV
ReactART-prod.js 0.0% -0.0% 194.78 KB 194.78 KB 33.14 KB 33.13 KB FB_WWW_PROD

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js +0.5% +0.7% 629.51 KB 632.82 KB 133.65 KB 134.61 KB RN_FB_DEV
ReactNativeRenderer-dev.js +0.5% +0.7% 629.43 KB 632.73 KB 133.62 KB 134.58 KB RN_OSS_DEV
ReactFabric-dev.js +0.5% +0.7% 618.27 KB 621.57 KB 130.9 KB 131.87 KB RN_FB_DEV
ReactFabric-prod.js 0.0% 0.0% 236.71 KB 236.71 KB 40.96 KB 40.96 KB RN_FB_PROD
ReactFabric-dev.js +0.5% +0.7% 618.17 KB 621.48 KB 130.87 KB 131.84 KB RN_OSS_DEV

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer.development.js +0.6% +0.9% 501.85 KB 504.96 KB 107.06 KB 108 KB UMD_DEV
react-test-renderer.development.js +0.6% +0.9% 497.39 KB 500.5 KB 105.95 KB 106.9 KB NODE_DEV
ReactTestRenderer-dev.js +0.6% +0.9% 508.14 KB 511.44 KB 105.66 KB 106.63 KB FB_WWW_DEV
react-test-renderer-shallow.production.min.js 0.0% -0.0% 11.54 KB 11.54 KB 3.54 KB 3.54 KB UMD_PROD
react-test-renderer-shallow.production.min.js 0.0% -0.0% 11.73 KB 11.73 KB 3.66 KB 3.66 KB NODE_PROD

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.6% +0.9% 485.87 KB 488.98 KB 102.78 KB 103.72 KB NODE_DEV
react-reconciler.production.min.js 0.0% -0.0% 61.42 KB 61.42 KB 18.37 KB 18.37 KB NODE_PROD
react-reconciler-persistent.development.js +0.6% +0.9% 483.78 KB 486.88 KB 101.9 KB 102.85 KB NODE_DEV
react-reconciler-reflection.production.min.js 0.0% -0.1% 2.43 KB 2.43 KB 1.09 KB 1.09 KB NODE_PROD

Generated by 🚫 dangerJS

@acdlite acdlite force-pushed the warn-suspense-priority branch 2 times, most recently from 07911d3 to 162af79 Compare April 25, 2019 01:39
//
// However, we do store the last discrete pending update per root. So we
// can reliably compare to that one. (If we broaden this warning to include
// high pri updates that aren't discrete, then this won't be sufficient.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really should have this warning too since it's pretty important to fix the mousemove events to have this property and we really shouldn't suspend there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thoughts on implementation then? I could track the high pri times per root in dev.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can get back to it later. I suspect I'll need to track some new field for suspendIfNeeded. Maybe we can use that.

Adds a warning when a user-blocking update is suspended.

Ideally, all we would need to do is check the current priority level.
But we currently have no rigorous way to distinguish work that was
scheduled at user- blocking priority from work that expired a bit and
was "upgraded" to a higher priority. That's because we don't schedule
separate callbacks for every level, only the highest priority level per
root. The priority of subsequent levels is inferred from the expiration
time, but this is an imprecise heuristic.

However, we do store the last discrete pending update per root. So we
can reliably compare to that one. (If we broaden this warning to include
high pri updates that aren't discrete, then this won't be sufficient.)

My rationale is that it's better for this warning to have false
negatives than false positives.

Potential follow-ups:
- Bikeshed more on the message. I don't like what I landed on that much
but I think it's good enough to start.
- Include the names of the components that updated. (The ideal place to
fire the warning is during the setState call but we don't know if
something will suspend until the next update. Maybe we could be clever
and warn during a subsequent update to the same component?)
@acdlite acdlite force-pushed the warn-suspense-priority branch from 162af79 to 0e8acda Compare May 7, 2019 22:09
@acdlite acdlite force-pushed the warn-suspense-priority branch from 0e8acda to 95990bb Compare May 7, 2019 23:02
@acdlite acdlite merged commit f9e60c8 into facebook:master May 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants