mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-01-12 22:51:09 +08:00
[fix] UIManager measurements don't block
A large number of layout measurements (and their corresponding tasks) can block the main thread. Make the work async and try to keep the UI responsive to user input while the layout work is taking place.
This commit is contained in:
@@ -27,11 +27,13 @@ const getRect = node => {
|
||||
const measureLayout = (node, relativeToNativeNode, callback) => {
|
||||
const relativeNode = relativeToNativeNode || (node && node.parentNode);
|
||||
if (node && relativeNode) {
|
||||
const relativeRect = getRect(relativeNode);
|
||||
const { height, left, top, width } = getRect(node);
|
||||
const x = left - relativeRect.left;
|
||||
const y = top - relativeRect.top;
|
||||
callback(x, y, width, height, left, top);
|
||||
setTimeout(() => {
|
||||
const relativeRect = getRect(relativeNode);
|
||||
const { height, left, top, width } = getRect(node);
|
||||
const x = left - relativeRect.left;
|
||||
const y = top - relativeRect.top;
|
||||
callback(x, y, width, height, left, top);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -54,8 +56,10 @@ const UIManager = {
|
||||
|
||||
measureInWindow(node, callback) {
|
||||
if (node) {
|
||||
const { height, left, top, width } = getRect(node);
|
||||
callback(left, top, width, height);
|
||||
setTimeout(() => {
|
||||
const { height, left, top, width } = getRect(node);
|
||||
callback(left, top, width, height);
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -56,9 +56,7 @@ const observe = instance => {
|
||||
resizeObserver.observe(node);
|
||||
} else {
|
||||
instance._layoutId = id;
|
||||
setTimeout(() => {
|
||||
instance._handleLayout();
|
||||
}, 0);
|
||||
instance._handleLayout();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -122,22 +120,24 @@ const applyLayout = Component => {
|
||||
const layout = this._layoutState;
|
||||
const { onLayout } = this.props;
|
||||
|
||||
if (this._isMounted && onLayout) {
|
||||
if (onLayout) {
|
||||
this.measure((x, y, width, height) => {
|
||||
if (
|
||||
layout.x !== x ||
|
||||
layout.y !== y ||
|
||||
layout.width !== width ||
|
||||
layout.height !== height
|
||||
) {
|
||||
this._layoutState = { x, y, width, height };
|
||||
const nativeEvent = {
|
||||
layout: this._layoutState,
|
||||
get target() {
|
||||
return findNodeHandle(this);
|
||||
}
|
||||
};
|
||||
onLayout({ nativeEvent, timeStamp: Date.now() });
|
||||
if (this._isMounted) {
|
||||
if (
|
||||
layout.x !== x ||
|
||||
layout.y !== y ||
|
||||
layout.width !== width ||
|
||||
layout.height !== height
|
||||
) {
|
||||
this._layoutState = { x, y, width, height };
|
||||
const nativeEvent = {
|
||||
layout: this._layoutState,
|
||||
get target() {
|
||||
return findNodeHandle(this);
|
||||
}
|
||||
};
|
||||
onLayout({ nativeEvent, timeStamp: Date.now() });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user