Skip to content

Latest commit

 

History

History
34 lines (27 loc) · 3.69 KB

proposals.md

File metadata and controls

34 lines (27 loc) · 3.69 KB

Кстати, я вчера вечером понял главную проблему перф теста. Плохая новость: на текущем ядре это невозможно обойти. Хорошая новость: эту же проблему невозможно обойти на редаксе и (без дичайших костылей) на эффекторе. Хорошая новость: вчера же я придумал что можно поправить в ядре, что бы этот кейс высчитывался в несколько раз быстрее остальных. Кстати, мобыкс этой проблемой не обладает.

А проблема заключается в том что любой комьютед от атома / стора - это подписка на него - иначе ну никак. Т.е. если у нас есть атом списка с тысячью элементами и мы делаем от него тысячу других атомов, то при обновлении одного элемента всей тысячи зависимых атомов нужно проверить - их ли элемент изменился. Это фундаментальная правда для атомов / селекторов / сторов - не важно - это просто реальность.

ЗАМЕТКА: entry point / точка входа - это точка начала вычислений и реакций стейт менеджера. Интересно то что она всегда одна (!) (тк у нас однопоточное исполнение) и ее можно строго предрасчитать (в нормальных стм): экшен, событие, вызов метода и тп. Т.к. точка входа всегда одна - мы можем попытаться предрасчитать все зависимости для нее.

Но! Что если мы скажем что у нас есть entry point который меняет список элементов, но точно НЕ меняет все элементы, кроме перечисленных в аргументах вызова энтрипоинта?)) Тогда мы сможем заблоговременно построить обход зависимостей так, что зависимости от списка элементов, которых нет в аргументах энтрипоинта не нужно даже учитывать… Ну грубо говоря как-то так, может я плохо объясняю… В общем реализация такой логики будет стоить около 300 гзип байтов 😂 но кмк оно того стоит. И в теории это не очень сложно. Выглядеть будет примерно так:

declareAtom([], (r, lense) => [
  r(someAtomOrAtctionWhatEver, regularReducer)
  lense(
    someAction,
    (listElement, actionPayload) => newElementValue,
    { get: Function, set: Function }
  )
])

Где get и set - это функции получения и записи элемента по ключу (классические линзы). Ключ перется из экшена, а попадает туда через второй аргумент вызова экшена: someAction(value, elementKey) Для массива геттер и сеттер могут, например, выглядить так:

get: (list, key) => list[key]
set: (list, key, value) => ((list = list.slice()), (list[key] = value), list)