1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-07-16 00:14:34 +02:00

Desktop,Mobile: Fixes #11065: Improve performance when there are many selected items (#11067)

This commit is contained in:
Henry Heino
2024-09-21 04:53:16 -07:00
committed by GitHub
parent 5beb80bf61
commit 0965c6d257
6 changed files with 42 additions and 5 deletions

View File

@ -888,6 +888,7 @@ packages/lib/ArrayUtils.js
packages/lib/AsyncActionQueue.test.js
packages/lib/AsyncActionQueue.js
packages/lib/BaseApplication.js
packages/lib/BaseModel.test.js
packages/lib/BaseModel.js
packages/lib/BaseSyncTarget.js
packages/lib/ClipperServer.js

1
.gitignore vendored
View File

@ -865,6 +865,7 @@ packages/lib/ArrayUtils.js
packages/lib/AsyncActionQueue.test.js
packages/lib/AsyncActionQueue.js
packages/lib/BaseApplication.js
packages/lib/BaseModel.test.js
packages/lib/BaseModel.js
packages/lib/BaseSyncTarget.js
packages/lib/ClipperServer.js

View File

@ -32,7 +32,7 @@ export default class NoteListUtils {
const menuUtils = new MenuUtils(cmdService);
const notes: NoteEntity[] = noteIds.map(id => BaseModel.byId(props.notes, id));
const notes: NoteEntity[] = BaseModel.modelsByIds(props.notes, noteIds);
const singleNoteId = noteIds.length === 1 ? noteIds[0] : null;

View File

@ -0,0 +1,31 @@
import BaseModel from './BaseModel';
describe('BaseModel', () => {
test.each([
[0, 0],
[4, 10],
[10, 4],
[5, 5],
])('should filter items by IDs (itemCount: %d, idCount: %d)', (itemCount, idCount) => {
const items = [];
const ids = [];
const expectedMatchingItems = [];
for (let i = 0; i < idCount; i++) {
const id = `matching-${i}`;
ids.push(id);
if (items.length < itemCount) {
const item = { id };
items.push(item);
expectedMatchingItems.push(item);
}
}
while (items.length < itemCount) {
items.push({ id: `non-matching-${items.length}` });
}
expect(BaseModel.modelsByIds(items, ids)).toMatchObject(expectedMatchingItems);
});
});

View File

@ -169,11 +169,15 @@ class BaseModel {
public static modelsByIds<T extends BaseItemEntity>(items: T[], ids: string[]): T[] {
const output = [];
for (let i = 0; i < items.length; i++) {
if (ids.indexOf(items[i].id) >= 0) {
output.push(items[i]);
// Prefer a `Set` to using `ids.includes` -- this gives a better running time.
const idSet = new Set(ids);
for (const item of items) {
if (idSet.has(item.id)) {
output.push(item);
}
}
return output;
}

View File

@ -54,7 +54,7 @@ export default function stateToWhenClauseContext(state: State, options: WhenClau
const selectedNoteIds = state.selectedNoteIds || [];
const selectedNoteId = selectedNoteIds.length === 1 ? selectedNoteIds[0] : null;
const selectedNote: NoteEntity = selectedNoteId ? BaseModel.byId(state.notes, selectedNoteId) : null;
const selectedNotes = selectedNoteIds.map(id => state.notes.find(n => n.id === id)).filter(n => !!n);
const selectedNotes = BaseModel.modelsByIds(state.notes ?? [], selectedNoteIds);
const commandFolderId = options.commandFolderId || state.selectedFolderId;
const commandFolder: FolderEntity = commandFolderId ? BaseModel.byId(state.folders, commandFolderId) : null;