Lag a mobilalkalmazásban egy észrevehető késés a felhasználói művelet és a felület reakciója között, amely a főszál túlterhelése, memóriaszivárgás vagy nem optimális bemeneti-kimeneti műveletek miatt keletkezik. A logikai hibákkal kapcsolatos hibákkal ellentétben a lag teljesítményprobléma: az alkalmazás helyesen, de lassan működik. A AppDynamics Mobile App Performance Report 2024 szerint a felhasználók 62%-a törli az alkalmazást, ha az 3 másodpercnél tovább lassul. A lagok diagnosztizálásához CPU, memória és hálózat profilozására van szükség az Android Studio Profiler és Xcode Instruments segítségével.
Főbb pontok
Lag (az angol lag szóból) a mobilalkalmazásban egy szubjektíven érezhető késés a felhasználói művelet (érintés, csúsztatás, szövegbevitel) és a felület reakciója között. Technikailag a lagot a bemeneti esemény és a képkocka teljes megjelenítése közötti időként mérik: kényelmes küszöb — 100 ms-ig, észrevehető — 200 ms-tól, kritikus — 500 ms felett.
A felhasználói terminológiában a „lagzik” és a „lassul” gyakran szinonimaként használatos, de technikailag a lag egy rögzített késés (pl. 300 ms minden kattintásnál), míg a „lassul” egy nem állandó lassulás: az alkalmazás néha simán működik, néha egy másodpercre lefagy. A hiba a laggal ellentétben nem a sebességhez, hanem a megjelenítés helyességéhez kapcsolódik.
A Google Play és az App Store figyelembe veszi a teljesítménymutatókat az alkalmazások rangsorolásánál. Az ANR arány, a jank gyakorisága és az indítási idő befolyásolja a láthatóságot a keresésben és a telepítések konverzióját. Az állandó lagokkal rendelkező alkalmazás az első indítás után a felhasználók akár 40%-át is elveszíti.
Lagok akkor keletkeznek, amikor a fő UI szál nem tudja feldolgozni a képkockákat 60 FPS (16.6 ms/képkocka) vagy 120 FPS (8.3 ms) sebességgel. Vizsgáljuk meg a késések fő forrásait.
Bármely szinkron művelet az UI szálban — olvasás a SharedPreferences-ből, munka az adatbázissal Roomon keresztül suspend nélkül, kép dekódolása Bitmap-pé — blokkolja a képkocka megjelenítését. Androidon ez képkockák kihagyásához (jank) vezet, iOS-en — a Core Animation megjelenítés késéséhez.
Amikor a Garbage Collector Androidon vagy az ARC iOS-en felszabadítja a memóriát, minden szál leáll. Gyakori GC szünetek akkor keletkeznek, amikor sok ideiglenes objektum jön létre — például minden egyes lista adapter hívásakor egy új ViewHolder példány jön létre. Ez rángatózó görgetésként jelentkezik.
Egymásba ágyazott ConstraintLayout, többszörös LinearLayout, átfedő View — minden egymásba ágyazás növeli a measure és layout pass idejét. Az Xcode jelzi, hogy a mély réteghierarchia (több mint 10 szint) 20-30%-os FPS csökkenést okoz.
A lagok okainak azonosításához az IDE-be épített profilozókat és rendszerfigyelő eszközöket használnak. Minden eszköz a saját feladatát oldja meg.
A CPU Profiler megmutatja, hogy mely metódusok foglalják a processzoridőt és mely szálakban hajtódnak végre. Ha egy nehéz számításokkal rendelkező metódus a main thread-ben fut — ez a probléma gyökere. Nyomkövetés rögzítése bekapcsolt sample Java Method segítségével lehetővé teszi a hívási verem megtekintését minden pillanatban és a „forró pontok” megtalálását.
Az iOS analóg eszköze — Time Profiler — minden ezredmásodpercben gyűjt verem mintákat és megmutatja, hogy az CPU idő hány százalékát foglalja el egy metódus. A Main Thread Only jelzővel való kombináció csak a főszálon végzett műveleteket szűri ki, ami közvetlenül jelzi a lagok forrásait.
A lassú hálózati kérések a lag benyomását keltik, még akkor is, ha az UI szál nincs blokkolva. A Network Profiler az Android Studioban és a Network Link Conditioner az Xcode-ban lehetővé teszi a lassú kapcsolat szimulálását és annak megfigyelését, hogy az alkalmazás hogyan viselkedik valós körülmények között. A chunkolt válaszok előrehaladás nélkül és a nagy JSON rakományok a látszólagos lagok tipikus forrásai.
Példa hálózati kérés profilozására OkHttp-val időméréssel:
class TimingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val start = System.nanoTime()
val response = chain.proceed(chain.request())
val duration = (System.nanoTime() - start) / 1_000_000
Log.d("Időzítés", "A kérés $duration ms-ig tartott")
return response
}
}
A lagok megszüntetése szisztematikus munkát igényel: egyetlen metódus optimalizálásától az architekturális változtatásokig. Vizsgáljuk meg a leghatékonyabb technikákat.
Kotlin Coroutines a Dispatchers.IO diszpécserrel hálózati kérésekhez és Dispatchers.Default számításokhoz garantálja, hogy a főszál szabad marad az UI számára. iOS-en a Grand Central Dispatch a .global(qos: .userInitiated) sorral háttérfeladatokhoz és a .main sorral UI frissítésekhez — a standard megközelítés. Kerülje a sync műveleteket a sorok között.
A RecyclerView Androidon és UICollectionView iOS-en helyes konfigurációt igényel: ViewHolder minimális objektumlétrehozással az onBindViewHolder-ban, DiffUtil a változások kiszámításához, prefetching az adatok előzetes betöltéséhez. iOS-en használjon diffable data source-t animált frissítésekhez kézi kezelés nélkül.
Ugyanazon kép betöltése minden görgetéskor — garantált lag. A Coil (Android) és Kingfisher (iOS) a képeket memóriában és lemezen gyorsítótárazza, biztosítva az azonnali megjelenítést ismételt kérés esetén. Adatokhoz használjon Room-ot Flow vagy Combine alapú gyorsítótárazó réteggel.
Példa kép gyorsítótárazás beállítására Coil-lel Androidon:
val imageLoader = ImageLoader(context) {
memoryCachePolicy(CachePolicy.ENABLED)
diskCachePolicy(CachePolicy.ENABLED)
crossfade(true)
size(512, 512)
}
// Betöltés automatikus gyorsítótárazással
imageView.load("https://example.com/image.jpg") {
placeholder(R.drawable.placeholder)
error(R.drawable.error)
}
A lagok megelőzése olcsóbb, mint javításuk éles környezetben. A megelőző intézkedések az eszközök és az architektúra szintjén épülnek be a fejlesztési folyamatba.
A StrictMode — az Android beépített eszköze, amely véletlenszerű bemeneti-kimeneti műveleteket és hálózati hívásokat észlel a főszálon a fejlesztési szakaszban. Kapcsolja be az Application.onCreate-ben penaltyDeath politikával a kritikus megsértésekhez. Ez az egyetlen módja annak, hogy garantálja, a fejlesztő látja a problémát a commit előtt.
Az iOS analógja — Main Thread Checker az Xcode-ban, a Runtime Sanitization része. Automatikusan ellenőrzi, hogy minden UIKit és AppKit hívás a főszálból történik. Kapcsolja be a Debug build sémában és érjen el nulla figyelmeztetést a CI-ban.
Adja hozzá a CI csővezetékhez a Macrobenchmark (Android) és XCTMetrics (iOS) futtatását az indítási idő, görgetési FPS és memóriahasználat méréséhez. Állítson be küszöbértékeket: ha egy új commit több mint 5%-kal növeli az indítási időt — a build sikertelen.
Gyakran Ismételt Kérdések
A lag a késés szubjektív érzése, amely magas FPS mellett is előfordulhat, ha a késést a bemenet feldolgozási ideje okozza, nem pedig a megjelenítés. Az alacsony FPS (kevesebb mint 30 képkocka/s) — a lagok egyik oka, de nem az egyetlen.
Használja a Frame Timing API-t Androidon (Choreographer) és a CADisplayLink-et iOS-en a képkockák közötti idő mérésére. A Google Play Vitals valós körülmények között mutatja a jank arányt. Pontos mérésekhez használja a Macrobenchmark-ot görgetési forgatókönyvekkel.
A régi eszközök kevesebb CPU maggal, kevesebb RAM-mal és lassabb memóriával rendelkeznek. Egy művelet, amely egy zászlóshajón 5 ms-ig tart, egy budget eszközön 50 ms-ig is tarthat. Tesztelje a teljesítményt alsó kategóriás eszközökön és állítson be Baseline Profiles-t az AOT fordításához.
Igen, ez az egyik leghatékonyabb módszer. A nagy felbontású képek sok memóriát és CPU időt foglalnak a dekódoláshoz. Használjon downscale-t a View méretére, WebP (Android) és HEIC (iOS) formátumokat, valamint gyorsítótárazást Coil vagy Kingfisher segítségével.
A SwiftUI automatikusan optimalizálja a frissítéseket diffing segítségével, ami csökkenti a lagok kockázatát az adatok változásakor. Azonban az összetett hierarchiák és a gyakori body újraépítések FPS csökkenést okozhatnak. Az UIKit nagyobb ellenőrzést biztosít a teljesítmény felett, de kézi optimalizálást igényel.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is