Согласно докладу создателя SolidJS Райана Карниато на JSNation на прошлой неделе, Solid планирует ввести новый примитив в свою реактивную архитектуру.
Есть две причины, почему это важно: во-первых, Карнатио, лидер в области фреймворков, демонстрирует то, что он видит в будущем для всех фреймворков JavaScript с точки зрения расширения их возможностей; и, во-вторых, за Solid иногда следуют другие, как мы видели на примере внедрения Signals в Angular и Preact.
Карниато объяснил сигналы как «подобные электронной таблице», где обычное задание представляет собой момент времени.
«Это означает, что по завершении переменная A отражает текущую сумму, но если B или C изменятся, вам придется выполнить присваивание снова». — сказал он.
«Сигналы — это всего лишь набор примитивов, помогающих представить синхронизацию», — добавил он. Signals существовали уже большую часть десятилетия, когда он открыл Solid.js с открытым исходным кодом еще в 2018 году, но Signals потеряли популярность из-за модели компонентов React, сказал он.
«Трудно игнорировать это влияние, когда почти каждая платформа, кроме React, на данный момент первоклассно внедрила Signals. Так здорово, правда? Конец истории», — сказал он. «Нет, я думаю так: мы находимся только в начале гораздо больших перемен, и я не одинок в этом мнении».
Он также говорит не об искусственном интеллекте, а, скорее, о проблеме низкоуровневой архитектуры, позволяющей получить максимальную отдачу от ваших приложений.
«Просто иметь сигналы недостаточно. Сигналы — это механизм изменений, но то, как вы их используете, имеет решающее значение», — сказал он.
По его словам, общей чертой, которая делает Signals мощными, является знание графа данных, на котором работает ваше приложение. Это позволяет разработчикам делать «невероятные вещи, которые в противном случае нам было бы нелегко сделать», добавил он.
В своем выступлении он рассмотрел возможности Signals, представив примеры кода, ссылающиеся на будущие функции Solid, которые, возможно, даже не были доступны в настоящее время. Это включало новое примитивное предложение по структуре.
Сигналы не означают более высокую производительность
Карниато начал с рассмотрения производительности, потому что об этом легче всего говорить и «возможно, наименее важно», сказал он.
«Все начинается с развенчания распространенного заблуждения: я использую Signals, поэтому моя платформа приложений должна работать быстрее», — сказал он. «К сожалению, это работает не так, как выяснил Джо Савона из команды React — если вы смотрели его выступление на React Conf 2025, где он показал, что добавление любого управления состоянием на самом деле снижает потолок производительности вашего фреймворка».
Карниато добавил, что, хотя компилятор React может позволить разработчикам писать более оптимальный код, он не оказывает существенного влияния на абсолютную производительность.
По его словам, добавление MobX, Zustand или Signals в React или даже Signals в Preact не гарантирует улучшения производительности во всех случаях. Фактически, в среднем это делает их медленнее. Это связано с тем, что платформы построены на основе виртуального DOM (VDOM), и каждый раз при обновлении состояния платформа должна повторно запускать функции компонентов и сравнивать дерево VDOM, которое сравнивает старое виртуальное дерево с новым виртуальным деревом для поиска изменений.
По его словам, ответ на сигналы и лучшую производительность можно найти в мелкозернистом рендеринге. С этой целью SolidJS исключает VDOM и использует реактивный граф только для обновления точных, детализированных узлов DOM, которые зависят от измененных данных. Solid, а также Svelte и Vue присоединились к Solid, создав дерево мелкозернистого рендеринга.
«Представьте себе какое-нибудь приложение, в котором вам нужно поднять состояние так, чтобы оно было доступно в нескольких точках, например, в корзине покупок в заголовке и, возможно, в кнопке «Купить» глубоко на вашей странице», — сказал он. «Вы обновляете состояние, запускаете повторный рендеринг по дереву, действительно нужно обновить только корзину покупок, но всю эту дополнительную работу делаем мы».
«Это начинается с развенчания распространенного заблуждения: я использую Signals, поэтому моя платформа приложений должна быть быстрее».
– Райан Карниато, создатель SolidJS
Обычно разработчикам советуют использовать мемоизацию, которая кэширует результат вызова функции и возвращает кэшированный результат, когда те же входные данные повторяются, вместо пересчета результата.
SolidJS, Vue и Svelte используют реактивные примитивы, такие как сигналы, которые по своей сути мемоизированы. Но мемоизация создает компромисс между скоростью и памятью.
«Вы можете понять, что данные, которые вы отправляете на кнопку покупки, не меняются, а запускаются только по одному пути. Обычно это то, что делает компилятор React. Это то, что сделал Svelte 3», — сказал он. «Если корзина изменилась, этого не избежать: повторно запустить все компоненты, от владельца состояния до этого изменения. Мы можем удалить ветки, которые не изменились в процессе, но изменение должно достичь своего места в пользовательском интерфейсе».
По его словам, точка, в которой вы используете сигналы, попадает в дерево и становится новым маршрутом.
«Однако при мелкозернистом рендеринге все реквизиты работают именно так», — сказал он. «По умолчанию вы можете объявить эти данные в верхней части вашего приложения, передать их через 10 компонентов и получить одинаковые результаты. Не нужно перезапускать весь компонент или какой-либо из его родительских элементов, меняются только части».
По его словам, это приводит к тому, что вся категория «будет ли мой компонент повторен» исчезнет, и композиция исполнения перестанет быть проблемой, сказал он.
По его словам, Svelte и Vue присоединились к Solid в разработке мелкозернистого рендеринга.
Новый примитив для твердого тела
Магазины — это прокси, где каждый объект недвижимости потенциально может стать отдельным сигналом. Работа с хранилищами привела к тому, что Карниато осознал, что существуют проблемы, требующие обработки детализированных данных, и места, где вы начинаете с одного источника, но хотите разделить или разделить реактивность.
«Проверять каждую строку при изменении выбранного класса в таблице — бесполезная трата, но не всегда практично включать «выбрано» в каждую строку, особенно когда эти данные совместно используются в нескольких местах», — сказал он. «Иногда нам просто нужно проецировать реактивные данные на другие данные, не изменяя источник. Иногда нам нужно иметь возможность создавать эфемерные расширения этих данных, такие как слияние и оптимистические изменения, не фиксируя их».
Он объяснил две передовые концепции модели реактивности SolidJS, обе из которых направлены на устранение необходимости в сложных побочных эффектах (таких как useEffect в React) для управления синхронизацией состояний.
Первое — это Прогнозыкоторый станет новым примитивом для Solid. Это все еще в работе. Прогнозы объясняют и разделяют реактивность на несколько разных источников, объяснил Карниато. Они подобны специализированному фильтру или линзе, которую вы накладываете на основные данные. Они являются гранулярными, производными и неизменяемыми. Они также позволяют разработчикам создавать эфемерные изменения, такие как обновление Optimistic UI (показывая пользователям изменения непосредственно перед тем, как сервер их фактически подтвердит), не меняя при этом основные данные приложения, пояснил он.
«Хотя вы, возможно, не используете их очень часто, они представляют собой пространство, для которого у нас никогда раньше не было хорошего решения перед фреймворками — примитив, который является одновременно детальным и производным», — сказал он.
Второй Асинхронные сигналыкоторые уже являются частью SolidJ, реализованных с помощью createResource. Асинхронные сигналы — это решение для интеграции медленных данных непосредственно в быстрый синхронный поток пользовательского интерфейса на основе операций чтения.
«Хотя вы, возможно, не используете их очень часто, они представляют собой пространство, для которого у нас никогда раньше не было хорошего решения перед фреймворками — примитив, который является одновременно детальным и производным».
– Мясистый
Традиционные модели ориентированы на запись, то есть вам придется вручную сообщать платформе об обновлении после поступления медленных данных, что часто приводит к сложной логике внутри методов useEffect или жизненного цикла. Но подход Solid ориентирован на чтение, поэтому ему следует приостанавливать работу только тогда, когда у него нет данных для рендеринга (проблема «чтения»).
«Что может быть вам интересно, так это то, что мы детально проработаны и можем направить реактивность туда, где находится чтение», — сказал он. «По сути, в этой модели дети автоматически становятся братьями и сестрами».
Затем он продемонстрировал, насколько быстро загружается подход с детальной реактивностью: загрузка всей страницы заняла две секунды, потому что все они работают параллельно, отметил он.
Он также обсудил, как это можно использовать для создания «самовосстанавливающейся реактивности», при которой реактивный граф знает все зависимости, позволяя платформе автоматически отслеживать ошибки обратно в асинхронный источник и повторять выборку при нажатии кнопки «Сброс» — без повторного запуска функций компонента.
Хотя детальная реактивность гарантирует скорость, приложение по-прежнему сталкивается с проблемой согласованности, известной как разрыв, при работе с несрочными асинхронными обновлениями. Карниато отметил, что SolidJS фактически разрывается по умолчанию после начальной загрузки — например, номер счетчика может обновиться мгновенно, но сопровождающая медленно извлекаемая фраза кратко показывает старые данные.
Чтобы решить эту проблему, SolidJS использует Переходычто позволяет разработчику пометить обновление как несрочное. Этот примитив необходим для обеспечения плавного одновременного рендеринга асинхронных данных. Переходы также «могут связать воедино мутацию и асинхронную выборку, чтобы устранить странные состояния гонки вокруг ваших данных и ожидающих состояний», — пояснил Карниато. Переходы можно использовать, чтобы приложение не страдало от визуальных «разрывов» при медленных изменениях данных.
Он отметил, что Solid обладает этими функциями примерно с 2020 года, что дает ему опыт работы с примитивами. Переходы — это ключевой механизм для создания полнофункционального оптимистичного пользовательского интерфейса.
Но лучшее еще впереди, поскольку фреймворки опираются на мелкозернистую реактивность.
«Я думаю, что мы находимся на пороге следующего большого события», — сказал Карниато аудитории.
ТЕНДЕНЦИОННЫЕ ИСТОРИИ YOUTUBE.COM/THENEWSTACK Технологии развиваются быстро, не пропустите ни одной серии. Подпишитесь на наш канал YouTube, чтобы смотреть все наши подкасты, интервью, демонстрации и многое другое. ПОДПИСАТЬСЯ Группа, созданная в Sketch. Лорейн Лоусон — опытный репортер в области технологий, которая в течение 25 лет освещала технологические вопросы, от интеграции данных до безопасности. До прихода в The New Stack она работала редактором сайта банковских технологий Bank Automation News. У нее есть… Подробнее от Лорейн Лоусон.