Make screen dimension reflection fast

Summary:
After loading a layout plugin snapshot, I noticed the plugin feels really sluggish. I noticed that getDimensions, which recursively walks the full tree, is triggered on every rendering, although the state it introduces is only required when opening a screenshot visualizer. So Moved the function invocation to there.

Also did some first steps on supporting iOS; the visualizer will no show a preview of iOS as well. I'll leave implementing the highlights to a volunteer :)

Reviewed By: passy

Differential Revision: D29262697

fbshipit-source-id: b13b19b013eeeb98abb66fb648a193c69688a7e3
This commit is contained in:
Michel Weststrate
2021-06-22 04:09:36 -07:00
committed by Facebook GitHub Bot
parent c6a7d48864
commit b9250e7795

View File

@@ -35,6 +35,7 @@ import {
IDEFileResolver,
IDEType,
} from 'flipper';
import {message} from 'antd';
type State = {
init: boolean;
@@ -335,8 +336,9 @@ export default class LayoutPlugin extends FlipperPlugin<
if (this.state.visualizerWindow) {
this.state.visualizerWindow.close();
} else {
const screenDimensions = this.state.screenDimensions;
if (!screenDimensions) {
const screenDimensions = this.loadScreenDimensions();
if (!screenDimensions || !this.state.visualizerScreenshot) {
message.warn('No visualizer screenshot or dimensions available');
return;
}
const visualizerWindow = window.open(
@@ -376,21 +378,19 @@ export default class LayoutPlugin extends FlipperPlugin<
});
};
getScreenDimensions(): {width: number; height: number} | null {
if (this.state.screenDimensions) {
return this.state.screenDimensions;
}
requestIdleCallback(() => {
loadScreenDimensions(): {width: number; height: number} | null {
// Walk the layout tree from root node down until a node with width and height is found.
// Assume these are the dimensions of the screen.
let elementId = this.props.persistedState.rootElement;
while (elementId != null) {
const element = this.props.persistedState.elements[elementId];
const element: any = this.props.persistedState.elements[elementId];
if (!element) {
return null;
}
if (element.data.View?.width) {
if (
element.data?.View?.width ||
element.data?.UIView?.bounds?.size?.width
) {
break;
}
elementId = element.children[0];
@@ -398,22 +398,19 @@ export default class LayoutPlugin extends FlipperPlugin<
if (elementId == null) {
return null;
}
const element = this.props.persistedState.elements[elementId];
if (
element == null ||
typeof element.data.View?.width != 'object' ||
typeof element.data.View?.height != 'object'
) {
const element: any = this.props.persistedState.elements[elementId];
const width =
element?.data?.View?.width?.value ??
element?.data?.UIView?.bounds?.size?.width;
const height =
element?.data?.View?.height?.value ??
element?.data?.UIView?.bounds?.size?.height;
if (typeof width !== 'number' || typeof height !== 'number') {
return null;
}
const screenDimensions = {
width: element.data.View?.width.value,
height: element.data.View?.height.value,
};
const screenDimensions = {width, height};
this.setState({screenDimensions});
});
return null;
return screenDimensions;
}
render() {
@@ -456,8 +453,6 @@ export default class LayoutPlugin extends FlipperPlugin<
const showAnalyzeYogaPerformanceButton = GK.get('flipper_yogaperformance');
const screenDimensions = this.getScreenDimensions();
if (!this.state.init) {
return null;
}
@@ -543,14 +538,14 @@ export default class LayoutPlugin extends FlipperPlugin<
) : null}
</DetailSidebar>
{this.state.visualizerWindow &&
screenDimensions &&
this.state.screenDimensions &&
(this.state.visualizerScreenshot ? (
<VisualizerPortal
container={this.state.visualizerWindow.document.body}
elements={this.props.persistedState.elements}
highlightedElement={this.state.highlightedElement}
screenshotURL={this.state.visualizerScreenshot}
screenDimensions={screenDimensions}
screenDimensions={this.state.screenDimensions}
/>
) : (
'Loading...'