Version note — reviewed October 13, 2026: This article was written in 2018. Device examples, app experiences, and vendor opinions describe that period; the old hardware rankings and buying advice are outdated. Technical corrections and updates identify their Android versions. These are not new measurements of the named products.
I’ve long wanted to write about Android system fluency because it’s the most direct aspect of the user experience. The long-standing criticism that Android “gets laggier over time” still casts a shadow over the platform, and it’s a primary reason many users default to iPhone.
Because Google keeps Android open, different manufacturers produce devices with vastly different hardware, and app quality varies wildly. Consequently, fluency is affected by countless factors. It’s rarely just “the system isn’t optimized.” Often, two devices with the same OS but different SOCs offer completely different experiences.
I want to talk through some of the reasons Android can feel slow, so that the next time it happens, we don’t immediately blame the system. Perhaps uninstalling one app will turn out to be enough. Here are the areas I want to cover:
- Hardware
- System
- Applications
- The Optimization Loop
Ready? Let’s get started, and please join the discussion.
1. Hardware Level
CPU
The CPU handles much of an app’s business logic and layout work, but the phone’s overall experience also depends on its GPU, storage, memory, cooling, and software workload. The original Qualcomm > Huawei > Samsung > MediaTek ranking did not specify chips or test conditions and should not be used as a buying guide. Compare specific SoCs and devices, including sustained performance rather than just short bursts.
GPU
The GPU is normally part of the SoC: for example, Snapdragon 845 includes Adreno 630. Graphics-heavy games can put substantial pressure on it. However, a game’s name alone does not establish whether it is CPU- or GPU-bound. That applies to Honor of Kings too: version, scene, quality settings, and target frame rate all matter.
RAM
When I wrote this in 2018, 4 GB was common, and a phone almost needed 6 or 8 GB before it could call itself a flagship. That was a comment on the market then, not a current Android minimum or buying recommendation. More RAM can retain cached processes and files, reducing reloads, but capacity is different from bandwidth. Heap limits, rendering caches, and preloading still need bounds; more memory does not guarantee faster execution.
Keeping more background processes also has a cost if they continue running and competing for CPU or power.
Storage (UFS vs. EMMC)
The original comparison concerned eMMC 5.1 and UFS 2.1, common in the 2018 discussion. Storage affects file reads, installation, and resource loading, but interface names and sequential copy speeds do not determine every launch or interaction. Random I/O latency, implementation, and concurrent load also matter.
The Chinese original incorrectly stated that Snapdragon 660 did not support UFS. Qualcomm’s Snapdragon 660 product brief lists both eMMC and UFS. Platform support does not tell us which storage a particular phone actually uses.
Screen Resolution
1920 × 1080 describes one 16:9 resolution; phones with other aspect ratios do not all use those dimensions. Higher actual rendering resolution can increase pixel processing and bandwidth costs in rendering, composition, screenshots, or recording. The impact depends on the rendering path and its bottleneck.
Physical display resolution, app rendering resolution, and recording output resolution can differ. I used the Meizu MX4 Pro as an example because users had reported lag and battery drain. Those reports alone do not establish its 2K panel as the sole cause.
Battery Capacity
Battery capacity affects runtime and device design, but workload, efficiency, display power, and temperature also matter. Comparing mAh alone can mislead when battery voltages differ, and a larger battery does not guarantee better sustained performance.
The Chinese article’s recommendations of Oppo Find X, Vivo NEX, and Huawei Mate 10 were 2018 buying advice and are now outdated. The broader point was to consider usable runtime and cooling alongside the SoC.
SoC Platform
The SoC (System-on-a-Chip) and its vendor software form a foundation for the device. OEMs integrate that platform with their hardware and Android customizations.
In my 2018 development experience, Qualcomm’s platform was comfortable to work with: plenty of optimization code and configuration options, good documentation, and quick support. This is a historical engineering opinion, not a controlled comparison or a ranking of today’s vendor platforms.
As for the patent fees, pay what needs paying. We used to joke that if Meizu had adopted Qualcomm SoCs earlier, it would have gone public ages ago.
2. System Level
App Management Policies
Back in 2018, app developers had plenty of reasons to resent Chinese OEMs’ aggressive background controls. But those controls had a reason too: apps from the same vendor kept waking one another up. In some of the cases we investigated, apps were busy in the background or too many processes were occupying memory, and ordinary users had no idea what to do about it. That does not establish the cause of most Android lag.
Examples of vendor policies included restricting apps from silently launching other apps, unnecessary background residency, and prolonged CPU work during screen-off. Their behavior depends on ROM, permissions, and user settings; they are not universal Android prohibitions.
Remote message delivery, posting a notification, and opening its destination are separate steps. An OEM Push SDK is not a universal prerequisite for notifications. For example, on devices with the required services and connectivity, FCM notification messages received in the background can appear in the system tray. OEM push services have their own requirements.
From Android 13 (API 33), non-exempt notifications also require the POST_NOTIFICATIONS runtime permission; channels and user settings affect display too. Tapping a notification may require a cold start if the process has been reclaimed. The resulting delay depends on initialization and the destination screen, not just the push provider.
Memory Strategy
OEMs tune cached processes, memory-pressure handling, and rendering caches for their products. The original LowMemoryKiller threshold discussion reflects older implementations. Android 9 and later use userspace lmkd when no kernel LMK driver is present; Android 10 added PSI-based pressure monitoring, and Android 11 revised the killing strategy to account for thrashing. Kernel support and device configuration still matter. See AOSP lmkd.
Some low-memory cases we investigated involved repeated process kills, reloads, and high CPU use. Reclaim is not all disk swapping: clean file-backed pages can be discarded and read again on demand, while some anonymous pages can be compressed in RAM through zRAM. Devices may also configure zRAM writeback. See Android memory allocation.
Block I/O in a trace is a clue, not proof that memory pressure caused a missed frame. Correlate reclaim, page faults, I/O waits, and process restarts with the affected work. The old advice to buy 8 GB because memory needs only grow is no longer a useful general rule.
Process Scheduling
A rendering dependency that cannot get CPU time may miss its deadline. A Runnable interval in a trace means the thread is eligible to run but waiting for a CPU; it can also follow preemption. It does not by itself prove a scheduler defect.
Check competing runnable work, priority, CPU affinity or cpuset restrictions, and wakeup/migration behavior. Frequency limits and big/little-core placement can change completion time, but running on a little core does not automatically mean jank.
WMS/AMS lock contention and Binder waits require a separate dependency analysis: a blocked thread may be sleeping rather than Runnable. Distinguish slow execution, waiting for CPU, and waiting for another thread or resource. See Perfetto CPU Scheduling. System tuning must also account for the kernel, SoC, and power policy.
Main Thread & Render Thread
For hardware-accelerated View/HWUI rendering, the main thread and RenderThread are useful starting points. RenderThread is created on demand through the renderer path, not necessarily alongside the main thread at process startup. Games with their own rendering paths may use a different structure. See the Android 5.0 RenderThread walkthrough.
Profile GPU Rendering bars can identify slow stages, but they do not fully measure GPU execution, SurfaceFlinger, or screen presentation. Follow up in a trace. Possible causes include:
- Long input handlers.
- Heavy animation or list-update work, including item creation and binding.
- Expensive Measure/Layout/Draw passes.
- Frequent large bitmap uploads.
- Rendering commands, GPU work, or buffer waits.
Not all jank originates in these two app threads. Composition, display scheduling, and resource contention also matter. The goal is to finish critical work on time while accommodating input, audio, other necessary work, and power limits; assigning the whole foreground rendering path the highest priority cannot guarantee that.
Triple Buffering
Android 4.1’s Project Butter introduced improvements including synchronized timing and triple buffering. Extra buffering can improve producer/consumer overlap, but queuing may add input-to-display latency. It does not guarantee that an over-budget frame will avoid jank.
Refresh intervals are approximately 16.67 ms at 60 Hz, 11.11 ms at 90 Hz, and 8.33 ms at 120 Hz. These are not universal per-thread budgets. Crossing a 16 ms bar alone does not fully establish presentation jank, and triple buffering cannot be used to dismiss it.
On Android 12 (API 31) and later, Perfetto FrameTimeline can help compare expected and actual timelines and identify late presentation, alongside CPU/GPU and SurfaceFlinger work. Availability depends on version, capture configuration, and rendering-path coverage. Missing data does not mean zero jank.
Virtual Machine (ART vs. Dalvik)
ART improved execution and memory management, but GC can still pause the main thread. Android 8.0’s default Concurrent Copying collector moves much of the work concurrently while retaining a pause phase; allocation pressure and the time needed to suspend threads also matter. See AOSP’s ART GC debugging guide.
Inspect allocation rate, GC frequency, pause duration, and their overlap with slow frames. Neither “Dalvik jank is all GC” nor “ART eliminates GC pauses” is a sound diagnosis.
Thermal and Low-Battery Limits
Thermal throttling, battery saver, and device-idle restrictions are different mechanisms. Depending on the device and state, they can affect frequencies, background work, or networking; overheating does not universally trigger core shutdowns, process kills, disabled effects, and network disconnection together.
A game slowing down after sustained play may be thermally limited, but workload, memory, and network changes need checking too. Android 10 (API 29) added PowerManager thermal-status callbacks. Observe them alongside frame times; ADPF thermal guidance also describes adapting workload for sustainable performance. A larger battery cannot substitute for cooling.
3. Application Level
Complex Layouts
Complex layouts can increase Measure/Layout/Draw work, especially during scrolling when items are created or bound. Hierarchy depth alone is not a diagnosis: inspect actual traversal counts, time spent, and missed deadlines.
Excessive Business Logic
Here is my complaint about Taobao’s cold start in 2018. The home screen would appear, but trying to use it felt like crap: tap a button, nothing; try to scroll, nothing. Some versions had improved, but on a low-end phone it was the same old story. This describes my experience then, not a test of the current release.
Heavy initialization, synchronous module loading, or competing CPU work can make an already visible home screen slow to respond.
The article did not include a complete trace proving substantial dex2oat work on every such launch. ART uses interpretation, JIT, and profile-guided AOT compilation, with behavior depending on installation, existing artifacts, usage, and system policy. A cold start does not mean recompiling the entire app. Modern apps can use Baseline Profiles for common paths, while still measuring initial display and business readiness separately.
Memory Churn
Rapid temporary-object allocation can increase GC frequency and CPU work. A sawtooth memory graph also occurs in normal apps; it does not alone prove a bug or leak. Examine allocation hotspots, GC pauses, and frame timing. If objects remain after their work is finished and collection has occurred, investigate why they are still referenced.
Slow Networking
Users may describe a long wait for content as lag, but network waiting and rendering jank are different metrics. An asynchronous request can be pending while the UI remains smooth. If network work, parsing, or updates block the main thread, investigate that execution path.
Suboptimal Design
Complex, nested animations can be a programmer’s nightmare. A flagship user might love the effect while someone with a low-end phone curses the stuttering. We need enough knowledge and measurements to talk through the tradeoffs with designers. Users of cheaper phones care about performance too, so the design needs to account for them, or provide an appropriate alternative.
Implementation Bugs
Performance bugs can be an unattractive job. At my company, the time spent investigating one could have fixed a dozen visible UI bugs, and we still might not have solved it. Even so, my view was that confirmed performance problems caused by implementation errors deserved top priority.
4. The Optimization Loop
Laboratory Monitoring
Use data to monitor performance during development, simulating user environments to catch problems early. Record device, OS/app versions, refresh rate, temperature, and compilation state so comparisons are meaningful. Separate startup waiting, interaction response, and rendering jank.
Real-World Data Collection
Collect performance metrics from users to identify the most common issues. Be careful to avoid the “observer effect” where monitoring itself causes lag. Focus on indicators such as CPU waiting, memory pressure, and thermal state, tied to the affected scenario. Correlation is a starting point, not causation; verify the explanation against the timeline and a reproducible case.
Targeted Optimization
Rank issues by frequency and impact. Often, this requires collaboration between OEMs and app developers. Incorporate these scenarios back into the lab environment to create a continuous improvement loop: Lab Monitor -> User Simulation -> Big Data Collection -> Targeted Fix -> Lab Update.
About Me && Blog
Below is my personal intro and related links. I look forward to exchanging ideas with fellow professionals. “When three walk together, one can always be my teacher!”
- Blogger Intro
- Blog Content Navigation: A guide for my blog content.
- Curated Excellent Blog Articles - Android Performance Optimization Must-Knows
- Android Performance Optimization Knowledge Planet: The paid community stopped operating in 2026 and no longer accepts new members; this link preserves its history.
One walks faster alone, but a group walks further together.
