Skip to content

Instantly share code, notes, and snippets.

@typeetfunc
Last active September 24, 2016 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save typeetfunc/9f5e8065367f8adb448813e5e020136e to your computer and use it in GitHub Desktop.
Save typeetfunc/9f5e8065367f8adb448813e5e020136e to your computer and use it in GitHub Desktop.
# Использование Immutable.js
## Зачем?
Как известно главным способом оптимизации является растановка PureRenderMixin добавляющий
shouldComponentUpdate компоненту - https://facebook.github.io/react/docs/pure-render-mixin.html
Однако у данного способа есть минус - производится только поверхностное сравнение state и props.
Если мы изменим их гдето в глубине по ссылке - компонент этого не заметит и не перерендерится
Если мы случайно пересоздадим обьект с теми же данными то компонент перерендерится - несмотря на то
что данные посути не изменились.
как решать эти 2 проблемы?
первую проблему можем решить "административно" - никогда не изменять данные по ссылке(так принято делать сейчас):
пример
Вместо
var data = this.state.data;
data.param = 'newValue';
this.setState({data});
Пишем
var data = this.state.data;
this.setState({data: {...data, param: 'newValue'}});
Однако вторая проблема этим не решается
this.setState({data: {...data, param: 'oldValue'}});
вызовет полный ре-рендер компонента - хотя вроде как ничего изменилось
Возможное решение - всегда держать стейт и пропс "плоскими" - т.е. без вложенности
Возможно ли это? очень врятли - хотя надо старатся делать именно так.
Почему же примитивы сравниваются всегда верно то есть 'aaa' === 'aaa' всегда?
Дело в том что и числа и строки иммутабельны - их нельзя изменить по ссылке.
Следовательно компилятор может мемоизировать результат аллокации.
То есть первый раз пишем 'aaa' компилятор создает участок памяти куда складывает эту строку,
и затем если мы еще раз пишем 'aaa' коммпилятор просто возврашает ссылку на уже выделенную память,
тем самым экономив аллокации.
Как быть? Ответ - использовать иммутабельные структуры данных к примеру Immutable.js https://facebook.github.io/immutable-js
данная библиотека предоставляет большое число неизменяемых структур данных
var map1 = Immutable.Map({a:1, b:2, c:3});
var map2 = map1.set('b', 2);
assert(map1 === map2); // no change
var map3 = map1.set('b', 50);
assert(map1 !== map3); // change
с довольно неплохим апи позволяющем смешивать жс-структуры с структурами из библиотеки
Таким образом использоваие подобной библиотеки позволяет:
1) Избежать лишних перерендеров компонентов(довольно дорогих)
2) избежать лишних аллокаций(особенно по срравнению с "ручным" поддержанием иммутабельности) -
иммутабельные структуры данных это такой gzip для данных позволяющий переиспользовать куски данных
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment