Merge pull request #4817 from urbit/lf/virt-perf

VirtualScroller: performance, memory leaks
This commit is contained in:
matildepark 2021-04-23 23:11:56 -04:00 committed by GitHub
commit a8ee7fcfe4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 24 deletions

View File

@ -75,7 +75,14 @@ export function ChatResource(props: ChatResourceProps) {
); );
const clearUnsent = useCallback( const clearUnsent = useCallback(
() => setUnsent(s => _.omit(s, station)), () => {
setUnsent(s => {
if(station in s) {
return _.omit(s, station);
}
return s;
});
},
[station] [station]
); );

View File

@ -146,8 +146,6 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
private cleanupRefInterval: NodeJS.Timeout | null = null; private cleanupRefInterval: NodeJS.Timeout | null = null;
private initScroll: NodeJS.Timeout | null = null;
constructor(props: VirtualScrollerProps<T>) { constructor(props: VirtualScrollerProps<T>) {
super(props); super(props);
this.state = { this.state = {
@ -170,15 +168,9 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
componentDidMount() { componentDidMount() {
this.updateVisible(0); this.updateVisible(0);
this.resetScroll();
this.loadTop(); this.loadTop();
this.loadBottom(); this.loadBottom();
this.cleanupRefInterval = setInterval(this.cleanupRefs, 5000); this.cleanupRefInterval = setInterval(this.cleanupRefs, 5000);
this.initScroll = setTimeout(() => {
log('scroll', 'initialised scroll');
this.restore();
this.initScroll = null;
}, 100);
} }
@ -218,7 +210,9 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
if(size !== prevProps.size || pendingSize !== prevProps.pendingSize) { if(size !== prevProps.size || pendingSize !== prevProps.pendingSize) {
if(this.scrollLocked) { if(this.scrollLocked) {
this.updateVisible(0); if(!this.state.visibleItems.peekLargest()![0].eq(this.props.data.peekLargest()![0])) {
this.updateVisible(0);
}
this.resetScroll(); this.resetScroll();
} }
@ -230,9 +224,8 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
if(this.cleanupRefInterval) { if(this.cleanupRefInterval) {
clearInterval(this.cleanupRefInterval); clearInterval(this.cleanupRefInterval);
} }
if(this.initScroll) { this.cleanupRefs();
clearTimeout(this.initScroll); this.childRefs.clear();
}
} }
startOffset() { startOffset() {
@ -370,10 +363,6 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
// bail if we're going to adjust scroll anyway // bail if we're going to adjust scroll anyway
return; return;
} }
if(this.initScroll) {
clearTimeout(this.initScroll);
this.initScroll = null;
}
if(this.saveDepth > 0) { if(this.saveDepth > 0) {
log('bail', 'deep scroll queue'); log('bail', 'deep scroll queue');
return; return;
@ -385,17 +374,15 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
const startOffset = this.startOffset(); const startOffset = this.startOffset();
if (scrollTop < ZONE_SIZE) { if (scrollTop < ZONE_SIZE) {
log('scroll', `Entered start zone ${scrollTop}`); log('scroll', `Entered start zone ${scrollTop}`);
if (startOffset === 0 && onStartReached) { if (startOffset === 0) {
onStartReached(); onStartReached && onStartReached();
this.scrollLocked = true;
} }
const newOffset = Math.max(0, startOffset - this.pageDelta); const newOffset = Math.max(0, startOffset - this.pageDelta);
if(newOffset < 10) { if(newOffset < 10) {
this.loadBottom(); this.loadBottom();
} }
if(newOffset === 0) {
this.scrollLocked = true;
}
if(newOffset !== startOffset) { if(newOffset !== startOffset) {
this.updateVisible(newOffset); this.updateVisible(newOffset);
} }
@ -429,8 +416,11 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
log('bail', 'Deep restore'); log('bail', 'Deep restore');
return; return;
} }
if(this.initScroll) { if(this.scrollLocked) {
log('bail', 'still initialising scroll'); this.resetScroll();
this.savedIndex = null;
this.savedDistance = 0;
this.saveDepth--;
return; return;
} }