Durerea de performanță poate face dezvoltatorii să meargă mai departe. În această postare pe blog, puteți afla din problemele de performanță pe care le-am întâlnit la Kraken și despre cum ne-am angajat într-o călătorie de adoptare a Noii Arhitecturi pentru a rezolva aceste probleme. Da, au fost scăderi de viteză pe parcurs. Am învățat de la ei și sperăm că și tu poți.
Noua arhitectură va fi cea implicită, începând de la React Native 0.76 și Expo SDK 52, următoarele versiuni ale React Native și Expo. Noile caracteristici în curs de dezvoltare vor fi implementate numai pentru Noua Arhitectură, iar unele biblioteci renunță deja la suportul pentru arhitectura veche. Ar trebui să începi cu adevărat să te gândești să-l adopti dacă nu vrei să ratezi!
Prezentare generală asupra arhitecturii Kraken
Kraken este una dintre cele mai mari, cele mai de încredere și mai sigure platforme de criptomonede, cu o comunitate vibrantă de peste 13 milioane de clienți din întreaga lume. În prezent avem trei aplicații mobile în producție – toate scrise în React Native cu o mulțime de biblioteci și componente native personalizate în Swift/Kotlin și un backend în Rust.
Deși nu folosim întreaga suită Expo din motive istorice, am început să migrăm pentru a folosi module Expo peste unele dintre pachetele comunității din motive de întreținere și performanță. Performanța este o preocupare esențială pentru noi, în special în aplicația noastră Pro, care consumă intens date și este plină de diagrame interactive care sunt actualizate în mod constant prin WebSockets. Acest lucru pune o presiune asupra performanței, în special pe dispozitivele Android de gamă joasă. Așa că mult timp ne-am ținut ochii pe progresul Noii Arhitecturi și am sperat că va atenua unele dintre problemele cu care ne confruntăm.
La sfârșitul acestei călătorii, am reușit să îmbunătățim semnificativ performanța aplicațiilor noastre în mai multe domenii:
Redare completă a aplicației: de 1,3 ori mai rapid
Redare ecran de pornire: de 2,5 ori mai rapid
Randamentul ecranului fluxului de tranzacționare: de 5,3 ori mai rapid
Și mai mult…
Continuați să citiți pentru a afla mai multe despre călătoria noastră și despre toate celelalte beneficii de performanță care au venit odată cu aceasta.
Planul nostru de adoptare a noii arhitecturi
Scopul nostru principal a fost să îmbunătățim performanța pe Android. Primul nostru curs de acțiune a fost să creăm o dovadă de concept rapidă folosind Fabric pentru a putea estima câștigurile. În ciuda bazei noastre de cod destul de mari și a multitudinii de dependențe, acest lucru s-a făcut destul de repede prin valorificarea stratului de interoperabilitate moștenit și eliminarea bibliotecilor/componentelor incompatibile. Rezultatul a fost o aplicație mult mai rapidă, care a fost susținută de valori obiective de performanță.
Știind că ecosistemul se afla încă într-o fază de migrare și așteptându-ne la unele margini aspre, am decis să adoptăm Noua Arhitectură într-o manieră incrementală pentru a reduce riscul ingineresc. Aceasta însemna să mergeți platformă cu platformă, aplicație cu aplicație și arhitectură caracteristică după caracteristică. Planul nostru simplificat arăta cam așa:
Actualizați bibliotecile de componente ale terților și migrați componentele interne pentru a suporta atât redarea nouă, cât și cea veche
Actualizați bibliotecile de module native ale terților și migrați bibliotecile interne la modulele Turbo native
Activați modul fără punte
Eliminați compatibilitatea cu versiunea anterioară odată ce este complet lansată
Viteza de adoptare a noii arhitecturi
În călătoria noastră progresivă de adoptare, ne-am confruntat cu o mână de scăderi de viteză. Acest lucru era de așteptat. În această secțiune îi vom chema pe fiecare în speranța că va ajuta alte echipe să le navigheze puțin mai repede decât am făcut-o noi.
Rapid
Spre deosebire de modulele Turbo, componentele Fabric nu au oficial suport Swift. A fost o dezamăgire, deoarece baza noastră de cod este în Swift și nu am vrut să revenim la Objective-C. Cu ceva inspirație din biblioteca Lottie (și ajutor dintr-un videoclip de la Coding With Nobody) am făcut-o să funcționeze. Este demn de remarcat faptul că modulele Expo au suport nativ Swift și un API probabil mai frumos. De asemenea, ținem un ochi pe proiectul Nitro de la Marc Rousavy, care ar putea susține componente Fabric în viitor.
Dozare automată
În unele ecrane am observat o randare mai lentă, în special ecrane foarte grele, cum ar fi graficele interactive.
Deși nu suntem complet siguri de cauza principală, bănuim că acest lucru s-a datorat procesării automate introduse în React 18, care este acceptată doar pe Noua Arhitectură. Teoria a fost că, în timp ce lotizarea duce la o încărcare mai mică a procesorului, a omis și câțiva pași intermediari care au dat o impresie mai rapidă. În cele din urmă, componenta nu a fost construită corect, așa că, după o refactorizare și o migrare pentru a utiliza Reanimated pentru interacțiuni sensibile la performanță, problemele au fost rezolvate.
Fără punte
Deoarece modul Bridgeless este cea mai recentă piesă a puzzle-ului Noua Arhitectură, am vrut să adoptăm aceasta din urmă, chiar dacă a fost schimbarea relativ cea mai puțin perturbatoare (mulțumită unui mod de interoperabilitate excelent). Cu toate acestea, planul nostru nu a funcționat, deoarece Expo 51 nu acceptă Fabric fără a utiliza și modul Bridgeless. Aceasta a fost o problemă pentru noi, deoarece doream niște remedieri în React Native 0.74, ceea ce însemna că a trebuit să adoptăm Bridgeless puțin mai devreme decât era planificat.
În general, a fost necomplicat, cu o singură excepție: CodePush va fi retras în curând și ne bazăm pe requestIdleCallback pentru unele dintre valorile noastre de performanță. În prezent, suntem în proces de migrare la actualizările Expo, dar între timp am reparat suportul prin pachetul de patch-uri/patch-uri și cererea backportedIdleCallback, care este acceptată de la 0.75.
Straturi de interoperabilitate
Modul de interoperabilitate pentru componentele Old Renderer a funcționat ca magic pentru majoritatea componentelor Android, dar pentru iOS am constatat că avea probleme de aspect pe una dintre componentele noastre native interne. Aceasta nu a fost niciodată starea finală intenționată, indiferent și am rezolvat-o pur și simplu migrându-le în Fabric.
Proguard
La începutul dezvoltării noastre, am observat că o ramură care a funcționat excelent în dezvoltare s-a prăbușit într-o versiune de producție cu mesaje de eroare oarecum vagi. După câteva săpături, am constatat că acest lucru a fost cauzat de eliminarea anumitor clase și metode de la terți de către Proguard. Este posibil să fi fost cauzat de natura leneșă a modulelor Turbo, care a încurcat optimizatorul Proguard, făcându-le să creadă că nu au fost folosite. Odată ce am descoperit problema, a fost ușor să excludem pur și simplu acele simboluri de la eliminarea.
Rola
După cum am menționat anterior, am dorit să adoptăm Noua Arhitectură cât mai progresiv posibil. În mod ideal, am fi vrut să mergem ecran cu ecran și, deși Noua Arhitectură este acceptată nativ, în prezent nu este acceptată de React Navigation, așa că a trebuit să fim atenți când lansăm Fabric. Cu toate acestea, datorită straturilor de interoperabilitate, am reușit să lansăm cu succes noul arc la nivel de proiect.
Maestru
Deși avem multe teste de componente folosind Biblioteca de testare React, din păcate, acestea nu ne vor oferi nicio încredere în adoptarea noului redator; în schimb, ne-am bazat foarte mult pe testele noastre automate end-to-end pe Maestro Cloud. Tot aici rulăm suita noastră de performanță pentru a ne oferi cifre serioase înainte de a începe producția.
Testare internă
În mod normal, nu ne bazăm pe testarea manuală, dar din moment ce aceste modificări au un impact mai mare și nu pot fi anulate cu ușurință cu un semnalizator de caracteristică, am distribuit build-uri intern pentru ca oamenii să testeze și să verifice dacă fluxurile lor au funcționat conform așteptărilor. Acest lucru a fost util în special pentru a găsi regresii de randare în ecranele de nișă care au fost inițial omise din cauza lipsei de testare vizuală.
„Canary lansează”
Când am crezut că am testat cât de mult am putut cu și fără automatizare, am vrut să le oferim unui număr mic de utilizatori de producție. În mod tradițional, am folosi steaguri de caracteristici în LaunchDarkly pentru aceasta, dar deoarece majoritatea pieselor noii arhitecturi sunt steaguri de compilare, aceasta nu a fost o opțiune. În schimb, am optat pentru versiunea unui om sărac a lansărilor canare prin lansări graduale pe Play Store.
Aplicațiile noastre sunt lansate pe o cadență săptămânală și, în esență, odată ce considerăm că o lansare este stabilă și complet lansată în producție, oferim unui mic procent de utilizatori o versiune cu Noua Arhitectură activată. Deoarece lansările treptate din Magazinul Play pot fi oprite, am putea limita impactul utilizatorului în cazul oricăror erori grave sau blocări. În plus, rularea înainte este mai rapidă datorită procesului de revizuire în general mai rapid.
Monitorizarea clientului real
Odată ce aplicația a fost în mâinile clienților noștri, i-am monitorizat religios în ceea ce privește stabilitatea, performanța și valorile de produs/conversie.
Stabilitate prin Sentry și Play Store
Performanță prin Sentry cu propriile noastre valori personalizate
Valori de produs în principal prin Mixpanel
Rezultatele adoptării noii arhitecturi
Stabilitate
În primele noastre versiuni, am observat o scădere ușoară a stabilității din cauza unei prăbușiri într-una dintre bibliotecile terțe prezente doar pe Noua Arhitectură și care afectează un flux destul de rar. Odată ce am remediat această problemă, stabilitatea a fost la egalitate cu arhitectura veche la 99,9% sesiuni fără blocări.
Performanţă
În general, datele noastre de producție au arătat că timpii de randare au devenit semnificativ mai rapid, dar cu o mare variabilitate între diferitele ecrane. Am observat, de asemenea, că cele mai mari îmbunătățiri au fost observate la cele mai lente dispozitive – atât în termeni absoluti, cât și relativi – ceea ce a fost o surpriză fericită.
Totuși, nu totul a devenit mai rapid: pornirea la rece nativă a devenit puțin mai lent, ceea ce a fost oarecum surprinzător, având în vedere migrarea noastră la modulele Turbo. Deoarece dimensiunea binară a aplicației a crescut odată cu noua arhitectură activată, presupunerea noastră actuală este că acest lucru este cauzat de părți încă prezente ale vechii arhitecturi. Ne așteptăm ca acest lucru să se îmbunătățească în viitor, când migrarea este complet finalizată și cu inițiative precum biblioteca dinamică unică a lui Nicola.
React Native 0.76 va fi livrat cu o singură bibliotecă dinamică îmbinată numită `https://t.co/w2nNNDov97`:https://t.co/peZ08rvbtS
Acest lucru vine cu economii majore de spațiu pentru utilizatori, precum și câștiguri de performanță
— Nicola (@cortinico) 20 august 2024
În ansamblu, cea mai importantă și mai holistică măsurătoare care influențează utilizatorul numită App Render Complete – care include boot nativ, js boot, rețea și randare – a fost îmbunătățită.
Măsură
P50
P95
Randarea aplicației este finalizată
1x
1,3x
Redare ecran de pornire
2x
2,5x
Ecran de randare a fluxului de tranzacționare
3,8x
5,3x
Pornire la rece nativă
0,9x
0,7x
Timp total de blocare a navigației
1x
1,1x
Următorii pași
Odată cu implementarea cu succes a Noii Arhitecturi, ne uităm la cum să valorificăm în continuare noile capabilități dobândite, cum ar fi:
Utilizați useDeferredValue pentru componente actualizate frecvent, dar mai puțin critice, cum ar fi indicatorii de preț
Remediați cazurile de aspect săritor prin înlocuirea onLayout cu apeluri sincrone de măsură().
Expuneți bibliotecile Rust existente din backend la aplicații prin legături JSI
Mulţumesc
Nicola Corti și echipa React Native de la Meta pentru furnizarea de resurse incredibil de utile pentru adoptarea noii arhitecturi și pentru a fi receptivi la feedback și pentru a răspunde rapid.
Brent Vatne la Expo pentru că a condus efortul de a face ecosistemul să migreze la noua arhitectură și a răspuns la întrebări aprofundate.
Întreaga echipă Software Mansion pentru a îndeplini sarcina uriașă de a migra multe dintre bibliotecile de bază ale terțelor părți, cum ar fi reanimated, gesture handler, ecrane și svg.
Începeți cu Kraken
Aceste materiale au doar scop informativ general și nu sunt sfaturi de investiții sau o recomandare sau o solicitare de a cumpăra, vinde, miza sau deține orice criptoactiv sau de a se angaja într-o strategie de tranzacționare specifică. Kraken nu face nicio declarație sau garanție de nici un fel, expresă sau implicită, cu privire la acuratețea, completitudinea, actualitatea, caracterul adecvat sau validitatea oricărei astfel de informații și nu va fi responsabil pentru erori, omisiuni sau întârzieri ale acestor informații sau orice pierderi, leziuni sau daune rezultate din afișarea sau utilizarea acestuia. Kraken nu lucrează și nu va lucra pentru a crește sau a reduce prețul oricărui criptoactiv anume pe care îl pune la dispoziție. Unele produse și piețe cripto nu sunt reglementate și este posibil să nu fiți protejat de compensații guvernamentale și/sau scheme de protecție de reglementare. Natura imprevizibilă a piețelor criptoactive poate duce la pierderi de fonduri. Taxele pot fi plătite pentru orice profit și/sau pentru orice creștere a valorii criptoactivelor dvs. și ar trebui să solicitați consiliere independentă cu privire la poziția dvs. fiscală. Se pot aplica restricții geografice.
Postarea Adoptarea progresivă de către Kraken a Noii Arhitecturi pentru remedierea problemelor de performanță a apărut mai întâi pe Kraken Blog.
Sursa: Kraken
Postarea Adoptarea progresivă de către Kraken a Noii Arhitecturi pentru remedierea problemelor de performanță a apărut mai întâi pe Crypto Breaking News.