Как стать автором
Обновить
54
0
Корзунов Антон @kashey

javascript, webgl, maps, react, орфография(нет)

Отправить сообщение
> если ничего не изменилось и результат вызова mapStateToProps такой же

Вот именно этот момент мемоизация и обеспечивает. Именно этот момент является источником проблем. Совсем чуть чуть повычисляли значения — map/filter или просто getInitialProps() какой либо вызвали — и до свидания.
Возьмем redux-form, который будет дергать стейт на каждое нажатие клавиши. Или react-beautiful-dnd, который будет делать все тоже самое на каждое движение мышкой.
Всегда есть куча событий, которые изменяют стор, и дергают mapStateToProps, но совершенно не относятся к ВСЕМУ приложению — что-то одно маленькое должно обновиться, а все остальное — нет.
Исключительно чтобы атмосферу не греть. Потому что рендер ДОРОГО! Если что-то начинает пересовываться — оно не остановиться пока в PureComponent не упрется.
Основная задача mapStateToProps — быть pure и idempotent. А если вы с этим не согласны — лучше вообще redux не использовать.
На самом деле Reflect был вчера выпилен. А насчет прокси
— полифил примерно для всего — github.com/tvcutsem/harmony-reflect
— полифил только для прокси — github.com/GoogleChrome/proxy-polyfill
Оба достаточно просты — используют дескрипторы для перехвата доступа к полям обьектов, что в принципе не медленно, но сильно медленнее чем прямой доступ к обьектам.

К сожалению скрипт который измеряет скорость работает не в браузере, и показать чиселки для сравнения я сейчас не могу. Но то что работает — 100%
А ведь специально старался разделить порядки, чтобы понятнее было. Все тесты лежат в репе, просто запустите их и получите более нормальный вариант.
Это все еще pull, просто у любого инструмента есть свои ограничения. Я так думаю где-то глубоко в глубинах Vue живет что-то похожее, ну а в MobX (@computed) живет вообще почти что тоже самое.
В итоге и получается, что и коробки Vue, да и Angular, могут работать сильно быстрее. Ну просто потому что програмисты такие програмисты. Глаз за глаз за ними нужен. Ну или костыль. И memoize-state – фабрика костылей. Подопрет где нужно и все окей.
1. Можно использовать селекторы. Можно использовать просто различные helper функции без мемоизации. Можно использовать вообще все что угодно, и оно будет работать, но не всегда эффективно, посколько рано или поздно мемоизация в reselect «скроет» доступ к конкретным значениям, и memoize-state начнет агриться на более «высокоуровневые» значения.

2. И да и нет. Для того чтобы возможная «другая» мемоизация работала требуется предоставлять «одинаковые» обьекты завернутые в «однаковые» прокси. В общем там внутри все созданные прокси храняться в WeakMap, и без надобности не создаются.

Почему нет — потому что сам state между вызовами будет разный, и для него прокси будет создаваться каждый раз.
Как говорилось выше — без проблем пару миллионов в секунду.
У reselect есть одна проблема — он помнит только один последний результат.
Если у вас есть два инстанса компонента, то в начале первый что-то возьмет из state на основе своих props, а потом второй, а потом опять первый. И всегда кеш будет чистый, так как то что там храниться — «не подходит».
Полуофициальное решение проблемы — re-reselect, который позволяет указать как «разделять» компоненты.
Второе полуофициальное решение — завернуть createSelector в замыкание, так чтобы проблемы с кешом не будет. Но тогда они не смогут «шарить» кеш между инстансами.
beautiful-react-redux оборачивает mapStateTopProps в memoize-state «снаружи», и еще раз «внутри». Те для каждого отдельного элемента, и для всех целиком, на случай если разницы между ними нет.
В общем универсальное решение.
К сожалению SVG use достаточно странная конструкция, которая с одной стороны — изолирует вложенное содержимое, и его сложно стилизовать. А с другой стороны нет — стили, определенные внутри SVG, без проблем «текут» из изображение в изображение.
Есть и другая проблема — заливки (defs) не поддерживаются от слова вообще.

