Room list: avoid excessive re-renders on room list store update or filter change (#32663)
* perf(room list): clear room list item vm only when changing space Clearing all the item vms at every room list change is causing massive re-render of all the room list items. References to the vms are already removed when out of view (see RoomListViewMode.updateVisibleRooms) and handled by GC. * perf(room list): avoid to re-render filters at every room list update RoomListView re-renders on update but the filters (children) don't need to. Add a memo to avoid excessive-rerenders. * chore: add `keepIfSame` to do diff on vm objects * perf(room list): avoid to create new filter ids and keys when the room list is updated The filterKeys are passed in the virtuoso context so it should reduce internal computing The filter ids array has always the same value, there is no point to create a new instance. * test(room list): remove no longer relevant test * test(room list): add new test to ensure that room list item vms are preserved
This commit is contained in:
@@ -124,6 +124,20 @@ describe("RoomListViewViewModel", () => {
|
||||
|
||||
expect(viewModel.getSnapshot().isLoadingRooms).toBe(false);
|
||||
});
|
||||
|
||||
// This test ensures that the room list item vms are preserved when the room list is changing
|
||||
it("should keep existing view model when ListsUpdate event fires", () => {
|
||||
viewModel = new RoomListViewViewModel({ client: matrixClient });
|
||||
|
||||
// Create view model for room1
|
||||
const room1VM = viewModel.getRoomItemViewModel("!room1:server");
|
||||
expect(room1VM).toBeDefined();
|
||||
|
||||
RoomListStoreV3.instance.emit(RoomListStoreV3Event.ListsUpdate);
|
||||
|
||||
// View model should be still valid
|
||||
expect(room1VM.isDisposed).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Space switching", () => {
|
||||
@@ -295,24 +309,6 @@ describe("RoomListViewViewModel", () => {
|
||||
expect(viewModel.getSnapshot().activeFilterId).toBeUndefined();
|
||||
expect(viewModel.getSnapshot().roomIds).toEqual(["!room1:server", "!room2:server", "!room3:server"]);
|
||||
});
|
||||
|
||||
it("should clear view models when filter changes", () => {
|
||||
viewModel = new RoomListViewViewModel({ client: matrixClient });
|
||||
|
||||
// Get view models
|
||||
const vm1 = viewModel.getRoomItemViewModel("!room1:server");
|
||||
const disposeSpy = jest.spyOn(vm1, "dispose");
|
||||
|
||||
jest.spyOn(RoomListStoreV3.instance, "getSortedRoomsInActiveSpace").mockReturnValue({
|
||||
spaceId: "home",
|
||||
rooms: [room2],
|
||||
filterKeys: [FilterKey.UnreadFilter],
|
||||
});
|
||||
|
||||
viewModel.onToggleFilter("unread");
|
||||
|
||||
expect(disposeSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Room item view models", () => {
|
||||
|
||||
Reference in New Issue
Block a user