mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 04:51:31 +08:00 
			
		
		
		
	To prevent search lag when there are a large number of notes
This commit is contained in:
		
							parent
							
								
									8c6dbb4446
								
							
						
					
					
						commit
						a7799d32b0
					
				| @ -10,6 +10,18 @@ const SELECTED_NOTE_PATH_KEY = "data-note-path"; | ||||
| 
 | ||||
| const SELECTED_EXTERNAL_LINK_KEY = "data-external-link"; | ||||
| 
 | ||||
| // To prevent search lag when there are a large number of notes, set a delay based on the number of notes to avoid jitter.
 | ||||
| const notesCount = await server.get<number>(`stats/notesCount`); | ||||
| let debounceTimeoutId: ReturnType<typeof setTimeout>; | ||||
| 
 | ||||
| function getSearchDelay(notesCount: number): number { | ||||
|     const maxNotes = 20000;  | ||||
|     const maxDelay = 1000;   | ||||
|     const delay = Math.min(maxDelay, (notesCount / maxNotes) * maxDelay); | ||||
|     return delay; | ||||
| } | ||||
| let searchDelay = getSearchDelay(notesCount); | ||||
| 
 | ||||
| export interface Suggestion { | ||||
|     noteTitle?: string; | ||||
|     externalLink?: string; | ||||
| @ -72,10 +84,9 @@ async function autocompleteSource(term: string, cb: (rows: Suggestion[]) => void | ||||
|     const activeNoteId = appContext.tabManager.getActiveContextNoteId(); | ||||
|     const length = term.trim().length; | ||||
| 
 | ||||
|     let results: Suggestion[] = []; | ||||
|     if (length >= 3) { | ||||
|         results = await server.get<Suggestion[]>(`autocomplete?query=${encodeURIComponent(term)}&activeNoteId=${activeNoteId}&fastSearch=${fastSearch}`); | ||||
|     } | ||||
|     let results = await server.get<Suggestion[]>(`autocomplete?query=${encodeURIComponent(term)}&activeNoteId=${activeNoteId}&fastSearch=${fastSearch}`); | ||||
| 
 | ||||
|     options.fastSearch = true; | ||||
| 
 | ||||
|     if (length >= 1 && options.allowCreatingNotes) { | ||||
|         results = [ | ||||
| @ -112,6 +123,7 @@ async function autocompleteSource(term: string, cb: (rows: Suggestion[]) => void | ||||
| } | ||||
| 
 | ||||
| function clearText($el: JQuery<HTMLElement>) { | ||||
|     searchDelay = 0; | ||||
|     $el.setSelectedNotePath(""); | ||||
|     $el.autocomplete("val", "").trigger("change"); | ||||
| } | ||||
| @ -122,6 +134,7 @@ function setText($el: JQuery<HTMLElement>, text: string) { | ||||
| } | ||||
| 
 | ||||
| function showRecentNotes($el: JQuery<HTMLElement>) { | ||||
|     searchDelay = 0; | ||||
|     $el.setSelectedNotePath(""); | ||||
|     $el.autocomplete("val", ""); | ||||
|     $el.autocomplete("open"); | ||||
| @ -137,11 +150,8 @@ function fullTextSearch($el: JQuery<HTMLElement>, options: Options) { | ||||
|     options.fastSearch = false; | ||||
|     $el.autocomplete("val", ""); | ||||
|     $el.setSelectedNotePath(""); | ||||
|     searchDelay = 0; | ||||
|     $el.autocomplete("val", searchString); | ||||
|     // Set a delay to avoid resetting to true before full text search (await server.get) is called.
 | ||||
|     setTimeout(() => { | ||||
|         options.fastSearch = true; | ||||
|     }, 100); | ||||
| } | ||||
| 
 | ||||
| function initNoteAutocomplete($el: JQuery<HTMLElement>, options?: Options) { | ||||
| @ -154,6 +164,15 @@ function initNoteAutocomplete($el: JQuery<HTMLElement>, options?: Options) { | ||||
| 
 | ||||
|     options = options || {}; | ||||
| 
 | ||||
|     // Used to track whether the user is performing character composition with an input method (such as Chinese Pinyin, Japanese, Korean, etc.) and to avoid triggering a search during the composition process.
 | ||||
|     let isComposingInput = false; | ||||
|     $el.on("compositionstart", () => { | ||||
|         isComposingInput = true;  | ||||
|     }); | ||||
|     $el.on("compositionend", () => { | ||||
|         isComposingInput = false;  | ||||
|     }); | ||||
| 
 | ||||
|     $el.addClass("note-autocomplete-input"); | ||||
| 
 | ||||
|     const $clearTextButton = $("<a>").addClass("input-group-text input-clearer-button bx bxs-tag-x").prop("title", t("note_autocomplete.clear-text-field")); | ||||
| @ -226,7 +245,19 @@ function initNoteAutocomplete($el: JQuery<HTMLElement>, options?: Options) { | ||||
|         }, | ||||
|         [ | ||||
|             { | ||||
|                 source: (term, cb) => autocompleteSource(term, cb, options), | ||||
|                 source: (term, cb) => { | ||||
|                     clearTimeout(debounceTimeoutId); | ||||
|                     debounceTimeoutId = setTimeout(() => { | ||||
|                         if (isComposingInput) { | ||||
|                             return; | ||||
|                         } | ||||
|                         autocompleteSource(term, cb, options); | ||||
|                     }, searchDelay);  | ||||
|                      | ||||
|                     if (searchDelay === 0) { | ||||
|                         searchDelay = getSearchDelay(notesCount); | ||||
|                     } | ||||
|                 }, | ||||
|                 displayKey: "notePathTitle", | ||||
|                 templates: { | ||||
|                     suggestion: (suggestion) => suggestion.highlightedNotePathTitle | ||||
|  | ||||
| @ -48,7 +48,16 @@ function getSubtreeSize(req: Request) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| // Get the total number of notes
 | ||||
| function getNotesCount(req: Request) { | ||||
|     const notesCount = sql.getRow( | ||||
|         `SELECT COUNT(*) AS count FROM notes WHERE isDeleted = 0;`, | ||||
|     ) as { count: number }; | ||||
|     return notesCount.count; | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|     getNoteSize, | ||||
|     getSubtreeSize | ||||
|     getSubtreeSize, | ||||
|     getNotesCount | ||||
| }; | ||||
|  | ||||
| @ -361,6 +361,7 @@ function register(app: express.Application) { | ||||
|     apiRoute(GET, "/api/similar-notes/:noteId", similarNotesRoute.getSimilarNotes); | ||||
|     apiRoute(GET, "/api/backend-log", backendLogRoute.getBackendLog); | ||||
|     apiRoute(GET, "/api/stats/note-size/:noteId", statsRoute.getNoteSize); | ||||
|     apiRoute(GET, "/api/stats/notesCount", statsRoute.getNotesCount); | ||||
|     apiRoute(GET, "/api/stats/subtree-size/:noteId", statsRoute.getSubtreeSize); | ||||
|     apiRoute(PST, "/api/delete-notes-preview", notesApiRoute.getDeleteNotesPreview); | ||||
|     route(GET, "/api/fonts", [auth.checkApiAuthOrElectron], fontsRoute.getFontCss); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SiriusXT
						SiriusXT