Facebook выпустил новую версию своего фреймворка Relay JavaScript. Relay Modern был разработан, чтобы упростить использование, расширить возможности и повысить производительность на мобильных устройствах.
Relay был представлен как фреймворк JavaScript для создания приложений, управляемых данными. Он использует библиотеку Facebook React для создания пользовательских интерфейсов с GraphQL для извлечения составных данных. Facebook создал основу для поддержки двух технологий для обработки таких элементов, как управление сетевыми запросами, обработка ошибок и согласованность данных. Relay представил две концепции: размещенные в одном месте определения данных и представлений и декларативную выборку данных.
Идея совместного размещения данных и представления означает, что вы получаете контейнеры, которые объединяют как логику представления, так и зависимости данных каждого компонента. Это обычные контейнеры React, которые интегрируются с GraphQL, поэтому, например, у вас может быть контейнер, который отображает имя пользователя и фотографию профиля и указывает зависимости его данных.
Декларативная выборка данных означает, что разработчики указывают, какие данные требуются, а не как их загружать, кэшировать и обновлять. Это освобождает их от необходимости иметь дело с сетью напрямую, что снижает сложность приложения.
Relay Modern был разработан в ответ на обнаружение ограничений оригинальной конструкции, особенно при использовании на слабомощном мобильном оборудовании. Разработчики также сказали Facebook, что API был слишком «волшебным», что затрудняло изучение и предсказание.
Изменения привели к созданию Relay Modern, платформы GraphQL с упрощенным API, новыми функциями и меньшей общей структурой. Две новые концепции в обновленной версии — статические запросы и опережающая оптимизация. Обе идеи пришли со стороны GraphQL как способы повышения производительности устройств с низким энергопотреблением при плохих мобильных соединениях.
Одной из накладных расходов при использовании GraphQL была необходимость создавать запросы путем объединения нескольких строк для создания запроса, а затем загрузки этого запроса через медленное соединение. Такие запросы иногда могут вырасти до десятков тысяч строк GraphQL. Другой момент, который заметили разработчики, заключался в том, что все мобильные устройства с одним и тем же приложением отправляли более или менее одинаковые запросы.
Разработчики поняли, что если запросы GraphQL были статичными и известными и не изменялись условиями выполнения, не было необходимости создавать и отправлять их с мобильного телефона. Вместо этого они могут быть созданы один раз во время разработки, сохранены на серверах Facebook и заменены в мобильном приложении небольшим идентификатором. Приложение на мобильном телефоне должно только отправить идентификатор вместе с некоторыми переменными GraphQL, и сервер Facebook знает, какой запрос выполнить.
Похожая техника используется в Relay Modern. Компилятор Relay извлекает размещенные вместе фрагменты GraphQL из приложения, заранее конструирует и сохраняет запросы на сервере. Затем среда выполнения Relay может получать эти запросы и обрабатывать их результаты во время выполнения. Пример контейнера показан ниже:
Еще один способ, которым разработчики улучшили производительность, — это «опережающая оптимизация». Там, где есть статическая структура запроса, компилятор Relay оптимизирует вывод. Можно оптимизировать запрос, сохраненный на сервере, а также артефакты, которые среда выполнения Relay использует для получения этих запросов и обработки их результатов во время выполнения.
Наряду с оптимизацией Relay Modern имеет упрощенный API мутаций. Это позволяет разработчикам указывать «жирные запросы», в которых вы определяете все, что может измениться в ответ на применение мутации. Раньше, когда выполнялась мутация, классический Relay пересекал толстый запрос с фактически выполненными запросами, чтобы определить минимальный набор данных для повторной выборки. Иногда это затрудняло определение того, какая мутация будет генерироваться.
Вместо этого Relay Modern предоставляет явный API мутации: вы точно указываете, какие поля следует извлекать после мутации и как именно кеш должен обновляться после мутации. Это помогает как улучшить производительность, так и сделать систему более предсказуемой.
Учитывая объем изменений, существует API совместимости, который позволяет вам начать использовать новые API-интерфейсы Relay Modern в контексте существующего классического приложения Relay. При использовании API совместимости вы еще не получите преимуществ от статически известных запросов или меньшего ядра, но выиграете от более простого и предсказуемого API.