Open lifeart opened 4 months ago
Comparing to existing Lamport clocks model in GlimmerVM we eliminate tag re-validation phase, and literally executing only values needs to be updated.
Benefits comparing to Lamport clock - is:
Benefits to have update-only VM:
Lookup stage looks like
// DEDUPLICATED SET OF MERGED_CELLS
const MERGED_CELLS_TO_INVALIDATE = new Set();
// ACTUALLY CHANGED CELLS
TAGS_TO_INVALIDATE.forEach((CELL) => {
OPCODES_FOR_CELL(CELL).forEach((opcode) => {
execute(opcode);
});
RELATED_MERGED_CELLS(CELL).forEach((RELATED_CELL) => {
MERGED_CELLS_TO_INVALIDATE.add(RELATED_CELL);
});
});
// DERIVED CELLS
MERGED_CELLS_TO_INVALIDATE.forEach((CELL) => {
OPCODES_FOR_CELL(CELL).forEach((opcode) => {
execute(opcode);
});
});
GXT introduces a streamlined reactivity system inspired by Glimmer's @tracked
but with a focus on explicit DOM updates and minimal overhead. This system allows you to build dynamic UIs where changes in data automatically propagate to the view, without the complexity of traditional invalidation-based approaches.
Cells: The fundamental building block of reactivity in GXT is the Cell
. A Cell
holds a value and provides a mechanism to update that value. When a Cell
's value changes, GXT tracks this change and schedules a DOM update.
Formula: Formula
represent derived state. They are functions that depend on one or more Cells
. When the value of any dependent Cell
changes, the Formula
automatically recalculates its value.
Explicit DOM Updates: GXT doesn't rely on a virtual DOM or diffing algorithms. Instead, it explicitly updates only the parts of the DOM that are affected by a change in reactive data. This results in highly efficient updates and minimal overhead.
Opcodes: GXT uses "opcodes" to represent DOM operations associated with reactive data. When a Cell
's value changes, its associated opcodes are executed, updating the DOM accordingly.
Simplicity: GXT's reactivity system is easy to understand and use. You simply define Cells
to hold your data and Formula
to derive state. GXT handles the rest.
Efficiency: Explicit DOM updates ensure that only the necessary parts of the UI are re-rendered, resulting in excellent performance.
Flexibility: GXT's reactivity system is flexible enough to handle complex scenarios, including nested reactivity and asynchronous updates.
import { cell, formula } from '@lifeart/gxt';
const count = cell(0); // Define a Cell to hold the count
const doubled = formula(() => count.value * 2); // Derive the doubled value
// ... in your template ...
<span>{{count}}</span>
<span>{{doubled}}</span>
// ...
count.value++; // Updating the count will automatically update the DOM
In this example, updating the count
Cell
will trigger a re-evaluation of the doubled
Formula
and an update to the DOM elements displaying both values.
Reduced Boilerplate: GXT's reactivity system eliminates the need for manual DOM manipulation, reducing code complexity and improving maintainability.
Improved Performance: Explicit DOM updates minimize unnecessary re-renders, leading to faster and smoother UI updates.
Enhanced Developer Experience: GXT's simple and intuitive reactivity system makes it easier to build dynamic and responsive applications.
This reactivity system is a core part of GXT's philosophy of providing a lightweight and performant framework for building modern web applications.