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