Scheduler
Kivi scheduler is responsible for executing frame tasks like updating components, reading from DOM, executing microtasks and macrotasks.
Frame tasks
Frame tasks will be executed in batches, starting with updating components sorted by their depth in components tree, and then switching between read and write tasks until there are no tasks left.
There are two functions for accesing frame tasks: currentFrame()
to get task group for the current frame, and
nextFrame()
for the next frame.
Each frame task group provides different queues for components, DOM read and write tasks, and tasks that will be executed after all other tasks are finished:
currentFrame().updateComponent(c: Component<any, any>);
currentFrame().read(task: () => void);
currentFrame().write(task: () => void);
currentFrame().after(task: () => void);
Microtasks and Macrotasks
Scheduler also provides interface for adding microtasks and macrotasks into browser event loop.
scheduleMicrotask(cb: () => void)`
scheduleMacrotask(cb: () => void)`
Monotonically increasing clock
Each time scheduler finishes executing tasks from one of the queues, it increments internal clock. This clock can be used to implement efficient checks in components to detect which input parameter has been changed since the last update.
For example:
import {clock} from "kivi";
class Data {
mtime: number;
value: number;
constructor(value: number) {
this.mtime = clock();
this.value = value;
}
setValue(newValue: number) {
if (this.value !== newValue) {
this.value = newValue;
this.mtime = clock();
}
}
}
const MyComponent = new ComponentDescriptor<Data, any>()
.newPropsReceived((c, oldProps, newProps) => {
if (c.mtime < newProps.mtime) {
c.markDirty();
}
});
Here we need to check if component's mtime
property is older than mtime
in a data object, and if it is older,
we are marking component as dirty. When component finishes update, it will automatically set its mtime
to the current
clock()
value.