Вот хороший пример — codesandbox.io/s/k26937poxr, достаточно просто потыкать мышкой в html код, чтобы увидеть глубину падения.
Не забывайте про
import { setConfig } from 'react-hot-loader'
setConfig({ logLevel: 'debug' })
V4/next? Создай issue, дай сорсы — разберем.
В общем надо разработать философию — «зачем нужен RHL», и так чтобы адептам TDD продать можно было.
> Чтобы при Сtrl+R страница открывалась в том же виде что и до.
Вот есть у вас форма — пользователь ввел в нее данные и (!)обновил страницу.
— пользователь видит форму какой она была — пользователь очень рад.
— пользователь видит форму такой какой она _должна_ быть (со старыми данными) — пользователь не рад.
И оба этих варианта имеют право на жизнь. А то тот же самый пользователь не сохранит данные, потому что и так же все нормально.
А где есть два варианта — там есть и три.
Именно так и я поступил — в начале поныл, а потом написал полностью новую версию, с которой ныть уже не надо.
— работает не для всего (только компоненты)
V3 работал только для компонентов, доступных как переменные. V4 работает на уровне отрендереного React-дерева, в котором НЕ компонент не бывает. А вот то, что hot требует на вход компоненту — как раз логично. Это же базовый строительный блок. И обернуть достаточно «Application»(точку входа). Которая компонента по умолчанию.

— работает не всегда (изменения cW/DM)
К сожалению сложно опять что компонент немного по другому должен старотовать, так как изменение может находиться вне пределов функции. RHL ругнется в консоль, если заметит что-то странное, но обновлять ничего не будет.

— а порой и не работает (для HOC молча падает)
Кто?

— Ради экономии одного нажатия F5?
F5 вы можете сами нажать, а вот для того чтобы привести все приложение в старый стейт — потребуется 5-20 секунд.

— чтобы F5 восстанавливал его в том же состоянии
В общем случае это или не возможно (половине UI сложно прокинуть стейт из redux/mobx), или не нужно (половина элементов UI работают через свои стейты).

Как уже говорилась — версия 4 работает практически для любого приложения. Единственный способ «сломать» — добавить новую ноду перед старыми — следуя дефолтному поведению React все перемаунтит. Решили не бороться со своей стороны.

Некоторые люди считают, что RHL — «вреден». Имхо он позволяет использовать реальный IDE заместо браузерной консоли, чтобы поправить стили или поведение элементов, тем самым позволяя быстрее создать более приятный пользователю look-n-feel.
Тесты — очень вредное явление. Главное потыкать мышкой и убедиться что приложение для пользователя удобно и приятно. То что согластно тестам оно работает правильно — для пользователя не значит ровным счетом ничего.
Только что применил hot-patch к статье, заменив <Заместо /> на <Вместо />
Конечно. В проде от hot-loader не остается ничего.

А насчет оборачивая «их кодом» — имхо — это супер минор.
Freactal прекрасен, как и многие другие решения. К сожалению требовалось «починить» именно что redux. И именно способом, максимально близким к идеалогии redux.
По другому идею не продать.
А они не PureComponent, а обычные StatelessFunctional. А значит перерисуются вместе с родителем, который перерисуется при любом изменении в любом из Todo.

Вообще вещать побольше connectов исключительно для контроля над распространением изменений — интересная практика.

Connect — начало любого изменения, потому что дергается непосредственно стором как бы глубоко он не сидел
Connect — конец любого изменения, потому что SCU не пропустит никакие нежданные изменения прилетевшие сверху.

Подробнее можно вот тут почитать -> medium.com/@alexandereardon/performance-optimisations-for-react-applications-round-2-2042e5c9af97
Автор хотел запускать JS код as-is. А as-is он — на 99% состоящий из npm зависимостей. Начиная от реакта и заканчивая leadpadом.
Далее — по тексту.

Информация

В рейтинге
Не участвует
Откуда
Sydney, New South Wales, Австралия
Дата рождения
Зарегистрирован
Активность