The move to high-refresh-rate displays on phones has completely changed user expectations, forcing us all to rethink how we design mobile UX. People now expect silky-smooth animations and zero lag, which means hitting 120Hz or even 144Hz is becoming the baseline, not a bonus. So, how do we actually use this tech to build a better app and not just burn battery?
Key Takeaways
- Focus on your motion design and animation curves to create perceived fluidity. The raw frame rate isn’t the whole story.
- Use the OS-provided variable refresh rate (VRR) APIs, like Android’s `setPreferredDisplayModeId`, to get great performance without killing the battery.
- Run A/B tests on real devices with different refresh rates to find the right animation timings and feedback that work for all your users, not just the ones with the latest phone.
- Integrate haptic feedback by syncing tactile bumps and clicks with on-screen actions to make the whole experience feel more responsive and physical.
1. Understand Device Capabilities and Target Refresh Rates
Before you touch a line of code or a design file, you’ve got to know what phones your users are actually carrying. Not every device has a high-refresh-rate screen, and even on the ones that do, the behavior is wildly inconsistent. Some Android phones might offer 120Hz, while others will flip between 60Hz and 90Hz to save power. Pro Tip: Don’t just build for the fanciest screen. It’s tempting, but a huge chunk of your audience is probably still on a 60Hz device, and your design has to feel good for them, too. A common trap is assuming all 120Hz panels are created equal. They’re not. A top-tier Samsung Galaxy S25 Ultra at 120Hz renders things very differently from a mid-range phone that claims the same spec, because panel quality, processing power, and OS tweaks matter. The first step is to dig into your analytics. Use something like Firebase or your own custom telemetry to find out the dominant refresh rates across your active user base. If you see that 60% of your users have phones that can do 90Hz or better, that’s a pretty clear signal for where you should be focusing your efforts. A 2026 report from DisplayMate Technologies noted that the average refresh rate on premium phones has jumped by 35% in just two years, so the market is definitely moving. You need to define your minimum and optimal refresh rate targets. A simple navigation transition might be fine at 60Hz, but it feels truly slick at 120Hz. The idea is to make sure the experience is solid for everyone, not just perfect for the few at the very top.
2. Optimize Animation Durations and Easing Curves
This is where the real work is. A higher refresh rate gives you more frames to play with, so your animations can be quicker and smoother without looking choppy. A big mistake is just taking your old 60Hz animation timings and using them on a 120Hz screen. If you do that, the animation just feels wrong, too fast, almost frantic. The goal is perceived fluidity. An animation that feels right at 300-400ms on a 60Hz screen can often be shortened to 200-250ms on a 120Hz display, or even less for small micro-interactions. You’re looking for that sweet spot where it feels instant but the user can still track what happened. Easing curves become even more important here. A linear animation feels robotic no matter how many frames you’re pushing. Using curves like `ease-in-out` or a custom cubic Bezier gives motion a more natural, physical quality. For a common UI element like a slide-out menu, adding a slight overshoot and bounce makes the interaction feel more satisfying and tangible. In Android, this means getting familiar with `ObjectAnimator` and its `TimeInterpolator` instances. On the iOS side, `UIViewPropertyAnimator` gives you really fine-grained control over timing curves. I’ve found that a `CubicBezierInterpolator` with control points around `(0.4, 0.0, 0.2, 1.0)` is a great starting point for most UI transitions, as it starts fast but decelerates smoothly. Screenshot Description: An Xcode screenshot showing a `UIViewPropertyAnimator` with a custom `timingParameters` using `UISpringTimingParameters` to achieve a bouncy animation for a modal presentation, explicitly setting `dampingRatio` to 0.7 and `initialVelocity` to 0.5.
3. Implement Variable Refresh Rate (VRR) APIs
Modern phones have variable refresh rates, and this is a lifesaver for balancing a slick UI with decent battery life. Instead of being locked at 120Hz all the time, VRR lets the OS adjust the refresh rate based on what’s on screen. Reading a static article? The screen can drop to 10Hz or even 1Hz. Scrolling through a feed or playing a game? It jumps right back up to 120Hz. For Android devs, the `setPreferredDisplayModeId` API (in Android 11+) is your best friend. Developers can programmatically request a specific display mode. For instance, if your app is showing a fast-paced game, you might request `Display.Mode.REFRESH_RATE_120`. Once the user pauses, you can switch back to the default. Pro Tip: Don’t just set it and forget it. You need to actively manage the refresh rate based on what the user is doing. This is the difference between a thoughtful implementation and a lazy one. A classic mistake is cranking up the refresh rate and then failing to revert when it’s not needed. This just torches the battery for no good reason, and users will notice their phone dying faster, even if they don’t know why. On iOS, developers have less direct control. The system handles ProMotion display adjustments pretty intelligently on its own. Your job is to design animations that don’t fight the system. Avoiding constant, unnecessary redraws or heavy CPU-based animations for static screens will give the OS the room it needs to lower the refresh rate and save power. Screenshot Description: An Android Studio screenshot displaying Java code within an `Activity` class, showing the use of `Window.setPreferedDisplayModeId` to request a 120Hz display mode when a game view is active, and then resetting it when the game is paused.
4. Use Haptic Feedback for Enhanced Responsiveness
Smooth visuals are one thing, but pairing them with haptic feedback makes an interface feel solid and real. When you combine them well, a subtle vibration can make an interaction feel even more direct and satisfying. Think about a button press that not only animates instantly but also gives you a crisp little tap. We’re not talking about just making the phone buzz. It’s about designing specific haptic patterns that match the visual feedback. A successful action might trigger a different haptic response than a failed one, creating a richer experience. On iOS, you have `UIImpactFeedbackGenerator` and `UINotificationFeedbackGenerator`, which give you pre-canned effects (light, medium, heavy, success, warning, error). Android has `Vibrator` and `HapticFeedbackConstants` for the same purpose. The trick is to be subtle. If you use haptics everywhere, they just become annoying noise. Pro Tip: Test your haptics with real users. What feels “crisp” to you might be “jarring” or “annoying” to someone else. Tweak the intensity and duration based on feedback. For a drag-and-drop interaction, you could trigger a `UIImpactFeedbackGenerator` with a `light` intensity when the user first picks up an item. Then, when they drag it over a valid drop target and it snaps into place, a `medium` tap could confirm the action. This kind of sensory feedback, combined with the smooth 120Hz motion, makes the interaction feel much better than visuals alone could. Screenshot Description: A Swift code snippet demonstrating the instantiation and use of a `UIImpactFeedbackGenerator` with `.light` style, triggered upon a user tapping a UI element to provide subtle haptic confirmation.
5. Conduct Rigorous Performance Testing and A/B Testing
None of this theory matters if you don’t test it on a bunch of real phones. You have to be rigorous. Use tools like Android’s `Profile GPU Rendering` or Xcode’s `Core Animation Instrument` to hunt down performance problems. You’re looking for dropped frames, high CPU/GPU load, and memory issues. A high refresh rate is useless if your app can’t actually draw frames fast enough to keep up. A/B testing is just as important for your design decisions. Test two different animation timings for a key transition, one optimized for 120Hz and one that’s a bit slower. See what users actually prefer by measuring satisfaction or task completion times. You might learn that users on 90Hz devices prefer a duration that’s somewhere between your 60Hz and 120Hz versions. When I’m profiling performance, I’m not just chasing the highest FPS number. Consistency is what matters. A rock-solid 90 FPS feels infinitely better than a janky 120 FPS that frequently drops frames down to 40. What users perceive as “smooth” is all about that consistency. Screenshot Description: A screenshot of Android Studio’s `Profile GPU Rendering` tool showing a green bar consistently below the 16ms threshold, indicating smooth rendering at 60Hz, alongside an explanation of how to interpret the colored bars for frame rendering times. High-refresh-rate screens give us a huge opportunity to build more intuitive and satisfying apps. If you’re smart about your animations, use the VRR APIs, add some well-placed haptics, and test everything obsessively, you can create an experience that really stands out from the crowd.
What’s a “high-refresh-rate display” for a phone?
It’s a screen that updates its image more than the old standard of 60 times per second (60Hz). You’ll see common rates like 90Hz, 120Hz, and sometimes even 144Hz. This means the screen can show more frames per second which makes all motion, like scrolling and animations, look much smoother and feel more responsive.
Do high refresh rates kill my phone’s battery?
They definitely use more power than a 60Hz screen. That’s why modern phones have variable refresh rate (VRR) tech. It’s smart enough to lower the refresh rate way down when you’re looking at something static (like reading this text) and crank it back up only when motion is happening, which helps save a lot of battery life.
Should my animations be different for 90Hz vs 120Hz?
Maybe, but the difference is subtle. You can get away with slightly faster animations at 120Hz, but the jump from 60Hz to 90Hz is far more noticeable to users than the jump from 90Hz to 120Hz. A better approach is to design for a range of high refresh rates and test on a few different devices to find a sweet spot that feels good on all of them.
What tools can I use to find UI performance problems?
Every platform has its own tools. For Android, you can enable “Profile GPU Rendering” in the Developer Options to get a quick visual on your frame times, and the profiler in Android Studio lets you dig deeper. For iOS, Xcode’s Instruments has templates like “Core Animation” and “Game Performance” that are perfect for spotting dropped frames and other rendering issues.
Can I force my app to run at a specific refresh rate?
On Android, yes. Since Android 11, you can use the `Window.setPreferredDisplayModeId` API to request a specific refresh rate. This is great for a game that needs max performance or for an e-reader app that wants to save battery. iOS doesn’t give you this direct control. It prefers to manage the ProMotion display’s refresh rate automatically based on what you’re showing on screen.