Skip to content

Commit

Permalink
feat: debounce to save CPU
Browse files Browse the repository at this point in the history
  • Loading branch information
linonetwo committed May 22, 2024
1 parent bf59b39 commit 8cb0785
Show file tree
Hide file tree
Showing 14 changed files with 74 additions and 30 deletions.
4 changes: 3 additions & 1 deletion src/commandpalette/configs/config.tid
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ caption: <<lingo Name $:/plugins/linonetwo/commandpalette/language/>>
;<<lingo Configs/TextAlias/Caption>>
:<$edit-text tiddler="$:/plugins/linonetwo/commandpalette/configs/TextAlias" tabindex=-1 focus=false cancelPopups="yes" fileDrop=no tag="input" /> <<lingo Configs/TextAlias/Description>>
;<<lingo Configs/DesktopWidth/Caption>>
:<$edit-text tiddler="$:/plugins/linonetwo/commandpalette/configs/DesktopWidth" tabindex=-1 focus=false cancelPopups="yes" fileDrop=no tag="input" type="number" />% <<lingo Configs/DesktopWidth/Description>>
:<$edit-text tiddler="$:/plugins/linonetwo/commandpalette/configs/DesktopWidth" tabindex=-1 focus=false cancelPopups="yes" fileDrop=no tag="input" type="number" />% <<lingo Configs/DesktopWidth/Description>>
;<<lingo Configs/DebounceDuration/Caption>>
:<$edit-text tiddler="$:/plugins/linonetwo/commandpalette/configs/DebounceDuration" tabindex=-1 focus=false cancelPopups="yes" fileDrop=no tag="input" type="number" />ms <<lingo Configs/DebounceDuration/Description>>
3 changes: 2 additions & 1 deletion src/commandpalette/configs/configs.multids
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ TitleAlias: title caption alias
TextAlias: text keywords
HideDefaultSearchBar: no
TitlePriorityText: no
DesktopWidth: 80
DesktopWidth: 80
DebounceDuration: 300
2 changes: 2 additions & 0 deletions src/commandpalette/language/en-GB/Translations.multids
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Configs/DesktopWidth/Caption: Width on desktop mode
Configs/DesktopWidth/Description: Width of the input and result boxes on the screen (does not affect mobile, which is full screen by default)
Configs/TitlePriorityText/Caption: Title higher than text.
Configs/TitlePriorityText/Description: When checked, title search results will be listed on the top, and text search results will be listed below, when searching user tiddlers. (The result on the bottom can be selected by pressing the ↑ up arrow key to circle go to the bottom of the search results)
Configs/DebounceDuration/Caption: Search debounce duration
Configs/DebounceDuration/Description: Pressing a key to search once will lead to lagging, here set the search anti-shake duration, meaning two consecutive key presses within this duration will be judged as inputting, and will wait for you to finish typing before searching, in milliseconds.
SystemTitle: Title of system tiddler
UserTitle: Title of user tiddler
UserTitlePinyin: Title Pinyin of user tiddler
Expand Down
2 changes: 2 additions & 0 deletions src/commandpalette/language/zh-Hans/Translations.multids
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Configs/DesktopWidth/Caption: 桌面模式宽度
Configs/DesktopWidth/Description: 输入框和结果框占屏幕的宽度(不影响移动端,移动端默认全屏)
Configs/TitlePriorityText/Caption: 标题高于内容
Configs/TitlePriorityText/Description: 勾选后,在搜索用户内容时,将标题搜索结果排在上面,内容搜索结果排在下面。(下面的内容可以通过按↑上方向键转到搜索结果的底部来选择)
Configs/DebounceDuration/Caption: 搜索防抖时长
Configs/DebounceDuration/Description: 按一个键就搜一次会导致卡顿,这里设置搜索防抖时长,意思是两次连续按键在这个时长内就判定为输入中,就会等你输入完再搜索,单位毫秒。
UserTitle: 用户条目标题
SystemTitle: 系统条目标题
UserTitlePinyin: 用户条目标题拼音
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ import type { AutocompletePlugin } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsSearchSystem, checkIsUnderFilter } from '../utils/checkPrefix';
import { IContext } from '../utils/context';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { lingo } from '../utils/lingo';
import { renderTextWithCache } from '../utils/renderTextWithCache';

