Last active
September 24, 2016 18:40
-
-
Save typeetfunc/9f5e8065367f8adb448813e5e020136e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Использование 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