improve performance

This commit is contained in:
Gimle Larpes 2025-07-28 16:42:50 +02:00
parent 71e775fed1
commit 4947efe274
3 changed files with 50 additions and 6 deletions

View file

@ -1,4 +1,4 @@
import React, { MouseEventHandler, useCallback, useMemo, useRef, useState } from 'react'; import React, { MouseEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Box, Chip, Icon, IconButton, Icons, Line, Scroll, Spinner, Text, config } from 'folds'; import { Box, Chip, Icon, IconButton, Icons, Line, Scroll, Spinner, Text, config } from 'folds';
import { useVirtualizer } from '@tanstack/react-virtual'; import { useVirtualizer } from '@tanstack/react-virtual';
import { useAtom, useAtomValue } from 'jotai'; import { useAtom, useAtomValue } from 'jotai';
@ -199,6 +199,11 @@ export function Lobby() {
[mx] [mx]
); );
const closedCategoriesCache = useRef(new Map());
useEffect(() => {
closedCategoriesCache.current.clear();
}, [closedCategories, roomToParents, getRoom]);
/** /**
* Recursively checks if a given parentId (or all its ancestors) is in a closed category. * Recursively checks if a given parentId (or all its ancestors) is in a closed category.
* *
@ -209,19 +214,29 @@ export function Lobby() {
*/ */
const getInClosedCategories = useCallback( const getInClosedCategories = useCallback(
(spaceId: string, parentId: string, previousId?: string): boolean => { (spaceId: string, parentId: string, previousId?: string): boolean => {
const categoryId = makeLobbyCategoryId(spaceId, parentId);
if (closedCategoriesCache.current.has(categoryId)) {
return closedCategoriesCache.current.get(categoryId);
}
// Ignore root space being collapsed if in a subspace, // Ignore root space being collapsed if in a subspace,
// this is due to many spaces dumping all rooms in the top-level space. // this is due to many spaces dumping all rooms in the top-level space.
if (parentId === spaceId) { if (parentId === spaceId) {
if (previousId) { if (previousId) {
if (getRoom(previousId)?.isSpaceRoom() || spaceRooms.has(previousId)) return false; if (getRoom(previousId)?.isSpaceRoom() || spaceRooms.has(previousId)) {
closedCategoriesCache.current.set(categoryId, false);
return false;
} }
} }
if (closedCategories.has(makeLobbyCategoryId(spaceId, parentId))) { }
if (closedCategories.has(categoryId)) {
closedCategoriesCache.current.set(categoryId, true);
return true; return true;
} }
const parentParentIds = roomToParents.get(parentId); const parentParentIds = roomToParents.get(parentId);
if (!parentParentIds || parentParentIds.size === 0) { if (!parentParentIds || parentParentIds.size === 0) {
closedCategoriesCache.current.set(categoryId, false);
return false; return false;
} }
@ -232,6 +247,7 @@ export function Lobby() {
} }
}); });
closedCategoriesCache.current.set(categoryId, !anyOpen);
return !anyOpen; return !anyOpen;
}, },
[closedCategories, getRoom, roomToParents, spaceRooms] [closedCategories, getRoom, roomToParents, spaceRooms]

View file

@ -208,9 +208,10 @@ const getSpaceJoinedHierarchy = (
const space = getRoom(spaceId); const space = getRoom(spaceId);
if (!space) return false; if (!space) return false;
const childEvents = getStateEvents(space, StateEvent.SpaceChild).filter(isValidChild); const childEvents = getStateEvents(space, StateEvent.SpaceChild);
return childEvents.some((childEvent): boolean => { return childEvents.some((childEvent): boolean => {
if (!isValidChild(childEvent)) return false;
const childId = childEvent.getStateKey(); const childId = childEvent.getStateKey();
if (!childId || !isRoomId(childId)) return false; if (!childId || !isRoomId(childId)) return false;
const room = getRoom(childId); const room = getRoom(childId);

View file

@ -2,6 +2,7 @@ import React, {
MouseEventHandler, MouseEventHandler,
forwardRef, forwardRef,
useCallback, useCallback,
useEffect,
useMemo, useMemo,
useRef, useRef,
useState, useState,
@ -315,6 +316,13 @@ export function Space() {
[mx, allJoinedRooms] [mx, allJoinedRooms]
); );
const closedCategoriesCache = useRef(new Map());
const ancestorsCollapsedCache = useRef(new Map());
useEffect(() => {
closedCategoriesCache.current.clear();
ancestorsCollapsedCache.current.clear();
}, [closedCategories, roomToParents, getRoom]);
/** /**
* Recursively checks if a given parentId (or all its ancestors) is in a closed category. * Recursively checks if a given parentId (or all its ancestors) is in a closed category.
* *
@ -325,20 +333,30 @@ export function Space() {
*/ */
const getInClosedCategories = useCallback( const getInClosedCategories = useCallback(
(spaceId: string, parentId: string, previousId?: string): boolean => { (spaceId: string, parentId: string, previousId?: string): boolean => {
const categoryId = makeNavCategoryId(spaceId, parentId);
if (closedCategoriesCache.current.has(categoryId)) {
return closedCategoriesCache.current.get(categoryId);
}
// Ignore root space being collapsed if in a subspace, // Ignore root space being collapsed if in a subspace,
// this is due to many spaces dumping all rooms in the top-level space. // this is due to many spaces dumping all rooms in the top-level space.
if (parentId === spaceId) { if (parentId === spaceId) {
if (previousId) { if (previousId) {
if (getRoom(previousId)?.isSpaceRoom()) return false; if (getRoom(previousId)?.isSpaceRoom()) {
closedCategoriesCache.current.set(categoryId, false);
return false;
}
} }
} }
if (closedCategories.has(makeNavCategoryId(spaceId, parentId))) { if (closedCategories.has(categoryId)) {
closedCategoriesCache.current.set(categoryId, true);
return true; return true;
} }
const parentParentIds = roomToParents.get(parentId); const parentParentIds = roomToParents.get(parentId);
if (!parentParentIds || parentParentIds.size === 0) { if (!parentParentIds || parentParentIds.size === 0) {
closedCategoriesCache.current.set(categoryId, false);
return false; return false;
} }
@ -349,6 +367,7 @@ export function Space() {
} }
}); });
closedCategoriesCache.current.set(categoryId, !anyOpen);
return !anyOpen; return !anyOpen;
}, },
[closedCategories, getRoom, roomToParents] [closedCategories, getRoom, roomToParents]
@ -391,8 +410,14 @@ export function Space() {
* @returns True if every parent category is collapsed; false otherwise. * @returns True if every parent category is collapsed; false otherwise.
*/ */
const getAllAncestorsCollapsed = (spaceId: string, roomId: string): boolean => { const getAllAncestorsCollapsed = (spaceId: string, roomId: string): boolean => {
const categoryId = makeNavCategoryId(spaceId, roomId);
if (ancestorsCollapsedCache.current.has(categoryId)) {
return ancestorsCollapsedCache.current.get(categoryId);
}
const parentIds = roomToParents.get(roomId); const parentIds = roomToParents.get(roomId);
if (!parentIds || parentIds.size === 0) { if (!parentIds || parentIds.size === 0) {
ancestorsCollapsedCache.current.set(categoryId, false);
return false; return false;
} }
@ -402,6 +427,8 @@ export function Space() {
allCollapsed = false; allCollapsed = false;
} }
}); });
ancestorsCollapsedCache.current.set(categoryId, allCollapsed);
return allCollapsed; return allCollapsed;
}; };