Мемоизация — ключевой инструмент для повышения производительности приложений на JavaScript-фреймворках, включая Inferno. Она позволяет избежать повторного рендеринга компонентов, когда их входные данные не изменились, экономя ресурсы и ускоряя работу интерфейса.
В Inferno компоненты могут быть функциональными или классовыми. Для функциональных компонентов мемоизация позволяет кешировать результат рендера на основе пропсов. Если пропсы остаются неизменными между рендерами, компонент не будет пересоздан, что снижает нагрузку на виртуальный DOM.
Пример функционального компонента:
import { render } from 'inferno';
import { memo } from 'inferno-memo';
const Button = ({ label, onClick }) => {
console.log('Button render');
return <button onCl ick={onClick}>{label}</button>;
};
const MemoizedButton = memo(Button);
render(<MemoizedButton label="Click me" onCl ick={() => console.log('Clicked')} />, document.getElementById('app'));
В данном примере memo оборачивает компонент
Button и предотвращает его повторный рендер, если
label и onClick остаются неизменными.
Механизм memo в Inferno схож с React.memo и
выполняет аналогичные функции:
Пример кастомной функции сравнения:
const areEqual = (prevProps, nextProps) => {
return prevProps.label === nextProps.label && prevProps.value === nextProps.value;
};
const CustomMemoButton = memo(Button, areEqual);
Для сложных вычислений внутри компонента полезно использовать useMemo-подобные подходы, чтобы пересчет происходил только при изменении зависимостей.
Пример мемоизации вычислений:
import { useMemo } from 'inferno-hooks';
const ExpensiveComponent = ({ data }) => {
const processedData = useMemo(() => {
console.log('Processing data');
return data.map(item => item * 2);
}, [data]);
return <div>{processedData.join(', ')}</div>;
};
В этом примере processedData пересчитывается только
тогда, когда изменяется массив data.
Частая проблема производительности — создание новых функций при каждом рендере. В Inferno можно использовать useCallback для мемоизации коллбеков, аналогично React:
import { useCallback } from 'inferno-hooks';
const Counter = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prev => prev + 1);
}, []);
return <button onCl ick={increment}>{count}</button>;
};
Использование useCallback предотвращает создание новой
функции increment при каждом рендере, что особенно важно
для мемоизированных дочерних компонентов.
Для классовых компонентов мемоизация осуществляется с помощью
shouldComponentUpdate или
PureComponent. PureComponent автоматически
выполняет поверхностное сравнение пропсов и состояния:
import { Component, render } from 'inferno';
class Button extends Component {
shouldComponentUpdate(nextProps) {
return this.props.label !== nextProps.label;
}
render() {
console.log('Button render');
return <button onCl ick={this.props.onClick}>{this.props.label}</button>;
}
}
Использование shouldComponentUpdate или
PureComponent позволяет контролировать ререндер на уровне
классового компонента.
Мемоизация в Inferno позволяет добиться высокой производительности за счет минимизации лишних рендеров и пересчетов. Она применяется как на уровне компонентов, так и на уровне вычислений и событий, обеспечивая гибкую и масштабируемую оптимизацию интерфейсов.