export const plugin = {
getSources(parameters) {
async getSources(parameters) {
if (parameters.query.length === 0) return [];
if (!checkIsSearchSystem(parameters) || checkIsUnderFilter(parameters)) return [];
const focusedTiddler = $tw.wiki.getTiddlerText('$:/temp/focussedTiddler');
const variables = { currentTiddler: focusedTiddler ?? '', commandpaletteinput: parameters.query.slice(1) };
const { widget } = parameters.state.context as IContext;
return [
return await debounced([
{
sourceId: 'actionString',
async getItems({ query }) {
Expand Down Expand Up @@ -60,6 +61,6 @@ export const plugin = {
},
},
},
];
]);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ import type { AutocompletePlugin } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsSearchSystem, checkIsUnderFilter } from '../utils/checkPrefix';
import { IContext } from '../utils/context';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { lingo } from '../utils/lingo';
import { renderTextWithCache } from '../utils/renderTextWithCache';

export const plugin = {
getSources(parameters) {
async getSources(parameters) {
if (parameters.query.length === 0) return [];
if (!checkIsSearchSystem(parameters) || checkIsUnderFilter(parameters)) return [];
const focusedTiddler = $tw.wiki.getTiddlerText('$:/temp/focussedTiddler');
const variables = { currentTiddler: focusedTiddler ?? '' };
const { widget } = parameters.state.context as IContext;
return [
return await debounced([
{
sourceId: 'message',
async getItems({ query }) {
Expand Down Expand Up @@ -70,6 +71,6 @@ export const plugin = {
},
},
},
];
]);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import type { AutocompletePlugin } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsSearchSystem, checkIsUnderFilter } from '../utils/checkPrefix';
import { IContext } from '../utils/context';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { lingo } from '../utils/lingo';
import { renderTextWithCache } from '../utils/renderTextWithCache';

export const plugin = {
getSources(parameters) {
async getSources(parameters) {
if (parameters.query.length === 0) return [];
if (!checkIsSearchSystem(parameters) || checkIsUnderFilter(parameters)) return [];
const { widget } = parameters.state.context as IContext;
return [
return await debounced([
{
sourceId: 'config',
async getItems({ query }) {
Expand Down Expand Up @@ -42,6 +43,6 @@ export const plugin = {
},
},
},
];
]);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
import type { AutocompletePlugin, GetSources } from '@algolia/autocomplete-js';
import type { AutocompletePlugin, AutocompleteSource } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsFilter, checkIsSearchSystem, checkIsUnderFilter } from '../utils/checkPrefix';
import { IContext } from '../utils/context';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { lingo } from '../utils/lingo';
import { renderTextWithCache } from '../utils/renderTextWithCache';

export const plugin = {
getSources(parameters) {
const sources: ReturnType<GetSources<ITiddlerFields>> = [];
async getSources(parameters) {
const sources: Array<AutocompleteSource<ITiddlerFields>> = [];
if (checkIsFilter(parameters)) {
const { widget } = parameters.state.context as IContext;
sources.push({
Expand Down Expand Up @@ -96,6 +97,6 @@ export const plugin = {
},
});
}
return sources;
return await debounced(sources);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import type { AutocompletePlugin } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsSearchSystem, checkIsUnderFilter } from '../utils/checkPrefix';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { lingo } from '../utils/lingo';

export const plugin = {
getSources(parameters) {
async getSources(parameters) {
if (parameters.query.length === 0) return [];
if (!checkIsSearchSystem(parameters) || checkIsUnderFilter(parameters)) return [];
return [
return await debounced([
{
sourceId: 'system-title',
async getItems({ query }) {
Expand All @@ -30,6 +31,6 @@ export const plugin = {
},
},
},
];
]);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ import type { AutocompletePlugin } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsSearchTags } from '../utils/checkPrefix';
import { IContext } from '../utils/context';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { lingo } from '../utils/lingo';

export const plugin = {
getSources(parameters) {
async getSources(parameters) {
if (parameters.query.length === 0) return [];
if (!checkIsSearchTags(parameters)) {
return [];
}
return [{
return await debounced([{
// suggest tags for user to search
sourceId: 'tags',
async getItems({ query }) {
Expand Down Expand Up @@ -39,6 +40,6 @@ export const plugin = {
return lingo('NoResult');
},
},
}];
}]);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import type { AutocompletePlugin } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsSearchUser, checkIsUnderFilter } from '../utils/checkPrefix';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { getFieldsAsText } from '../utils/getFieldsAsTitle';
import { lingo } from '../utils/lingo';

export const plugin = {
getSources(parameters) {
async getSources(parameters) {
if (parameters.query.length === 0) return [];
if (!checkIsSearchUser(parameters) || checkIsUnderFilter(parameters)) return [];
return [
return await debounced([
{
sourceId: 'text',
async getItems({ query }) {
Expand Down Expand Up @@ -56,6 +57,6 @@ export const plugin = {
},
},
},
];
]);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { AutocompletePlugin } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsSearchUser, checkIsUnderFilter } from '../utils/checkPrefix';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { getFieldsAsTitle } from '../utils/getFieldsAsTitle';
import { lingo } from '../utils/lingo';

export const plugin = {
getSources(parameters) {
async getSources(parameters) {
if (!checkIsSearchUser(parameters) || checkIsUnderFilter(parameters)) return [];
if (
// check `pinyinfuse` operator is installed
Expand All @@ -17,7 +18,7 @@ export const plugin = {
return [];
}
if (parameters.query.length === 0) return [];
return [
return await debounced([
{
sourceId: 'title-pinyin',
async getItems({ query }) {
Expand All @@ -39,6 +40,6 @@ export const plugin = {
},
},
},
];
]);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import type { AutocompletePlugin } from '@algolia/autocomplete-js';
import { ITiddlerFields } from 'tiddlywiki';
import { checkIsSearchUser, checkIsUnderFilter } from '../utils/checkPrefix';
import { debounced } from '../utils/debounce';
import { filterTiddlersAsync } from '../utils/filterTiddlersAsync';
import { getFieldsAsTitle } from '../utils/getFieldsAsTitle';
import { lingo } from '../utils/lingo';

export const plugin = {
getSources(parameters) {
async getSources(parameters) {
if (parameters.query.length === 0) return [];
if (!checkIsSearchUser(parameters) || checkIsUnderFilter(parameters)) return [];
return [
return await debounced([
{
sourceId: 'title',
async getItems({ query }) {
Expand All @@ -31,6 +32,6 @@ export const plugin = {
},
},
},
];
]);
},
} satisfies AutocompletePlugin<ITiddlerFields, unknown>;
28 changes: 28 additions & 0 deletions src/commandpalette/widgets/utils/debounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-return */

import { AutocompleteSource } from '@algolia/autocomplete-shared';
import { ITiddlerFields } from 'tiddlywiki';

/* eslint-disable @typescript-eslint/no-unsafe-argument */
type AnyFunction = (...arguments_: any[]) => any;

export function debouncePromise<T extends AnyFunction>(function_: T, time: number): (...arguments_: Parameters<T>) => Promise<ReturnType<T>> {
let timerId: ReturnType<typeof setTimeout>;

return async function debounced(...arguments_: Parameters<T>): Promise<ReturnType<T>> {
if (timerId) {
clearTimeout(timerId);
}

return await new Promise<ReturnType<T>>((resolve) => {
timerId = setTimeout(() => {
resolve(function_(...arguments_));
}, time);
});
};
}

const debounceDuration = Number($tw.wiki.getTiddlerText('$:/plugins/linonetwo/commandpalette/configs/DebounceDuration', '300'));
export const debounced = debouncePromise(async (items: Array<AutocompleteSource<ITiddlerFields>>) => await Promise.resolve(items), debounceDuration);

0 comments on commit 8cb0785

Please sign in to comment.