The Art of Subtraction: How Adaptive Quality Creates a Better Experience for Everyone

There is an implicit promise baked into every application we build: that it will be a useful, pleasant, and reliable tool.

Back to all articles

There is an implicit promise baked into every application we build: that it will be a useful, pleasant, and reliable tool.

Yet, in the race for feature velocity and stunning visual polish, it’s dangerously easy for that promise to fracture. We build on powerful machines, test on the latest flagship phones, and marvel at the fluid animations and complex, soft-cast shadows. We then ship that idealized experience to the entire world, forgetting that a vast portion of our audience interacts with our work on hardware that is years old, network-constrained, and far less forgiving.

The Cost of Ignoring Reality

This isn’t a minor oversight; it’s a fundamental empathy gap. When an application stutters, drains a battery, or crashes on a mid-range or older device, we haven’t just delivered a poor user experience. We have failed to respect the user’s reality. We have prioritized our own ideal development environment over their everyday context, effectively telling them their hardware isn’t good enough for our software.

The true measure of sophisticated engineering and design isn’t just what an application can do on powerful hardware; it’s how gracefully it behaves when faced with constraints. This philosophy is about intentionally planning for a less-than-ideal world. It’s a commitment to ensuring that the core function of an application remains robust, responsive, and dignified, no matter the device. It is the art of strategic subtraction.

“80–90% of the end-user response time is spent on the front-end. Start there.” — Steve Souders
“80–90% of the end-user response time is spent on the front-end. Start there.” — Steve Souders

The Myth of the “Average” Device

There’s a strong temptation in development to optimize for an imaginary middle ground, a mythical “average” device. This often leads to an experience that isn’t truly great for anyone: it underutilizes the power of high-end phones and overwhelms the capabilities of lower-end ones.

The core principle behind a more respectful approach is the acknowledgment that there is no “average” user. The person using a top-of-the-line phone deserves the rich, fluid experience their device was made for. But the person using a three-year-old budget phone — or a flagship from five years ago — deserves something even more important: an application that is fast, reliable, and doesn’t make them feel punished for their hardware. This isn’t about equality of features; it’s about equality of respect for the user’s time, patience, and battery life.

Building Escalators, Not Elevators

This challenge is best addressed by a philosophy known as “graceful degradation.” It’s an approach that prioritizes the core experience above all else. Think of it like this: when an elevator loses power, it becomes a useless metal box. When an escalator loses power, it becomes a set of stairs. It’s less convenient, but it still performs its core function — it gets you from one floor to another. Our applications should be escalators.

This means building a solid, functional baseline experience that works for everyone. Then, for more capable devices, we can layer on enhancements — richer animations, complex shadows, higher-resolution assets. This is distinct from “progressive enhancement,” which typically starts with a minimal HTML base and adds CSS and JavaScript, but the spirit is the same: build a resilient foundation first.

The goal is to ensure that when a feature is subtracted due to hardware limitations, the application doesn’t break; it simply becomes a more streamlined version of itself.

“We have to design for the real world, not the blue-sky, best-case-scenario world.” — Karen McGrane
“We have to design for the real world, not the blue-sky, best-case-scenario world.” — Karen McGrane

The Adaptive Quality System

A philosophy is only useful if it can be put into practice. An “Adaptive Quality System” is a concrete way to implement graceful degradation. It’s an automated system designed to ensure the application runs smoothly on the widest possible range of devices by adjusting visually expensive elements.

Game developers mastered this decades ago. They know that shadows, particles, and complex animations are often the most computationally expensive parts of rendering a scene, yet have a relatively low impact on core usability. By scaling these elements down or removing them, you can achieve the biggest performance gains with the most predictable trade-off.

A Three-Tiered Approach

The system’s logic can be intentionally straightforward, designed for efficiency and predictability:

  1. Gather Intelligence: When the application starts, it performs a quick, low-overhead check of the device’s capabilities. This doesn’t need to be exhaustive. On Android, it can check the OS (SDK) version; on iOS, it can check the model generation. These are reliable proxies for the hardware’s general power.
  2. Make an Authoritative Decision: Based on predefined thresholds, the system assigns a single, app-wide quality level for the entire session: High, Medium, or Low. Making this decision once at startup prevents flickering or inconsistent experiences during use, providing a stable performance target.
  3. Apply Rules System-wide: This is where a component-driven framework becomes a superpower. Instead of asking every developer to remember to tweak every button, card, and dialog, the adaptive logic is built directly into the core components themselves.
“Simplicity is about subtracting the obvious, and adding the meaningful.” — John Maeda
“Simplicity is about subtracting the obvious, and adding the meaningful.” — John Maeda

The Power of a Component-Driven Framework

This strategy becomes truly scalable when an entire application is built from a common set of “smart” components. When the logic for adaptation is centralized, ensuring a graceful user experience on all devices becomes an automatic benefit, not a constant, manual effort. A developer using a standard AppCard component doesn’t have to do anything special; the component is already “quality-aware.”

A ‘Smart’ Component in Action

Consider this conceptual example in Flutter. The component contains its own logic to check the global quality level and render its appearance accordingly.

// Conceptual Example of a "smart" component
class AppCard extends StatelessWidget {
  final Widget child;
  const AppCard({super.key, required this.child});

@override
  Widget build(BuildContext context) {
    // 1. The component checks the globally-set quality level.
    final quality = AdaptiveQuality.currentLevel;
    // 2. It adapts its own appearance based on that level.
    switch (quality) {
      case QualityLevel.High:
        // Renders with a rich, detailed shadow.
        return Material(elevation: 8.0, child: child);
      case QualityLevel.Medium:
        // Renders with a simpler, less expensive shadow.
        return Material(elevation: 2.0, child: child);
      case QualityLevel.Low:
        // Renders with no shadow, preserving the core experience
        // with a clean border for definition.
        return Container(
          decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
          child: child,
        );
    }
  }
}

