Skip to content

Commit

Permalink
[DevTools] permanently polyfill for rAF in devtools_page (facebook#26193
Browse files Browse the repository at this point in the history
)

## Summary

We had this as a temporary fix for facebook#24626. Now that Chrome team decides
to turn the flag on again (with good reasons explained in
https://bugs.chromium.org/p/chromium/issues/detail?id=1241986#c31), we
will turn it into a long term solution.
In the future, we want to explore whether we can render React elements
on panel.html instead, as `requestAnimationFrame` produces higher
quality animation.

## How did you test this change?

Tested on local build with "Throttle non-visible cross-origin iframes"
flag enabled.
  • Loading branch information
mondaychen authored Feb 23, 2023
1 parent bfb9cbd commit ca2cf31
Showing 1 changed file with 14 additions and 23 deletions.
37 changes: 14 additions & 23 deletions packages/react-devtools-extensions/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,20 @@ const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY =
const isChrome = getBrowserName() === 'Chrome';
const isEdge = getBrowserName() === 'Edge';

// since Chromium v102, requestAnimationFrame no longer fires in devtools_page (i.e. this file)
// mock requestAnimationFrame with setTimeout as a temporary workaround
// https://github.com/facebook/react/issues/24626
if (isChrome || isEdge) {
const timeoutID = setTimeout(() => {
// if requestAnimationFrame is not working, polyfill it
// The polyfill is based on https://gist.github.com/jalbam/5fe05443270fa6d8136238ec72accbc0
const FRAME_TIME = 16;
let lastTime = 0;
window.requestAnimationFrame = function (callback, element) {
const now = window.performance.now();
const nextTime = Math.max(lastTime + FRAME_TIME, now);
return setTimeout(function () {
callback((lastTime = nextTime));
}, nextTime - now);
};
window.cancelAnimationFrame = clearTimeout;
}, 400);

requestAnimationFrame(() => {
clearTimeout(timeoutID);
});
}
// rAF never fires on devtools_page (because it's in the background)
// https://bugs.chromium.org/p/chromium/issues/detail?id=1241986#c31
// Since we render React elements here, we need to polyfill it with setTimeout
// The polyfill is based on https://gist.github.com/jalbam/5fe05443270fa6d8136238ec72accbc0
const FRAME_TIME = 16;
let lastTime = 0;
window.requestAnimationFrame = function (callback, element) {
const now = window.performance.now();
const nextTime = Math.max(lastTime + FRAME_TIME, now);
return setTimeout(function () {
callback((lastTime = nextTime));
}, nextTime - now);
};
window.cancelAnimationFrame = clearTimeout;

let panelCreated = false;

Expand Down

0 comments on commit ca2cf31

Please sign in to comment.