Механизм liveQuery в Dexie построен вокруг идеи
повторного выполнения запроса при изменениях данных, затрагивающих
результат выборки. В отличие от потоков событий уровня DOM или серверных
push-уведомлений, реактивность здесь основана на повторной оценке
функции запроса при срабатывании внутренних хуков Dexie.
Ключевая особенность: каждое изменение данных приводит не к “патчу” результата, а к полному повторному выполнению запроса. Это фундаментально определяет все ограничения и поведение производительности.
Пересчёт liveQuery происходит после завершения
транзакции записи. Это означает:
commit;Важный эффект: если логика приложения рассчитывает на пошаговую реактивность внутри сложной транзакции, этого не происходит — реактивность агрегируется на уровне завершённой транзакции.
Дополнительно стоит учитывать, что асинхронные цепочки транзакций
могут создавать каскадные пересчёты, особенно при последовательных
bulkPut, update и delete.
liveQuery реагирует только на изменения, проходящие
через Dexie API в текущем контексте выполнения:
table.add, put,
delete, bulkPut и т.д. отслеживаются;Последний пункт особенно критичен: в типичной конфигурации Dexie
не является распределённой реактивной системой между
вкладками без дополнительного слоя синхронизации (например,
через BroadcastChannel или аналогичные механизмы).
Это приводит к ситуации, когда данные фактически изменены, но
liveQuery в другой вкладке продолжает работать со старым
состоянием.
Каждый триггер liveQuery запускает:
Это означает, что сложные запросы становятся узким местом:
filter на больших коллекциях выполняется в памяти;toArray() на крупных выборках может блокировать
поток;map/filter/reduce не кэшируются между
обновлениями.При частых изменениях данных возникает эффект реактивного штормового пересчёта, когда одно изменение вызывает каскад повторных вычислений.
liveQuery предполагает, что функция запроса является
чистой и детерминированной относительно состояния базы. Однако на
практике часто встречаются нарушения этого условия:
Date.now() внутри запроса;Это приводит к тому, что одинаковые изменения данных могут давать разные результаты, а подписка становится логически нестабильной.
Особенно проблемны конструкции, где результат зависит от не-IndexedDB источников данных: они не триггерят пересчёт автоматически.
liveQueryХотя liveQuery поддерживает async функцию,
его модель остаётся синхронной по логике пересчёта:
Promise выполнения
запроса;Это создаёт эффект гонки:
Запрос внутри liveQuery должен рассматриваться как
функция отображения состояния базы в результат. Любые побочные эффекты
приводят к нестабильности:
liveQuery;Так как пересчёт происходит многократно, побочные эффекты могут выполняться десятки или сотни раз, создавая лавинообразное поведение.
Ошибки внутри liveQuery не ведут к краху всей системы,
но имеют специфическое поведение:
Это приводит к “тихим” сбоям, когда поток данных перестаёт обновляться или обновляется только частично.
Особую проблему создают:
Каждый вызов liveQuery(...).subscribe(...) создаёт
активную подписку. При отсутствии явного завершения:
В долгоживущих приложениях это приводит к накоплению подписок, особенно при:
unsubscribe.Эффект проявляется как постепенное снижение производительности без явных ошибок.
Каждая подписка liveQuery выполняет запрос независимо.
Это означает:
При архитектуре с множеством компонентов это может приводить к N-кратному выполнению одного и того же тяжёлого запроса.
Хотя Dexie эффективно использует индексы, liveQuery не
делает запрос “реактивным на уровне индекса”. Это означает:
Особая проблема возникает при фильтрации через
.filter(), так как она выполняется после загрузки данных и
полностью повторяется при каждом триггере.
Комбинации orderBy, limit,
offset внутри liveQuery создают скрытые
сложности:
offset становится ненадёжным при реактивных
обновлениях.Типичный эффект — “прыгающие страницы”, когда элементы смещаются между обновлениями.
В многовкладочной среде liveQuery не гарантирует
мгновенную консистентность:
Это приводит к эффекту временных расхождений, когда разные вкладки показывают разные версии одной базы.
При обновлении схемы базы данных:
Особенно критично это при частичных обновлениях приложения, когда часть вкладок уже обновлена, а часть ещё использует старую версию схемы.
Снижение проблем liveQuery обычно сводится к
архитектурным ограничениям:
liveQuery;Такая модель позволяет уменьшить частоту пересчётов и стабилизировать поведение реактивного слоя без изменения внутренней механики Dexie.