Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optimize addLog performance #567

Merged
merged 1 commit into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 78 additions & 47 deletions src/log/log.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export class VConsoleLogModel extends VConsoleModel {
public maxLogNumber: number = 1000;
protected logCounter: number = 0; // a counter used to do some tasks on a regular basis
protected pluginPattern: RegExp;
protected logQueue: IVConsoleLog[] = [];
protected flushLogScheduled: boolean = false;

/**
* The original `window.console` methods.
Expand Down Expand Up @@ -113,7 +115,7 @@ export class VConsoleLogModel extends VConsoleModel {

/**
* Hook `window.console` with vConsole log method.
* Methods will be hooked only once.
* Methods will be hooked only once.
*/
public mockConsole() {
if (typeof this.origConsole.log === 'function') {
Expand Down Expand Up @@ -228,7 +230,7 @@ export class VConsoleLogModel extends VConsoleModel {
return store;
});
}

/**
* Add a vConsole log.
*/
Expand All @@ -249,16 +251,8 @@ export class VConsoleLogModel extends VConsoleModel {
// }
// log.data = getLogDatasWithFormatting(item?.origData);

// extract pluginId by `[xxx]` format
const pluginId = this._extractPluginIdByLog(log);
this._signalLog(log);

if (this._isRepeatedLog(pluginId, log)) {
this._updateLastLogRepeated(pluginId);
} else {
this._pushLogList(pluginId, log);
this._limitLogListLength();
}

if (!opt?.noOrig) {
// logging to original console
this.callOriginalConsole(item.type, ...item.origData);
Expand Down Expand Up @@ -292,6 +286,54 @@ export class VConsoleLogModel extends VConsoleModel {
}, { cmdType: 'output' });
};

protected _signalLog(log: IVConsoleLog) {
// throttle addLog
if (!this.flushLogScheduled) {
this.flushLogScheduled = true;
window.requestAnimationFrame(() => {
this.flushLogScheduled = false;
this._flushLogs();
});
}
this.logQueue.push(log);
}

protected _flushLogs() {
const logQueue = this.logQueue;
this.logQueue = [];
const pluginLogs: Record<string, IVConsoleLog[]> = {};

// extract pluginId by `[xxx]` format
for (const log of logQueue) {
const pluginId = this._extractPluginIdByLog(log);

(pluginLogs[pluginId] = pluginLogs[pluginId] || []).push(log);
}

const pluginIds = Object.keys(plugin;Logs)
for (const pluginId of pluginIds) {
const logs = pluginLogs[pluginId];

const store = Store.get(pluginId);
store.update((store) => {
let logList = [...store.logList];

for (const log of logs) {
if (this._isRepeatedLog(logList, log)) {
this._updateLastLogRepeated(logList);
} else {
logList.push(log);
}
}

logList = this._limitLogListLength(logList);

return { logList };
})
}
contentStore.updateTime();
}

protected _extractPluginIdByLog(log: IVConsoleLog) {
// if origData[0] is `[xxx]` format, and `xxx` is a Log plugin id,
// then put this log to that plugin,
Expand All @@ -312,9 +354,8 @@ export class VConsoleLogModel extends VConsoleModel {
return pluginId;
}

protected _isRepeatedLog(pluginId: string, log: IVConsoleLog) {
const store = Store.getRaw(pluginId);
const lastLog = store.logList[store.logList.length - 1];
protected _isRepeatedLog(logList: IVConsoleLog[], log: IVConsoleLog) {
const lastLog = logList[logList.length - 1];
if (!lastLog) {
return false;
}
Expand All @@ -332,42 +373,32 @@ export class VConsoleLogModel extends VConsoleModel {
return isRepeated;
}

protected _updateLastLogRepeated(pluginId: string) {
Store.get(pluginId).update((store) => {
const list = store.logList
const last = list[list.length - 1];
last.repeated = last.repeated ? last.repeated + 1 : 2;
return store;
});
}

protected _pushLogList(pluginId: string, log: IVConsoleLog) {
Store.get(pluginId).update((store) => {
store.logList.push(log);
return store;
});
contentStore.updateTime();
protected _updateLastLogRepeated(logList: IVConsoleLog[]) {
const last = logList[logList.length - 1];
const repeated = last.repeated ? last.repeated + 1 : 2;
logList[logList.length - 1] = {
...last,
repeated,
};
return logList;
}

protected _limitLogListLength() {
protected _limitLogListLength(logList: IVConsoleLog[]): IVConsoleLog[] {
// update logList length every N rounds
const N = 10;
this.logCounter++;
if (this.logCounter % N !== 0) {
return;
}
this.logCounter = 0;

const stores = Store.getAll();
for (const id in stores) {
stores[id].update((store) => {
if (store.logList.length > this.maxLogNumber - N) {
// delete N more logs for performance
store.logList.splice(0, store.logList.length - this.maxLogNumber + N);
// this.callOriginalConsole('info', 'delete', id, store[id].logList.length);
}
return store;
});
// const N = 10;
// this.logCounter++;
// if (this.logCounter % N !== 0) {
// return logList;
// }
// this.logCounter = 0;

const len = logList.length;
const maxLen = this.maxLogNumber;
if (len > maxLen) {
// delete N more logs for performance
// this.callOriginalConsole('info', 'delete', len, len - maxLen);
return logList.slice(len - maxLen, len);
}
return logList;
}
}
3 changes: 2 additions & 1 deletion src/log/logRow.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<svelte:options immutable/>
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import * as tool from '../lib/tool';
Expand Down Expand Up @@ -42,7 +43,7 @@
const isTree = (origData: any) => {
return !(origData instanceof VConsoleUninvocatableObject) && (tool.isArray(origData) || tool.isObject(origData));
};

const onTapCopy = () => {
const text: string[] = [];
try {
Expand Down
1 change: 1 addition & 0 deletions src/log/logTree.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<svelte:options immutable/>
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import * as tool from '../lib/tool';
Expand Down
1 change: 1 addition & 0 deletions src/log/logValue.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<svelte:options immutable/>
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import * as tool from '../lib/tool';
Expand Down