refactor(editor): 优化依赖收集,优先收集数据源依赖

This commit is contained in:
roymondchen 2025-01-10 19:31:41 +08:00
parent 1baec3f1d4
commit 895c461e2b
2 changed files with 32 additions and 10 deletions

View File

@ -29,6 +29,7 @@ export interface DepEvents {
'add-target': [target: Target]; 'add-target': [target: Target];
'remove-target': [id: string | number]; 'remove-target': [id: string | number];
collected: [nodes: MNode[], deep: boolean]; collected: [nodes: MNode[], deep: boolean];
'ds-collected': [nodes: MNode[], deep: boolean];
} }
interface State { interface State {
@ -96,6 +97,7 @@ class Dep extends BaseService {
this.set('collecting', false); this.set('collecting', false);
this.emit('collected', nodes, deep); this.emit('collected', nodes, deep);
this.emit('ds-collected', nodes, deep);
} }
public collectIdle(nodes: MNode[], depExtendedData: DepExtendedData = {}, deep = false, type?: DepTargetType) { public collectIdle(nodes: MNode[], depExtendedData: DepExtendedData = {}, deep = false, type?: DepTargetType) {
@ -119,6 +121,9 @@ class Dep extends BaseService {
this.set('collecting', false); this.set('collecting', false);
resolve(); resolve();
}); });
idleTask.once('hight-level-finish', () => {
this.emit('ds-collected', nodes, deep);
});
}); });
} }
@ -185,6 +190,7 @@ class Dep extends BaseService {
deep: false, deep: false,
target, target,
}, },
target.type === DepTargetType.DATA_SOURCE,
); );
if (deep && Array.isArray(node.items) && node.items.length) { if (deep && Array.isArray(node.items) && node.items.length) {

View File

@ -2,8 +2,14 @@ import { EventEmitter } from 'events';
export interface IdleTaskEvents { export interface IdleTaskEvents {
finish: []; finish: [];
'hight-level-finish': [];
} }
type TaskList<T> = {
handler: (data: T) => void;
data: T;
}[];
globalThis.requestIdleCallback = globalThis.requestIdleCallback =
globalThis.requestIdleCallback || globalThis.requestIdleCallback ||
function (cb) { function (cb) {
@ -19,10 +25,9 @@ globalThis.requestIdleCallback =
}; };
export class IdleTask<T = any> extends EventEmitter { export class IdleTask<T = any> extends EventEmitter {
private taskList: { private taskList: TaskList<T> = [];
handler: (data: T) => void;
data: T; private hightLevelTaskList: TaskList<T> = [];
}[] = [];
private taskHandle: number | null = null; private taskHandle: number | null = null;
@ -31,8 +36,8 @@ export class IdleTask<T = any> extends EventEmitter {
this.setMaxListeners(1000); this.setMaxListeners(1000);
} }
public enqueueTask(taskHandler: (data: T) => void, taskData: T) { public enqueueTask(taskHandler: (data: T) => void, taskData: T, isHightLevel = false) {
this.taskList.push({ (isHightLevel ? this.hightLevelTaskList : this.taskList).push({
handler: taskHandler, handler: taskHandler,
data: taskData, data: taskData,
}); });
@ -43,6 +48,11 @@ export class IdleTask<T = any> extends EventEmitter {
} }
public clearTasks() { public clearTasks() {
if (this.taskHandle) {
globalThis.cancelIdleCallback(this.taskHandle);
}
this.hightLevelTaskList = [];
this.taskList = []; this.taskList = [];
} }
@ -65,10 +75,12 @@ export class IdleTask<T = any> extends EventEmitter {
} }
private runTaskQueue(deadline: IdleDeadline) { private runTaskQueue(deadline: IdleDeadline) {
const { hightLevelTaskList, taskList } = this;
// 动画会占用空闲时间,当任务一直无法执行时,看看是否有动画正在播放 // 动画会占用空闲时间,当任务一直无法执行时,看看是否有动画正在播放
// 根据空闲时间的多少来决定执行的任务数,保证页面不卡死的情况下尽量多执行任务,不然当任务数巨大时,执行时间会很久 // 根据空闲时间的多少来决定执行的任务数,保证页面不卡死的情况下尽量多执行任务,不然当任务数巨大时,执行时间会很久
// 执行不完不会影响配置,但是会影响画布渲染 // 执行不完不会影响配置,但是会影响画布渲染
while (deadline.timeRemaining() > 0 && this.taskList.length) { while (deadline.timeRemaining() > 0 && taskList.length) {
const timeRemaining = deadline.timeRemaining(); const timeRemaining = deadline.timeRemaining();
let times = 0; let times = 0;
if (timeRemaining <= 5) { if (timeRemaining <= 5) {
@ -82,18 +94,22 @@ export class IdleTask<T = any> extends EventEmitter {
} }
for (let i = 0; i < times; i++) { for (let i = 0; i < times; i++) {
const task = this.taskList.shift(); const task = hightLevelTaskList.length > 0 ? hightLevelTaskList.shift() : taskList.shift();
if (task) { if (task) {
task.handler(task.data); task.handler(task.data);
} }
if (this.taskList.length === 0) { if (hightLevelTaskList.length === 0 && taskList.length === 0) {
break; break;
} }
} }
} }
if (this.taskList.length) { if (!hightLevelTaskList.length) {
this.emit('hight-level-finish');
}
if (hightLevelTaskList.length || taskList.length) {
this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 }); this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 });
} else { } else {
this.taskHandle = 0; this.taskHandle = 0;