Как работят анимациите в React Native

React Native е чудесна рамка, която ви позволява да създавате мобилни приложения с различни платформи. Особено полезно е, ако сте уеб разработчик и искате бързо и евтино решение за разработване на собствени мобилни приложения, които работят както на Android, така и на iOS. Бонус: не е нужно да харчите $$$ за отделни екипи за iOS, Android и уеб.

Това не само намалява разходите ви, но също така ви позволява да споделяте част от кодовата си база между всичките три (Android, iOS и Web) компилации, което улеснява извършването на промени и пускането на актуализации.

React Native също ви позволява да работите доста близо до действителната ОС, което е важно за критични за изпълнение задачи като анимации.

Анимациите са неразделна част от всяко приложение, защото го правят интерактивно и по-привлекателно за крайния потребител. Но много пъти, докато работите с анимации, може да ви се струва, че работите с черна кутия.

Така че нека научим как работят анимациите в React Native. Можете да започнете да изучавате анимации в React Native от нулата от този безплатен плейлист в YouTube.

Анимираният API

React Native излага API, наречен Анимиран. Състои се от много прекрасни неща като анимационни стойности, пролетни / синхронизиращи анимации и събития. Но ние не сме тук, за да обсъждаме API - ще оставя това на официалните документи и на моя плейлист в YouTube. Те вършат много по-добра работа, покривайки това за вас.

Това, което искаме да обсъдим тук, всъщност е как React Native анимира нещата на екрана и какво се случва под капака.

Два начина за анимиране

Трябва да знаете как React Native работи под капака от другата ми статия. (Прочетете го набързо, ако още не сте го направили.) Тъй като React Native използва React и JavaScript, има точно 2 начина за извършване на анимации на екрана.

Първо, нека изясним един факт. React Native конструира действителни естествени изгледи на екрана, а не онези, представени чрез вградени уеб браузъри като Ionic. Поради това, ако искате да анимирате изглед по някакъв начин, това в крайна сметка трябва да се направи в родния изглед.

JavaScript трябва да комуникира с операционната система по някакъв начин, че изгледът трябва да се актуализира. JavaScript работи в нишка, различна от нишката на потребителския интерфейс (основната нишка), и само тази нишка на потребителския интерфейс може да актуализира изгледите. Така че JS трябва да използва моста, който React Native предоставя, за да сериализира и предаде тези данни на операционната система.

Работете в JS и актуализирайте родния изглед

Този подход означава, че правите изглед, който вече се вижда на екрана на потребителя, и работите върху това, което трябва да се направи за следващата му позиция в нишката на JavaScript. Стъпките изглеждат приблизително така:

  1. Анимацията започва
  2. JavaScript изпълнява requestAnimationFrameфункцията - функция, която се опитва да работи с 60 повиквания в секунда (60 FPS)
  3. JavaScript изчислява следващата позиция / непрозрачност / трансформация / каквото и да анимирате в изгледа.
  4. JavaScript сериализира тази стойност и я изпраща по моста.
  5. В другия край на моста Java (Android) или Objective C (iOS) десериализира тази стойност и прилага дадените трансформации в споменатия изглед.
  6. Рамката се актуализира на екрана.

Видя ли какво се случи там? Нито една от стъпките всъщност не изобразява компонент React Native. Това означава, че анимираният API всъщност "заобикаля" философията на React за немутиране на променливи "състояние".

Добрата новина: това всъщност е полезно в случай на анимации, защото ще бъде твърде бавно и лошо за производителността, ако оставим React да изобрази компонент 60 пъти в секунда!

Всичко това е хубаво и добро, но тук има много основен проблем. JavaScript е с една нишка. Така че асинхронната природа на JavaScript не работи тук, защото анимациите са задача, свързана с процесора. Нека да разгледаме плюсовете и минусите на този подход.

Професионалисти

  1. Можете да имате много сложни анимации, написани в JS и видими като естествени анимации.
  2. Повече контрол върху състоянието на анимацията

Минуси

  1. Голяма санкция за производителност, ако вашата нишка на JavaScript е супер заета.
  2. Ако мостът е зает, има намалена производителност, когато OS / JS искат да комуникират помежду си.

