Skip to content

Commit 006f44b

Browse files
committed
WIP frontend performances
1 parent 0899336 commit 006f44b

File tree

4 files changed

+94
-23
lines changed

4 files changed

+94
-23
lines changed

arduino-ide-extension/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@
7979
"react-disable": "^0.1.0",
8080
"react-select": "^3.0.4",
8181
"react-tabs": "^3.1.2",
82+
"react-virtualized-auto-sizer": "^1.0.6",
83+
"react-window": "^1.8.6",
8284
"semver": "^7.3.2",
8385
"string-natural-compare": "^2.0.3",
8486
"temp": "^0.9.1",
@@ -90,6 +92,8 @@
9092
"@types/chai": "^4.2.7",
9193
"@types/chai-string": "^1.4.2",
9294
"@types/mocha": "^5.2.7",
95+
"@types/react-virtualized-auto-sizer": "^1.0.1",
96+
"@types/react-window": "^1.8.5",
9397
"chai": "^4.2.0",
9498
"chai-string": "^1.5.0",
9599
"decompress": "^4.2.0",

arduino-ide-extension/src/browser/monitor/monitor-connection.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,9 @@ export class MonitorConnection {
7373
protected init(): void {
7474
this.monitorServiceClient.onMessage(async (port) => {
7575
const w = new WebSocket(`ws://localhost:${port}`);
76-
let h = 0;
7776
w.onmessage = (res) => {
7877
const messages = JSON.parse(res.data);
79-
h += messages.length;
80-
81-
if (h > 1000) {
82-
h = 0;
83-
console.log('read 1000 messages');
84-
}
85-
// console.log(`received ${messages.length} messages`);
86-
// this.onReadEmitter.fire({ messages });
78+
this.onReadEmitter.fire({ messages });
8779
};
8880
});
8981

arduino-ide-extension/src/browser/monitor/monitor-widget.tsx

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { MonitorConfig } from '../../common/protocol/monitor-service';
2020
import { ArduinoSelect } from '../widgets/arduino-select';
2121
import { MonitorModel } from './monitor-model';
2222
import { MonitorConnection } from './monitor-connection';
23+
import { FixedSizeList as List } from 'react-window';
24+
import AutoSizer from 'react-virtualized-auto-sizer';
2325

2426
@injectable()
2527
export class MonitorWidget extends ReactWidget {
@@ -299,7 +301,7 @@ export namespace SerialMonitorOutput {
299301
readonly clearConsoleEvent: Event<void>;
300302
}
301303
export interface State {
302-
lines: string[];
304+
lines: any;
303305
timestamp: boolean;
304306
}
305307
}
@@ -322,14 +324,32 @@ export class SerialMonitorOutput extends React.Component<
322324
};
323325
}
324326

