Skip to content

Commit 1755c54

Browse files
committed
feat: implement virtual scrolling to reduce DOM size
1 parent 0bb1643 commit 1755c54

File tree

4 files changed

+71
-16
lines changed

4 files changed

+71
-16
lines changed

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
"@types/react-dom": "^16.9.10",
1818
"@types/react-fontawesome": "^1.6.4",
1919
"@types/react-inspector": "^4.0.1",
20+
"@types/react-virtualized-auto-sizer": "^1.0.1",
21+
"@types/react-window": "^1.8.5",
2022
"@types/rsocket-core": "^0.0.6",
2123
"@types/rsocket-types": "^0.0.2",
2224
"@types/rsocket-websocket-client": "^0.0.3",
@@ -45,6 +47,8 @@
4547
"react-flex-panel": "^1.0.0",
4648
"react-fontawesome": "^1.7.1",
4749
"react-inspector": "^5.1.0",
50+
"react-virtualized-auto-sizer": "^1.0.6",
51+
"react-window": "^1.8.6",
4852
"rsocket-core": "^0.0.27",
4953
"rsocket-websocket-client": "^0.0.27"
5054
}

src/viewer/App.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@
9393
}
9494
.frame-list {
9595
flex: 1;
96-
overflow-y: auto;
97-
overflow-x: hidden;
9896
padding: 0;
9997

10098
.frame {
@@ -103,6 +101,7 @@
103101
border-bottom: 1px solid #ccc;
104102
display: flex;
105103
flex-direction: row;
104+
box-sizing: border-box;
106105
.fa {
107106
flex-shrink: 0;
108107
margin-top: 3px;

src/viewer/App.tsx

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import React, {MouseEventHandler} from 'react';
1+
import React, {MouseEventHandler, CSSProperties} from 'react';
22
// @ts-ignore no types for the package
33
import Panel from 'react-flex-panel';
44
import FontAwesome from 'react-fontawesome';
5+
import {FixedSizeList, ListChildComponentProps} from 'react-window';
6+
import AutoSizer from 'react-virtualized-auto-sizer';
57
import classNames from 'classnames';
68
import './App.scss';
79
import {ObjectInspector} from 'react-inspector';
@@ -84,15 +86,16 @@ function base64ToArrayBuffer(base64: string) {
8486
return bytes;
8587
}
8688

87-
const FrameEntry = ({frame, selected, onClick}:
88-
{ frame: WsFrameState, selected: boolean, onClick: MouseEventHandler }) => {
89+
const FrameEntry = ({frame, selected, onClick, style}:
90+
{ frame: WsFrameState, selected: boolean, onClick: MouseEventHandler, style: CSSProperties }) => {
8991
const rsocketFrame = tryDeserializeFrame(frame.payload)
9092
const frameName = rsocketFrame
9193
? <span className="name">{shortFrame(rsocketFrame)}</span>
9294
: <span className="name">{frame.text != null ? "Text Frame" : "Binary Frame"}</span>
9395
return (
9496
<li
9597
className={classNames("frame", "frame-" + frame.type, {"frame-selected": selected})}
98+
style={style}
9699
onClick={onClick}>
97100
<FontAwesome name={frame.type === "incoming" ? "arrow-circle-down" : "arrow-circle-up"}/>
98101
<TimeStamp time={frame.time}/>
@@ -412,6 +415,24 @@ export const App = observer(({store}: { store: AppStateStore }) => {
412415
}
413416
const {frames, activeFrame} = connection;
414417
const active = frames.find(f => f.id === activeFrame);
418+
419+
const Row = ({ index, style, data }: ListChildComponentProps) => {
420+
const frame = data[index];
421+
422+
return (
423+
<FrameEntry
424+
key={frame.id}
425+
style={style}
426+
frame={frame}
427+
selected={frame.id === activeFrame}
428+
onClick={e => {
429+
store.selectFrame(frame.id);
430+
e.stopPropagation();
431+
}}
432+
/>
433+
);
434+
};
435+
415436
return (
416437
<Panel cols className="App">
417438
<Panel size={300} minSize={180} resizable className="LeftPanel">
@@ -430,17 +451,16 @@ export const App = observer(({store}: { store: AppStateStore }) => {
430451
}
431452
</select>
432453
</div>
433-
<ul className="frame-list" onClick={() => store.selectFrame(undefined)}>
434-
{frames.map((frame: WsFrameState) =>
435-
<FrameEntry key={frame.id}
436-
frame={frame}
437-
selected={frame.id === activeFrame}
438-
onClick={e => {
439-
store.selectFrame(frame.id);
440-
e.stopPropagation();
441-
}}
442-
/>)}
443-
</ul>
454+
455+
<div className="frame-list">
456+
<AutoSizer disableWidth>
457+
{({ height }) => (
458+
<FixedSizeList height={height} width="100%" itemCount={frames.length} itemSize={18} innerElementType="ul">
459+
{Row}
460+
</FixedSizeList>
461+
)}
462+
</AutoSizer>
463+
</div>
444464
</Panel>
445465
<Panel minSize={100} className="PanelView">
446466
{active != null ? <FrameView wsFrame={active}/> :

yarn.lock

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@
133133
"@types/react" "*"
134134
csstype "^3.0.2"
135135

136+
"@types/react-virtualized-auto-sizer@^1.0.1":
137+
version "1.0.1"
138+
resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz#b3187dae1dfc4c15880c9cfc5b45f2719ea6ebd4"
139+
integrity sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==
140+
dependencies:
141+
"@types/react" "*"
142+
143+
"@types/react-window@^1.8.5":
144+
version "1.8.5"
145+
resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.5.tgz#285fcc5cea703eef78d90f499e1457e9b5c02fc1"
146+
integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==
147+
dependencies:
148+
"@types/react" "*"
149+
136150
"@types/react@*":
137151
version "17.0.0"
138152
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.0.tgz#5af3eb7fad2807092f0046a1302b7823e27919b8"
@@ -2773,6 +2787,11 @@ md5.js@^1.3.4:
27732787
inherits "^2.0.1"
27742788
safe-buffer "^5.1.2"
27752789

2790+
"memoize-one@>=3.1.1 <6":
2791+
version "5.2.1"
2792+
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
2793+
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
2794+
27762795
memory-fs@^0.4.1:
27772796
version "0.4.1"
27782797
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
@@ -3667,6 +3686,19 @@ react-is@^16.8.1:
36673686
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
36683687
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
36693688

3689+
react-virtualized-auto-sizer@^1.0.6:
3690+
version "1.0.6"
3691+
resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca"
3692+
integrity sha512-7tQ0BmZqfVF6YYEWcIGuoR3OdYe8I/ZFbNclFlGOC3pMqunkYF/oL30NCjSGl9sMEb17AnzixDz98Kqc3N76HQ==
3693+
3694+
react-window@^1.8.6:
3695+
version "1.8.6"
3696+
resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.6.tgz#d011950ac643a994118632665aad0c6382e2a112"
3697+
integrity sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==
3698+
dependencies:
3699+
"@babel/runtime" "^7.0.0"
3700+
memoize-one ">=3.1.1 <6"
3701+
36703702
react@^16.14.0:
36713703
version "16.14.0"
36723704
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"

0 commit comments

Comments
 (0)