Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
React Native pozwala tworzyć aplikacje na Androida i iOS w JavaScript przy użyciu deklaratywnego modelu programowania Reacta i Relay. To prowadzi do bardziej zwięzłego, łatwiejszego w zrozumieniu kodu; szybkiej iteracji bez cyklu kompilacji; oraz łatwego współdzielenia kodu na wielu platformach. Możesz wydawać aplikacje szybciej i skupić się na istotnych szczegółach, dzięki czemu twoja aplikacja wygląda i działa fantastycznie. Optymalizacja wydajności jest tego ważną częścią. Oto historia o tym, jak sprawiliśmy, że uruchamianie aplikacji React Native stało się dwukrotnie szybsze.
Gdy aplikacja działa szybciej, treści ładują się błyskawicznie, co oznacza, że użytkownicy mają więcej czasu na interakcję, a płynne animacje sprawiają, że korzystanie jest przyjemnością. Na rynkach wschodzących, gdzie dominują telefony klasy 2011 na sieciach 2G, skupienie na wydajności może zdecydować, czy aplikacja jest użyteczna, czy nie.
Od premiery React Native na iOS i Androida, stale poprawiamy wydajność przewijania list, efektywność pamięciową, responsywność interfejsu oraz czas uruchamiania aplikacji. Start aplikacji tworzy pierwsze wrażenie i testuje wszystkie elementy frameworka, dlatego jest najbardziej satysfakcjonującym i wymagającym wyzwaniem.
To jest fragment. Przeczytaj resztę posta na Facebook Code.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
Celem React Native jest zapewnienie najlepszego możliwego doświadczenia deweloperskiego. Kluczowym elementem jest czas między zapisaniem pliku a możliwością zobaczenia zmian. Naszym celem jest skrócenie tej pętli sprzężenia zwrotnego do poniżej 1 sekundy, nawet w miarę rozrastania się aplikacji.
Zbliżyliśmy się do tego ideału dzięki trzem głównym funkcjom:
Wykorzystanie JavaScriptu jako języka, który nie wymaga długiego czasu kompilacji.
Wdrożenie narzędzia zwanego Packager, które przekształca pliki es6/flow/jsx w zwykły JavaScript zrozumiały dla maszyny wirtualnej. Zaprojektowano je jako serwer przechowujący stan pośredni w pamięci, co umożliwia szybkie zmiany przyrostowe i wykorzystuje wiele rdzeni.
Stworzenie funkcji Live Reload, która przeładowuje aplikację przy zapisie.
W tym momencie wąskim gardłem nie jest już czas przeładowania aplikacji, ale utrata jej stanu. Typowym scenariuszem jest praca nad funkcją znajdującą się kilka ekranów dalej od ekranu startowego. Przy każdym przeładowaniu musisz klikać tę samą ścieżkę wielokrotnie, by wrócić do swojej funkcji, co wydłuża cykl do kilku sekund.
Idea Hot Reloading polega na utrzymywaniu działania aplikacji i wstrzykiwaniu nowych wersji edytowanych plików podczas działania programu. Dzięki temu nie tracisz stanu aplikacji, co jest szczególnie przydatne przy dopracowywania interfejsu.
Jeden film wart jest tysiąca słów. Zobacz różnicę między Live Reload (obecne) a Hot Reload (nowe).
Jeśli przyjrzysz się uważnie, zauważysz że możliwe jest odzyskanie się po czerwonym boksie błędów oraz importowanie modułów, które wcześniej nie istniały, bez konieczności pełnego przeładowania.
Ostrzeżenie: ponieważ JavaScript jest językiem silnie stanowym, Hot Reloading nie może być zaimplementowany idealnie. W praktyce obecne rozwiązanie sprawdza się dobrze w większości typowych przypadków, a pełne przeładowanie zawsze jest dostępne na wypadek problemów.
Hot Reloading dostępny jest od wersji 0.22. Możesz go włączyć:
Skoro wiemy już po co to i jak używać, czas na najciekawszą część: jak to właściwie działa.
Hot Reloading bazuje na funkcji Hot Module Replacement (HMR). Została ona wprowadzona przez webpack, a my zaimplementowaliśmy ją w React Native Packager. HMR sprawia, że Packager obserwuje zmiany plików i wysyła aktualizacje HMR do lekkiego środowiska uruchomieniowego HMR w aplikacji.
W skrócie, aktualizacja HMR zawiera nowy kod zmienionych modułów JS. Gdy środowisko uruchomieniowe je otrzyma, zastępuje stary kod modułów nowym:
Aktualizacja HMR zawiera nieco więcej niż tylko kod modułu, który chcemy zmienić, ponieważ samo zastąpienie kodu nie wystarczy, by środowisko uruchomieniowe uwzględniło zmiany. Problem w tym, że system modułów mógł już zapisać w pamięci podręcznej eksporty modułu, który aktualizujemy. Przykładowo, rozważ aplikację z dwóch modułów:
Moduł log wypisuje podaną wiadomość wraz z aktualną datą dostarczoną przez moduł time.
Gdy aplikacja jest bundle'owana, React Native rejestruje każdy moduł w systemie modułów za pomocą funkcji __d. Dla tej aplikacji, pośród wielu definicji __d, będzie jedna dla log:
__d('log',function(){ ...// module's code });
To wywołanie opakowuje kod każdego modułu w anonimową funkcję, którą powszechnie nazywamy funkcją fabryczną. System modułowy śledzi funkcję fabryczną każdego modułu, czy została już wykonana oraz wynik tego wykonania (eksporty). Gdy moduł jest wymagany, system modułowy albo dostarcza buforowane eksporty, albo wykonuje funkcję fabryczną modułu po raz pierwszy i zapisuje wynik.
Załóżmy, że uruchamiasz aplikację i wymagasz modułu log. W tym momencie żadna funkcja fabryczna log ani time nie została jeszcze wykonana, więc żadne eksporty nie są buforowane. Następnie użytkownik modyfikuje time, aby zwracał datę w formacie MM/DD:
// time.js functionbar(){ const date =newDate(); return`${date.getMonth()+1}/${date.getDate()}`; } module.exports= bar;
Packager wyśle nowy kod time do środowiska wykonawczego (krok 1). Gdy log zostanie ostatecznie wymagany, wyeksportowana funkcja zostanie wykonana z uwzględnieniem zmian w time (krok 2):
Teraz załóżmy, że kod log wymaga time jako zależności najwyższego poziomu:
const time =require('./time');// top level require // log.js functionlog(message){ console.log(`[${time()}] ${message}`); } module.exports= log;
Gdy log jest wymagany, środowisko wykonawcze zbuforuje jego eksporty oraz eksporty time (krok 1). Jeśli time zostanie zmodyfikowany, proces HMR nie może zakończyć się po prostu zastąpieniem kodu time. Gdyby tak zrobił, wykonanie log korzystałoby z buforowanej kopii time (starego kodu).
Aby log uwzględnił zmiany w time, musimy wyczyścić jego buforowane eksporty, ponieważ jeden z modułów od których zależy został "gorąco zamieniony" (krok 3). Gdy log zostanie ponownie wymagany, jego funkcja fabryczna zostanie wykonana, wymagając time i pobierając jego nowy kod.
HMR w React Native rozszerza system modułów poprzez wprowadzenie obiektu hot. To API opiera się na webpackowym rozwiązaniu. Obiekt hot udostępnia funkcję accept pozwalającą zdefiniować callback wykonywany przy wymianie modułu. Np. jeśli zmienimy kod time jak poniżej, po każdej modyfikacji zobaczymy "time changed" w konsoli:
Uwaga: tylko w rzadkich przypadkach będziesz musiał ręcznie używać tego API. Gorące przeładowanie powinno działać "out of the box" w większości typowych scenariuszy.
Jak widzieliśmy, czasem samo zaakceptowanie aktualizacji HMR nie wystarczy, ponieważ moduł używający zamienianego komponentu mógł zostać już wykonany z buforowanymi importami. Np. załóżmy, że drzewo zależności w aplikacji filmowej zawiera nadrzędny MovieRouter zależny od widoków MovieSearch i MovieScreen, które zależą od modułów log i time z poprzednich przykładów:
Jeśli użytkownik odwiedzi widok wyszukiwania filmów, ale nie drugi widok, wszystkie moduły oprócz MovieScreen będą miały buforowane eksporty. Przy zmianie w module time, środowisko wykonawcze musi wyczyścić eksporty log by uwzględniło zmiany w time. Proces się tu nie kończy: środowisko rekursywnie powtórzy tę operację aż do zaakceptowania wszystkich modułów nadrzędnych. Pobierze moduły zależne od log i spróbuje je zaakceptować. Dla MovieScreen może przerwać (nie był jeszcze wymagany). Dla MovieSearch wyczyści eksporty i rekursywnie przetworzy jego moduły nadrzędne. Na koniec zrobi to samo dla MovieRouter i zakończy proces (żaden moduł od niego nie zależy).
Aby przejść drzewo zależności, środowisko wykonawcze otrzymuje od Packagera odwrotne drzewo zależności w aktualizacji HMR. Dla tego przykładu środowisko otrzyma obiekt JSON:
Komponenty React są trudniejsze w obsłudze przy Hot Reloadingu. Problem polega na tym, że nie możemy po prostu zastąpić starego kodu nowym, ponieważ stracilibyśmy stan komponentu. W przypadku aplikacji webowych React, Dan Abramov zaimplementował transformację Babel, która wykorzystuje API HMR webpacka. W skrócie, jego rozwiązanie działa poprzez tworzenie proxy dla każdego komponentu React w czasie transformacji. Te proxy przechowują stan komponentu i delegują metody cyklu życia do właściwych komponentów, które podlegają hot reloadowaniu:
Oprócz tworzenia proxy, transformacja definiuje funkcję accept z kodem wymuszającym ponowne renderowanie komponentu przez React. Dzięki temu możemy aktualizować kod renderowania bez utraty stanu aplikacji.
Domyślny transformer w React Native używa babel-preset-react-native, który jest skonfigurowany do wykorzystania react-transform w taki sam sposób, jak w projektach webowych React z webpackiem.
Gdy zmienisz reducer, kod akceptujący tę zmianę zostanie wysłany do klienta. Klient zorientuje się, że reducer nie wie jak sam siebie zaakceptować, więc poszczy moduły, które się do niego odwołują i spróbuje je zaakceptować. Ostatecznie proces dotrze do pojedynczego store'a - modułu configureStore, który zaakceptuje aktualizację HMR.
Dzięki React Native mamy okazję przemyśleć sposób budowania aplikacji, aby zapewnić świetne doświadczenia deweloperskie. Hot Reloading to tylko jeden element układanki - jakie inne kreatywne rozwiązania możemy wdrożyć, żeby było jeszcze lepiej?
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
Dzięki niedawnym premiom Reacta na webie i React Native na urządzeniach mobilnych, dostarczamy programistom nową bibliotekę do tworzenia produktów. Kluczowym aspektem budowania solidnych aplikacji jest zapewnienie, że może z nich korzystać każdy – w tym osoby z dysfunkcjami wzroku lub innymi niepełnosprawnościami. Accessibility API dla Reacta i React Native pozwala dostosować aplikacje dla użytkowników wspomagających się technologiami asystującymi, takimi jak czytniki ekranu dla osób niewidomych i niedowidzących.
W tym wpisie skupimy się na aplikacjach React Native. Zaprojektowaliśmy Accessibility API dla Reacta tak, by działało i wyglądało podobnie do rozwiązań z Androida i iOS. Jeśli tworzyłeś już dostępne aplikacje na Androida, iOSa czy web, framework i nomenklatura React AX API będą ci znajome. Przykładowo, możesz oznaczyć element interfejsu jako accessible (czyli dostępny dla technologii asystujących) i użyć accessibilityLabel do podania tekstowego opisu elementu:
<View accessible={true} accessibilityLabel=”This is simple view”>
Przeanalizujmy nieco bardziej złożone zastosowanie React AX API na przykładzie flagowego produktu Facebooka napędzanego Reactem: aplikacji Ads Manager.
To jest fragment wpisu. Przeczytaj całość na Facebook Code.