When a developer uses <AppCard>, they automatically get this adaptive behavior. The logic is defined once, in one place, and propagated across the entire application. This is the essence of a maintainable and scalable design system.

You can extend this logic beyond shadows to animations, where on QualityLevel. Low, animation durations could be automatically reduced to zero, making transitions instant and saving precious processing cycles.

From Performance to Inclusion

This framework-level approach provides significant advantages that extend beyond just a smoother frame rate.

  • Broader Accessibility: The most crucial benefit is that the app delivers a good experience on a much wider range of hardware. Users on older or less expensive phones are not treated as an afterthought. They get a functional and responsive app, which is a form of technical inclusion.
  • Improved Perceived Performance: For users on lower-end devices, the app feels faster. By simplifying complex rendering and disabling non-essential animations at a systemic level, the interface is unburdened, leading to smoother scrolling and quicker screen transitions.
  • Reduced Battery Consumption: The reduced rendering workload on Medium and Low settings leads to lower power draw and helps conserve battery life — a valuable benefit for any mobile user, especially one whose device has an aging battery.
  • Enhanced Developer Experience: Centralizing the logic makes the developer’s job simpler and less error-prone. Instead of dozens of developers making ad-hoc performance decisions, the “right way” becomes the “easy way.” The framework handles the complexity, allowing teams to focus on building features, not performance-tuning every single widget.
“Performance is about respecting the people who use your site, no matter what device or connection they might be on.” — Tim Kadlec
“Performance is about respecting the people who use your site, no matter what device or connection they might be on.” — Tim Kadlec

Limitations and Future Horizons

This startup-based approach is a pragmatic compromise. It solves the vast majority of performance issues with a simple, robust, and predictable system. But the world of real-time graphics, especially in gaming, demonstrates a deeper spectrum of possibilities for where this philosophy could lead.

  • Adaptive Image & Asset Quality: A logical next step is to serve different asset qualities. An app with heavy image content could serve lower-resolution images to low-tier devices, saving both memory and network bandwidth. This mirrors how games use lower-quality textures to stay within a strict memory budget.
  • Scaling Complex Visual Effects: The system could be taught to manage advanced effects like particle systems (e.g., for celebrations), complex shaders for glass or glossy surfaces, or motion blur. A truly comprehensive system would build rules to simplify or disable these “cinematic” extras on less powerful hardware.
  • Real-time Dynamic Adaptation: The most advanced game engines use Dynamic Resolution Scaling (DRS), which adjusts rendering quality in real-time based on system load to maintain a target frame rate. The system described here makes its decision once at startup. A truly dynamic system could adapt to changing conditions during a user’s session, for example, by lowering the quality if the device starts to overheat or if the battery drops to a critical level. This is more complex to implement but represents the ultimate form of respecting the device’s current state.

The Final Payoff: Designing with Empathy

An Adaptive Quality System, implemented at the framework level, isn’t just a technical solution; it’s a statement of values. It asserts that an application’s design is not finished when it looks good on a developer’s high-end monitor. It’s finished when it feels good to a person on a crowded bus, using a budget phone with 10% battery left.

It’s a commitment to the idea that the best products don’t just offer power to those who can afford it. They offer dignity and respect to everyone.

By baking graceful degradation into the very components we build with, we create more than just software. We create resilience, we build trust, and we ensure our technology serves the many, not just the few.

“The best products don’t just empower users, they also get out of their way.” — Scott Belsky
“The best products don’t just empower users, they also get out of their way.” — Scott Belsky

Sources:

  1. Dynamic Resolution Scaling (DRS) Implementation Best Practice:
    https://www.eurogamer.net/digitalfoundry-2020-how-modern-games-use-dynamic-resolution-scaling
  2. Advanced Graphics Techniques Tutorial: The Elusive Frame Timing: A Case Study for Smoothness Over Speed:
    https://www.gdcvault.com/play/1025407/Advanced-Graphics-Techniques-Tutorial-The
  3. A List Apart: Responsive Web Design:
    https://alistapart.com/article/responsive-web-design/
  4. Resilient Web Design by Jeremy Keith:
    https://resilientwebdesign.com/chapter1/
  5. Smashing Magazine: Progressive Enhancement: What It Is, And How To Use It? : https://www.smashingmagazine.com/2009/04/progressive-enhancement-what-it-is-and-how-to-use-it/
  6. Unreal Engine Documentation: Dynamic Resolution:
    https://dev.epicgames.com/documentation/en-us/unreal-engine/dynamic-resolution-in-unreal-engine
  7. Adaptive serving based on network quality:
    https://web.dev/articles/adaptive-serving-based-on-network-quality
  8. Luke Wroblewski: Mobile First: https://www.lukew.com/resources/mobile_first.asp
  9. The forgotten benefits of “low tech” user interfaces:
    https://uxdesign.cc/the-forgotten-benefits-of-low-tech-user-interfaces-57fdbb6ac83
  10. Atomic Design by Brad Frost: https://atomicdesign.bradfrost.com/

Final Word 🪅

Illustration from article
Share this article

Your feedback is essential to us, and we genuinely value your support. When we learn of a mistake, we acknowledge it with a correction. If you spot an error, please let us know at blog@saropa.com and learn more at saropa.com.

Originally published by Saropa on Medium on June 9, 2025. Copyright © 2025