Napisao: Marin Maršić, Android Developer
SofaScore petak – dan za vlastiti razvoj i kreativnost developera
Pored svih obaveza koje kao developeri imamo na poslu, ponekad je uistinu teško pronaći vrijeme za reevaluaciju i poboljšanja postojećih programskih rješenja. Uz sve zadatke, sprinteve, bugove i fixeve ovakve stvari često budu odgađane u nedogled. Upravo iz tog razloga u SofaScoreu postoji nešto što zovemo “Petak 10%”. To je inicijativa koja omogućuje developerima da iskoriste 10% svog radnog vremena tjedno na razvijanje vlastitih ideja, istraživanje novosti u svijetu developmenta, predlaganje poboljšanja ili jednostavno rad na unapređivanju postojećih i usvajanju novih znanja. Drugim riječima, to su zadaci koji nam nisu direktno zadani, nego si ih sami smišljamo ovisno o vlastitim interesima.
Zahvaljujući ovoj inicijativi, jedan petak proveli smo analizirajući memorijske performanse naše mobilne aplikacije. Ovo su rezultati:
Kvalitetno korisničko iskustvo ne smije biti rezervirano samo za neke korisnike…
Živimo u vremenu kada se velike tehnološke kompanije silno trude biti ispred svoje konkurencije. Svake godine izlaze sve napredniji modeli pametnih telefona sa sve boljim karakteristikama. No ti vrhunski uređaji i dalje nisu dostupni velikom broju ljudi. Velik dio naših korisnika nalazi se u zemljama u razvoju i nemaju pristup najnaprednijim tehnologijama. Iz tog razloga jako velik naglasak stavljamo na optimizacije koje će svim našim korisnicima omogućiti kvalitetno iskustvo, ma gdje god da se oni nalazili.
Jedna od bitnijih značajki prilikom odabira novog pametnog telefona obično nam je njegova RAM memorija. S obzirom na to da je to memorija koja se koristi prilikom izvođenja aplikacija, iznimno je bitno da je imamo dovoljno kako bi sve radilo glatko. Iako u novije vrijeme količina te memorije raste, podjednako raste i kompleksnost samih aplikacija pa problem optimalnog korištenja dostupnih resursa nikad nije postao nešto što možemo zanemariti.
Odgovorno upravljanje memorijom nije poželjno, nego nužno
Podvrsta RAM memorije na koju ćemo se ovdje usredotočiti je heap memorija koja se koristi za dinamičku alokaciju objekata. Sve resurse koje generiramo, dohvaćamo s interneta i prikazujemo u aplikaciji zauzimaju određenu memoriju. Svaka Android aplikacija ima dodijeljenu maksimalnu količinu takve memorije kako bi se osiguralo glatko izvođenje svih procesa na uređaju. S njom treba biti odgovoran jer u slučaju lošeg ponašanja, sustav će “ubiti” aplikaciju kako bi oslobodio zauzete resurse.
Iako u java okruženju postoji Garbage collector zadužen za dealokaciju zauzete memorije, on može osloboditi samo one resurse za koje utvrdi da se više ne koriste tj. da na neki objekt ne postoji aktivna referenca. Međutim, ako na neki objekt koji nam više nije potreban i dalje postoji referenca, GC ga neće očistiti i memorija se neće osloboditi. Ovo će nam narušiti balans zauzete i otpuštene memorije pa ćemo s vremenom imati sve više zauzete memorije. GC će se u paničnoj potrazi za memorijom pokretati sve češće i izvoditi sve dulje što će rezultirati smrzavanjem aplikacije (ANR). U trenutku kada ne uspije pronaći dovoljno memorije aplikacija će se srušiti (OOM exception).
S obzirom na veliku fragmentiranost android ekosustava, teško je pratiti ponašanje naše aplikacije na velikom spektru uređaja različitih karakteristika. U tome nam dosta pomažu Googleovi alati za analizu performansi na aplikacijama naših korisnika: Play Store Console i Firebase Crashlytics. Iako smo uvijek stajali dobro po pitanju stabilnosti aplikacije, primijetili smo da bismo razinu ANR-ova mogli probati malo poboljšati. Koristeći alate za analizu memorijskih performansi naše aplikacije (Android Studio Profiler i Leak Canary) u više navrata uvjerili smo se da memorijom raspolažemo odgovorno na razini pojedinačnih ekrana u aplikaciji. No postojao je problem u samom konceptu korištenja naše aplikacije. Naime, većina danas popularnih aplikacija ima nekoliko ekrana (activity-ja) kroz koje navigiraju svoje korisnike i obično je jedan od tih ekrana glavni te na njemu korisnici izvode većinu aktivnosti. WhatsApp, Google Maps, Gmail, Uber, mBanking,… sve su to aplikacije koje imaju nekoliko ekrana (glavni, detalji poruke, postavke, profil) i čije je navigacijsko stablo poprilično plitko. Osim što naša aplikacija sadrži više vrsta ekrana, većina njih može biti prikazana u velikom broju varijanti. Npr. korisnik s popisa utakmica može ući u detalje jedne od njih, zatim može otvoriti detalje gostujućeg tima, pa detaljnije analizirati nekog od njihovih igrača te dalje otići na neki drugi turnir na kojem je taj igrač sudjelovao. Taj turnir onda opet ima popis utakmica što omogućava daljnje otvaranje novih ekrana. Sve prethodne ekrane koje je korisnik posjetio sustav drži u memoriji da bi se korisnik na njih mogao brzo i jednostavno vratiti pritiskom na tipku “back”.
Kako ostvariti ravnotežu između korisničkog iskustva i tehničkih ograničenja?
Tu sada dolazimo do problema: s jedne strane ograničeni smo količinom memorije kojom raspolažemo, a s druge strane želimo korisnicima omogućiti da koriste aplikaciju slobodno i bez ograničenja. Da bi pomirili ova dva zahtjeva odlučili smo ograničiti broj prethodnih ekrana koje čuvamo u memoriji (tzv. backstack). Pod pretpostavkom da se korisnici najviše sjećaju ekrana koji je neposredno prethodio trenutnom, a svakog prethodnog sve manje, odlučili smo u memoriji čuvati samo 5 prethodnih ekrana na kojem se korisnik nalazio. Ovim smo pristupom značajno poboljšali performanse naše aplikacije i smanjili smrzavanje aplikacije. Dodatno se ovo može unaprijediti tako da se umjesto fiksnog broja on određuje dinamički na temelju dostupne memorije na samom uređaju.
Broj rušenja aplikacije i ANR-ova nam se drastično smanjio, a zadovoljstvo korisnika i konkurentnost našeg proizvoda i dalje su ostali na visokoj razini. Zato u budućnosti i dalje planiramo raditi na ovakvim poboljšanjima, za što nam je posebno bitno konstantno jačanje development tima.
Iako se na prvu može činiti da smanjenje vremena koje developeri provode na rješavanju zadataka i ulaganje u individualni razvoj može prouzročiti usporavanje razvoja proizvoda, drago nam je da se kod nas to pokazalo uspješnim. Ovo je samo jedan u mnoštvu primjera gdje je ulaganje u zaposlenike indirektno utjecalo na poboljšanje proizvoda. Trud koji smo uložili svakako utječe i na zadovoljstvo naših korisnika koji to pokazuju ocjenama koje nam daju na Google Play Store-u (4.8) i App Store-u (4.9). One nam daje potvrdu da idemo u dobrom smjeru i poticaj da nastavimo tako dalje.