Честната мошеница е голяма измама. Има видеоклип по-долу в статията, който всъщност ви показва този проблем в реално време. Ще видите как JS прецаква голямо време с анимации, когато нишката на JavaScript стане заета.

Защо анимациите на JS изостават?

Анимациите, направени в JS, ще започнат да изостават, когато анимацията продължава и потребителят (или приложението) иска някакво друго действие, което трябва да се обработва от JS нишката.

Например, представете си, че се случва анимация. Това означава, че JS е зает с изпълнението на requestAnimationFrameфункцията. Ако приемем, че самите актуализации не са твърде тежки, да предположим, че потребителят започва да докосва бутон на екрана, който увеличава брояч.

Сега, когато requestAnimationFrameсе извиква често, вашето виртуално дърво React също се рендерира отново и отново, за да отчете увеличения брояч.

И двамата са задачи, свързани с процесора, изпълняващи се в една нишка, така че ще има хит в производителността. requestAnimationFrameще започне да пуска рамки поради допълнителна работа, извършена от JS нишката.

Всичко това означава, че ще получите много дръзка анимация.

Анимации на родния драйвер

Не се притеснявайте, защото React Native всъщност ви позволява да стартирате анимации и на родния драйвер! Какво искам да кажа с това, може да попитате?

Е, просто казано, това означава, че React Native разтоварва анимационната работа от JS нишката към UI нишката (ОС) и й позволява да се справя с анимацията на обекта. Това има няколко предимства:

  1. JS нишката (и React Native bridge) вече е безплатна за обработка на други интензивни задачи, като повтарящи се кранове от потребителя.
  2. Анимациите са много по-гладки, тъй като няма сериализация / десериализация и мостова комуникация.

Как React Native постига това? Хората в React Native ви позволяват като разработчик да предоставяте свойство, наречено useNativeDriverбулева стойност, когато изграждате анимационен обект.

Когато е зададено на true, React Native, преди да започне анимацията, сериализира цялото състояние на анимацията и какво трябва да се направи в бъдеще. След това го прехвърля веднъж през моста към операционната система.

От този момент нататък кодът Java (Android) или Objective C (iOS) изпълнява анимациите вместо JavaScript, като изчислява следващия анимационен кадър и изпраща тези данни отново и отново по моста.

Това много ускорява анимациите и анимациите работят по-гладко, особено на устройства от нисък клас. Нека да видим видео демонстрация на Native Animations срещу JS-базирани анимации в React Native:

В този случай стъпките изглеждат приблизително така:

  1. Анимацията започва
  2. JS сериализира информацията за анимацията и я изпраща по моста.
  3. В другия край, OS получава тази информация и стартира анимацията естествено.

Това е! Анимациите са много по-леки за JS нишката сега. Вече не requestAnimationFrameтича безкрайно.

Този метод обаче има собствен дял за и против.

Професионалисти:

  1. По-бързи анимации
  2. Неблокираща JS нишка
  3. По-малко подут мост

Минуси:

  1. По-малко контрол върху анимациите (JS не може да вижда какво се случва на екрана, след като стартира "автоматичната" анимация)
  2. По-малко свойства за манипулиране - родният драйвер не поддържа всички свойства, които трябва да бъдат анимирани. Например,   widthили heightне са родно анимирани, но opacityи transformса.

В много случаи ще откриете, че можете да заобиколите различен набор от анимации, като използвате, за useNativeDriver: trueда създадете подобен ефект, който не може да бъде постигнат без настройка useNativeDriver: false.

Екипът на React Native работи по добавяне на поддръжка за повече имоти, докато говорим, но засега вярвам, че в момента работи добре.

Заключение

Тази статия ви показа как React Native анимациите всъщност работят под капака и защо са красиви.

Какво мислите за тази статия? Кажете ми, като се свържете с мен в профилите ми в Instagram и Twitter! Ново за React Native? Започнете да го изучавате на codedamn - платформа, която разработчиците могат да учат и да се свързват!

Мир!