327+
listRef: any = React.createRef();
328+
325329
render(): React.ReactNode {
326330
return (
327331
<React.Fragment>
328-
<div style={{ whiteSpace: 'pre', fontFamily: 'monospace' }}>
332+
<AutoSizer>
333+
{({ height, width }) => (
334+
<List
335+
className="List"
336+
height={height}
337+
itemData={this.state.lines}
338+
itemCount={this.state.lines.length}
339+
itemSize={30}
340+
width={width}
341+
ref={this.listRef}
342+
onItemsRendered={() => this.scrollToBottom()}
343+
>
344+
{Row}
345+
</List>
346+
)}
347+
</AutoSizer>
348+
{/* <div style={{ whiteSpace: 'pre', fontFamily: 'monospace' }}>
329349
{this.state.lines.map((line, i) => (
330350
<MonitorTextLine text={line} key={i} />
331351
))}
332-
</div>
352+
</div> */}
333353
<div
334354
style={{ float: 'left', clear: 'both' }}
335355
ref={(element) => {
@@ -340,11 +360,16 @@ export class SerialMonitorOutput extends React.Component<
340360
);
341361
}
342362

363+
shouldComponentUpdate(): boolean {
364+
return true;
365+
}
366+
343367
componentDidMount(): void {
344-
this.scrollToBottom();
368+
// this.scrollToBottom();
345369
this.toDisposeBeforeUnmount.pushAll([
346370
this.props.monitorConnection.onRead(({ messages }) => {
347-
messages.forEach((message) => {
371+
const linesToAdd: string[] = [];
372+
for (const message of messages) {
348373
const rawLines = message.split('\n');
349374
const lines: string[] = [];
350375
const timestamp = () =>
@@ -359,14 +384,14 @@ export class SerialMonitorOutput extends React.Component<
359384
lines.push(timestamp() + rawLines[i]);
360385
}
361386
}
362-
363-
this.setState((prevState) => ({
364-
lines: [...prevState.lines, lines.join('\n')],
365-
}));
387+
linesToAdd.push(lines.join('\n'));
366388

367389
// const content = this.state.content + lines.join('\n');
368390
// this.setState({ content });
369-
});
391+
}
392+
this.setState((prevState) => ({
393+
lines: [...prevState.lines, ...linesToAdd],
394+
}));
370395
}),
371396
this.props.clearConsoleEvent(() => this.setState({ lines: [] })),
372397
this.props.monitorModel.onChange(({ property }) => {
@@ -378,9 +403,9 @@ export class SerialMonitorOutput extends React.Component<
378403
]);
379404
}
380405

381-
componentDidUpdate(): void {
382-
this.scrollToBottom();
383-
}
406+
// componentDidUpdate(): void {
407+
// this.scrollToBottom();
408+
// }
384409

385410
componentWillUnmount(): void {
386411
// TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout?
@@ -389,7 +414,8 @@ export class SerialMonitorOutput extends React.Component<
389414

390415
protected scrollToBottom(): void {
391416
if (this.props.monitorModel.autoscroll && this.anchor) {
392-
this.anchor.scrollIntoView();
417+
// this.anchor.scrollIntoView();
418+
this.listRef.current.scrollToItem(this.state.lines.length);
393419
}
394420
}
395421
}
@@ -399,6 +425,16 @@ const _MonitorTextLine = ({ text }: { text: string }): React.ReactElement => {
399425
};
400426
export const MonitorTextLine = React.memo(_MonitorTextLine);
401427

428+
const Row = ({
429+
index,
430+
style,
431+
data,
432+
}: {
433+
index: number;
434+
style: any;
435+
data: string;
436+
}) => <div style={style}>{data[index]}</div>;
437+
402438
export interface SelectOption<T> {
403439
readonly label: string;
404440
readonly value: T;

yarn.lock

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,13 @@
826826
"@babel/types" "^7.4.4"
827827
esutils "^2.0.2"
828828

829+
"@babel/runtime@^7.0.0":
830+
version "7.15.4"
831+
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
832+
integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
833+
dependencies:
834+
regenerator-runtime "^0.13.4"
835+
829836
"@babel/runtime@^7.10.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
830837
version "7.13.10"
831838
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
@@ -3013,6 +3020,13 @@
30133020
dependencies:
30143021
"@types/react" "*"
30153022

3023+
"@types/react-virtualized-auto-sizer@^1.0.1":
3024+
version "1.0.1"
3025+
resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz#b3187dae1dfc4c15880c9cfc5b45f2719ea6ebd4"
3026+
integrity sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==
3027+
dependencies:
3028+
"@types/react" "*"
3029+
30163030
"@types/react-virtualized@^9.18.3":
30173031
version "9.21.11"
30183032
resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.21.11.tgz#8eb60ed12ef0b2625769819f9fd10ad4bb1bdce0"
@@ -3021,6 +3035,13 @@
30213035
"@types/prop-types" "*"
30223036
"@types/react" "*"
30233037

3038+
"@types/react-window@^1.8.5":
3039+
version "1.8.5"
3040+
resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.5.tgz#285fcc5cea703eef78d90f499e1457e9b5c02fc1"
3041+
integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==
3042+
dependencies:
3043+
"@types/react" "*"
3044+
30243045
"@types/react@*":
30253046
version "17.0.3"
30263047
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79"
@@ -11364,6 +11385,11 @@ mem@^4.0.0:
1136411385
mimic-fn "^2.0.0"
1136511386
p-is-promise "^2.0.0"
1136611387

11388+
"memoize-one@>=3.1.1 <6":
11389+
version "5.2.1"
11390+
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
11391+
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
11392+
1136711393
memoize-one@^5.0.0:
1136811394
version "5.1.1"
1136911395
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
@@ -13916,6 +13942,11 @@ react-transition-group@^4.3.0:
1391613942
loose-envify "^1.4.0"
1391713943
prop-types "^15.6.2"
1391813944

13945+
react-virtualized-auto-sizer@^1.0.6:
13946+
version "1.0.6"
13947+
resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca"
13948+
integrity sha512-7tQ0BmZqfVF6YYEWcIGuoR3OdYe8I/ZFbNclFlGOC3pMqunkYF/oL30NCjSGl9sMEb17AnzixDz98Kqc3N76HQ==
13949+
1391913950
react-virtualized@^9.20.0:
1392013951
version "9.22.3"
1392113952
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
@@ -13928,6 +13959,14 @@ react-virtualized@^9.20.0:
1392813959
prop-types "^15.7.2"
1392913960
react-lifecycles-compat "^3.0.4"
1393013961

13962+
react-window@^1.8.6:
13963+
version "1.8.6"
13964+
resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.6.tgz#d011950ac643a994118632665aad0c6382e2a112"
13965+
integrity sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==
13966+
dependencies:
13967+
"@babel/runtime" "^7.0.0"
13968+
memoize-one ">=3.1.1 <6"
13969+
1393113970
react@^16.8.0:
1393213971
version "16.14.0"
1393313972
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"

0 commit comments

Comments
 (0)