Як React Native створює макети додатків (і як Fabric збирається їх змінити)

Команда React Native працювала над тим, що принципово змінить спосіб взаємодії внутрішніх компонентів React Native з операційною системою-хостом. Він має приємну кодову назву “проектна тканина” (поки не буде випущена офіційна назва).

Давайте обговоримо, що це насправді і які зміни він вносить у вас як розробника.

Як працює React Native зараз

Якщо поглянути, React Native зараз використовує 3 потоки:

  1. Інтерфейс користувача - це основний потік програми, на якому працює ваш додаток Android / iOS. Він має доступ до інтерфейсу, і ваш інтерфейс може змінити лише цей потік.
  2. Тіньова нитка - цей потік є фоновим потоком, що використовується React Native для обчислення вашого макета, створеного за допомогою бібліотеки React.
  3. Потік JavaScript - Цей потік - це місце, де живе і виконується ваш код JavaScript (по суті ваш код React).

Внутрішня робота…

Почнемо з початку. Припустимо, ви хочете намалювати червону рамку в центрі екрана. Отже, трапляється так, що ваш потік JS містить код для створення макета, тобто це червоне поле на екрані. Ось типовий фрагмент коду, який може досягти цього для React Native (RN):

Операційна система хоста має власну реалізацію макета і не відповідає типу коду flexbox, який ви щойно написали. Отже, RN перш за все повинен перетворити ваш кодований макет flexbox у систему компонування, яку може зрозуміти ваша операційна система хоста.

Зачекай! Перш ніж це зробити, нам потрібно вивантажити цю частину розрахунку макета в інший потік, щоб ми могли продовжувати виконувати наш потік JavaScript. Отже, RN використовує Shadow Thread, який по суті створює дерево вашого макета, який ви закодували у своєму потоці JS. У цьому потоці RN використовує механізм компонування під назвою Yoga, який перетворює макет на основі flexbox в систему компонування, яку може зрозуміти ваш рідний хост.

React Native використовує щось, що називається React Native bridge, для передачі цієї інформації з потоку JS до потоку Shadow. У двох словах, це просто серіалізує дані у форматі JSON і передає їх у вигляді рядка через міст.

На даний момент ми потрапили в нитку Тіні. Потік JS виконується, і на екрані нічого не намальовано.

Тепер, як тільки ми отримали розмітку від йоги, ця інформація знову передається в потік інтерфейсу через міст React Native. Знову ж таки, це робить деяку серіалізацію на потоці Shadow та десеріалізацію на основному потоці. Тут основний потік надає інтерфейс.

Проблеми з таким підходом

Якщо ви бачите, вся комунікація між потоками відбувається через міст, який працює, але повний обмежень. До них належать:

  • повільно передавати великі шматки даних (скажімо, файл зображення, перетворений у рядок base64), і
  • немає необхідності копіювати дані, якщо одне і те ж завдання можна реалізувати, просто вказуючи на дані в пам'яті (знову скажімо зображення)

Далі, все спілкування відбувається асинхронно, що в більшості випадків добре. Однак наразі неможливо синхронізувати оновлення потоку інтерфейсу користувача з потоку JS. Це створює проблему, коли ви використовуєте, скажімо, FlatList з величезним списком даних. (Ви можете розглядати FlatList як слабшу реалізацію RecyclerView.)

Нарешті, через цей асинхронний характер зв'язку між потоком JS та потоком інтерфейсу користувача, рідні модулі, які суворо вимагають синхронного доступу до даних, не можуть бути використані в повній мірі. Наприклад, адаптер RecyclerView на андроїд вимагає синхронного доступу до даних, які він відображає за відсутність мерехтіння на екрані. Зараз це неможливо через багатопотокову архітектуру, встановлену React Native.

Представляємо тканину

Зробіть крок назад і подумайте про свій браузер. Якщо поглянути глибше, поля введення, кнопки тощо насправді стосуються операційної системи. Тому ваш браузер просить вашу ОС (Windows, Mac, Linux або майже будь-що інше) намалювати, наприклад, поле введення десь на веб-сторінці. Святий молі! Подивіться прекрасне відображення від браузерів до React Native.

  • Інтерфейс користувача → Інтерфейс користувача
  • Механізм візуалізації браузера → React Native rendering engine (Yoga / Shadow thread)
  • Потік JavaScript → Потік JavaScript

Ми знаємо, що сучасні браузери дуже дорослі та ефективно виконують усі ці завдання. То чому б не реагувати нативним? Який зниклий фрагмент головоломки жорстоко обмежує React Native, але не браузери?

Виставлення власних викликів API безпосередньо до JavaScript

Ви коли-небудь щойно писали команди like document.getElementByIdі команди like setTimeoutі setIntervalу своїй консолі і бачили результат? О! Їх реалізація насправді [native code]! Що це означає?

Бачите, коли ви виконуєте ці функції, вони не викликають жодного коду JavaScript. Натомість ці функції пов’язані безпосередньо із власним кодом C ++, який викликається. Отже, браузер не дозволяє JS взаємодіяти з операційною системою хоста, використовуючи мости, а натомість безпосередньо піддає JS ОС за допомогою власного коду! У двох словах, це те, що зробить React Native Fabric: усуне міст і дозволить користувацькому інтерфейсу керувати безпосередньо з потоку JS за допомогою власного коду.

Винос

  1. RN Fabric дозволяє потоку інтерфейсу користувача (там, де малюється інтерфейс користувача) синхронізуватися з потоком JS (де програмується інтерфейс користувача)
  2. Тканина все ще знаходиться в стадії розробки, і команда React Native досі не вказала дату публічного випуску. Але я впевнений, що цього року ми побачимо щось чудове.
  3. Такі фреймворки для розробки додатків, як ці (RN, NativeScript, Flutter), покращуються з кожним днем!

Джерела зображень: //www.slideshare.net/axemclion/react-native-fabric-review20180725

TL; DR

Сподобалась ця стаття?

Якщо вам сподобалась ця стаття, сміливо дайте мені кілька хлопань і зв’яжіться зі мною у Twitter. Ви знаєте найкращу частину? Хлопання та твітер обидва безкоштовні! Якщо у вас є якісь запитання, сміливо їх залишайте в коментарях!

Швидкий безсоромний штекер: якщо ви починаєте роботу з React Native, ось мій 95% від курсу, як розпочати з ним: React Native - перші кроки