mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-06-01 18:15:13 +00: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:
+11
-7
@@ -27,11 +27,13 @@ const getRect = node => {
|
|||||||
const measureLayout = (node, relativeToNativeNode, callback) => {
|
const measureLayout = (node, relativeToNativeNode, callback) => {
|
||||||
const relativeNode = relativeToNativeNode || (node && node.parentNode);
|
const relativeNode = relativeToNativeNode || (node && node.parentNode);
|
||||||
if (node && relativeNode) {
|
if (node && relativeNode) {
|
||||||
const relativeRect = getRect(relativeNode);
|
setTimeout(() => {
|
||||||
const { height, left, top, width } = getRect(node);
|
const relativeRect = getRect(relativeNode);
|
||||||
const x = left - relativeRect.left;
|
const { height, left, top, width } = getRect(node);
|
||||||
const y = top - relativeRect.top;
|
const x = left - relativeRect.left;
|
||||||
callback(x, y, width, height, left, top);
|
const y = top - relativeRect.top;
|
||||||
|
callback(x, y, width, height, left, top);
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,8 +56,10 @@ const UIManager = {
|
|||||||
|
|
||||||
measureInWindow(node, callback) {
|
measureInWindow(node, callback) {
|
||||||
if (node) {
|
if (node) {
|
||||||
const { height, left, top, width } = getRect(node);
|
setTimeout(() => {
|
||||||
callback(left, top, width, height);
|
const { height, left, top, width } = getRect(node);
|
||||||
|
callback(left, top, width, height);
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
+18
-18
@@ -56,9 +56,7 @@ const observe = instance => {
|
|||||||
resizeObserver.observe(node);
|
resizeObserver.observe(node);
|
||||||
} else {
|
} else {
|
||||||
instance._layoutId = id;
|
instance._layoutId = id;
|
||||||
setTimeout(() => {
|
instance._handleLayout();
|
||||||
instance._handleLayout();
|
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -122,22 +120,24 @@ const applyLayout = Component => {
|
|||||||
const layout = this._layoutState;
|
const layout = this._layoutState;
|
||||||
const { onLayout } = this.props;
|
const { onLayout } = this.props;
|
||||||
|
|
||||||
if (this._isMounted && onLayout) {
|
if (onLayout) {
|
||||||
this.measure((x, y, width, height) => {
|
this.measure((x, y, width, height) => {
|
||||||
if (
|
if (this._isMounted) {
|
||||||
layout.x !== x ||
|
if (
|
||||||
layout.y !== y ||
|
layout.x !== x ||
|
||||||
layout.width !== width ||
|
layout.y !== y ||
|
||||||
layout.height !== height
|
layout.width !== width ||
|
||||||
) {
|
layout.height !== height
|
||||||
this._layoutState = { x, y, width, height };
|
) {
|
||||||
const nativeEvent = {
|
this._layoutState = { x, y, width, height };
|
||||||
layout: this._layoutState,
|
const nativeEvent = {
|
||||||
get target() {
|
layout: this._layoutState,
|
||||||
return findNodeHandle(this);
|
get target() {
|
||||||
}
|
return findNodeHandle(this);
|
||||||
};
|
}
|
||||||
onLayout({ nativeEvent, timeStamp: Date.now() });
|
};
|
||||||
|
onLayout({ nativeEvent, timeStamp: Date.now() });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user