I am trying to build excel like tool in frontend with formulas.
As may guess the main point is to be able to change cell if its dependencies are changed.
From the first look I thought this library is ideal for me, but...
After starting using it I saw performance dropped by more than 1000x and app basically became unresponsive...
When I made isolated repro I see it is really slower(like 100x slower than recalculating every time with), and that is my main problem:
import { memoize } from "proxy-memoize";
const MAX_VALUE = 100;
function getRandomFloat() {
return Math.random() * MAX_VALUE;
}
let nextId = 1;
function getId() {
return nextId++;
}
type El = {
col0: number;
col1: number;
col2: number;
col3: number;
col4: number;
id: number;
};
const longArr = new Array(1000).fill(0).map((_, i) => ({
col0: getRandomFloat(),
col1: getRandomFloat(),
col2: getRandomFloat(),
col3: getRandomFloat(),
col4: getRandomFloat(),
id: getId(),
}));
function getCol0Value(arr: El[], rowId: number) {
const currRow = arr.find((el) => el.id === rowId)!;
return currRow.col1 * currRow.col2;
}
const mapFuncs = new Map<string, (arr: El[]) => number>();
function getCol0ValueMemoized(arr: El[], rowId: number) {
const id = `${rowId} - col0`;
const formula = mapFuncs.get(id);
if (formula) {
return formula(arr);
}
const memoizedFormula = memoize((arr: El[]) => getCol0Value(arr, rowId));
mapFuncs.set(id, memoizedFormula);
return memoizedFormula(arr);
}
function getRows(arr: El[]) {
return arr.map((el) => {
// change below `getCol0ValueMemoized` to getCol0Value and see performance boost
return { ...el, col0: getCol0ValueMemoized(arr, el.id) };
});
}
const initialGetRowsLabel = "initial get rows";
console.time(initialGetRowsLabel);
const _rows1 = getRows(longArr);
console.timeEnd(initialGetRowsLabel); // 500ms vs 4ms
// change dependency and recalculate
const newArr = longArr.map((el, i) =>
i === 0 ? { ...el, col3: getRandomFloat() } : el,
);
const afterChangeGetRowsLabel = "after change";
console.time(afterChangeGetRowsLabel);
const _rows2 = getRows(newArr);
console.timeEnd(afterChangeGetRowsLabel); // 100ms vs 5ms
I am using zustand library for it. As you main see main idea is that cell may depend on any other cells from the array(or excel page).
Maybe proxy-memoize just is not designed for such use case?
Or maybe you can recommend some other library, or solution to not recalculate formulas for cell if its dependencies are not changed?
For now I just cannot use this library unfortunately...
I am trying to build excel like tool in frontend with formulas.
As may guess the main point is to be able to change cell if its dependencies are changed.
From the first look I thought this library is ideal for me, but...
After starting using it I saw performance dropped by more than 1000x and app basically became unresponsive...
When I made isolated repro I see it is really slower(like 100x slower than recalculating every time with), and that is my main problem:
I am using
zustandlibrary for it. As you main see main idea is that cell may depend on any other cells from the array(or excel page).Maybe
proxy-memoizejust is not designed for such use case?Or maybe you can recommend some other library, or solution to not recalculate formulas for cell if its dependencies are not changed?
For now I just cannot use this library unfortunately...