Мемоизация — это техника оптимизации, направленная на кэширование результатов функций для избежания повторных вычислений при одинаковых входных данных. В контексте Slim.js мемоизация играет ключевую роль при работе с реактивными компонентами, позволяя уменьшить нагрузку на рендеринг и повысить производительность приложений.
В основе мемоизации лежит сопоставление аргументов функции с её результатами. Когда функция вызывается с набором аргументов, который уже встречался ранее, возвращается сохранённый результат, вместо повторного вычисления.
Ключевые моменты:
Slim.js предоставляет реактивные свойства через декораторы и хук
@State. При изменении состояния компонента происходит
повторный рендеринг, что может приводить к повторным вызовам функций
вычисления значений. Мемоизация позволяет уменьшить количество таких
повторных вычислений.
Пример:
import { Slim, html, State } from 'slim-js';
class FibonacciComponent extends Slim {
@State()
n = 10;
fib = this.memoize((num) => {
if (num <= 1) return 1;
return this.fib(num - 1) + this.fib(num - 2);
});
render() {
return html`
<div>
<p>Fibonacci(${this.n}) = ${this.fib(this.n)}</p>
</div>
`;
}
}
customElements.define('fibonacci-component', FibonacciComponent);
В этом примере метод fib обёрнут в мемоизирующую
функцию. Каждый вызов с одинаковым аргументом использует кэшированный
результат, что значительно снижает количество рекурсивных
вычислений.
Slim.js не предоставляет встроенного универсального декоратора для мемоизации, поэтому часто используют собственную утилиту:
memoize(fn) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
Особенности этой реализации:
JSON.stringify)
позволяет использовать их как ключи.fn.apply(this, args).Slim.js поддерживает @Computed свойства, которые
пересчитываются только при изменении зависимостей. Мемизация может быть
интегрирована с @Computed для минимизации лишних
пересчетов.
import { Slim, html, State, Computed } from 'slim-js';
class FilteredList extends Slim {
@State()
items = [1, 2, 3, 4, 5];
@State()
filterValue = 3;
filteredItems = this.memoize(() =>
this.items.filter(i => i > this.filterValue)
);
render() {
return html`
<ul>
${this.filteredItems().map(item => html`<li>${item}</li>`)}
</ul>
`;
}
}
Здесь filteredItems пересчитывается только при изменении
items или filterValue. Мемоизация
предотвращает лишние фильтрации при повторных рендерах без изменения
входных данных.
Мемоизация особенно полезна при:
Правильное использование мемоизации позволяет:
JSON.stringify для точного и быстрого
кэширования.Мемоизация в Slim.js объединяет преимущества реактивного подхода с оптимизацией вычислений, обеспечивая высокую производительность даже при больших и динамически изменяемых интерфейсах.