Быстрее, чем быстрее — интерфейс JavaScript в новой архитектуре RN

React Native

задний план

С появлением Flutter и других новых фреймворков React Native сталкивается с растущими проблемами, и узкие места в производительности Rn становятся очевидными. Чтобы сохранить конкурентоспособность в противостоянии FLUTTER, в архитектуре заварен RN. Так, в выступлении на ReactConf 2018React Native's New ArchitectureRN официально представила нам три новых концепции: JSI, Fabric и TurboModule. Затем в первом квартале 2019 года разработчики RN@kelsetЯ написал статью, объясняющую, почему RN имеет такую ​​структуру из проекта высокого уровня:formidable.com/blog/2019/ Просто…. Давайте посмотрим, как RN решает проблему узких мест в производительности.

существующие проблемы

Старая архитектура RN сильно зависит от Bridge:

RN-bridge

Вся информация, передаваемая между JS и Native, должна быть сериализована в JSON для асинхронной передачи. Это вызывает относительно распространенную проблему с производительностью: когда вы быстро перемещаете ListView, экран становится белым, как показано ниже:

ListView白屏

Теперь есть три потока: Native UI thread, Layout thread и JS thread, связь между ними асинхронная. Когда ListView сдвигается вверх и ему нужно отобразить новую ячейку, Native асинхронно уведомляет поток JS.После того, как поток JS выполнит соответствующую обработку бизнес-логики, он асинхронно передается потоку Layout для расчета фактической области отображения Ячейка, а затем поток макета вычислит вычисление.Хороший результат асинхронно дается собственному потоку для рисования пользовательского интерфейса.Поскольку скольжение происходит очень быстро, пользовательский интерфейс не может быть обновлен вовремя, и он отображается в виде белого экрана.

Чтобы решить эту проблему, давайте посмотрим, как ListView не имеет белого экрана в браузере.

浏览器ListView

В узле, возвращаемом браузером, есть ссылка на объект, фактически сгенерированный C++, поэтому вызов из JS в браузер является синхронным вызовом, и, естественно, проблемы с белым экраном не будет.

Точно так же, если мы удалим этот асинхронный бридж, JS и Native одновременно будут удерживать HostObject, чтобы мы могли совершать синхронные вызовы между JS и Native, а вот замена моста — JavaScript Interface (JSI).

JavaScript Interface (JSI)

JSI — это оптимизированный и универсальный интерфейс JS-движка, который теоретически может взаимодействовать с любым JS-движком, включая Google V8 и Microsoft ChakraCore, или новую версию JavaScriptCore (JSC), которую сейчас использует RN (JSI был интегрирован в версию RN 0.59). , и версия АО была обновлена ​​​​в этой версии).

В то же время JSI является мостом между JS и Native.Реализуя JSI::HostObject на уровне C++, нет необходимости сериализовать его в JSON и передавать в обе стороны.Реализуется прямая связь между Native и JS. .

JSI

ListView скользит под JSI

JSI ListView滑动

Пунктирная линия — асинхронный вызов, реализация — синхронный вызов.

Сначала мы запускаем приложение, затем рендерим асинхронно, а затем асинхронно обновляем представление в потоке пользовательского интерфейса. До появления JSI это был единственный способ обработки нашего взаимодействия с Native и JS.

Теперь в UI-потоке есть callback для сетевого запроса на обновление состояния, а затем есть событие onScroll списка в UI-потоке Очевидно, что это событие onScroll — задача, с которой нам нужно срочно разобраться. С помощью JSI мы можем синхронно обрабатывать эту задачу onScroll, обновлять соответствующий Native View, и проблем с белым экраном не будет. После обработки этой срочной задачи основной поток может продолжить обработку задачи обратного вызова сетевого запроса.

Нативные модули под JSI

JSI также является краеугольным камнем рефакторинга Native Modules (т.е. TurboModules). Например, теперь есть требование делать снимки в РН и загружать снимки на сервер. До появления JSI нам приходилось многократно сериализовать данные между JS и Native, что было неэффективно и не нужно:

Native Modules call old

После того, как JSI, JS и Native одновременно удерживают HostObject, после получения изображения они отбрасывают ненужную передачу данных и продолжают выполнять операцию загрузки напрямую.

Native Modules call new

Reference

React Native's New Architecture

formidable.com/blog/2019/ Просто…