972: These Things Make Your App Feel Like Crap on Mobile

Summary of 972: These Things Make Your App Feel Like Crap on Mobile

by Wes Bos & Scott Tolinski - Full Stack JavaScript Web Developers

38mJanuary 21, 2026

Overview of 972: These Things Make Your App Feel Like Crap on Mobile

Wes Bos and Scott Tolinski list the UI/UX anti-patterns that make web apps feel inferior to native apps on mobile. They explain why these issues matter, give concrete fixes, and recommend tools and testing approaches so web developers can make their cross‑platform apps feel smooth, reliable, and less “janky.”

Key takeaways

  • Most “native vs web” complaints come from UX details (jank, layout shifts, scroll traps, slow feedback), not intrinsic platform limits.
  • Many problems are easy to fix with CSS, better rendering choices, caching, optimistic updates, and testing on real devices.
  • Test on real phones (and other people’s phones — kids, older relatives) and record first-time usage to spot friction you won’t find by shrinking a desktop browser.
  • Use observability tools (Sentry) and session replays to see real user interactions (rage clicks, dead clicks) and diagnose issues.

Common mobile issues (what to watch for)

  • Zooming inputs: mobile browsers auto‑zoom small text fields, producing odd zoomed pages after typing.
  • Accidental selection / pointer problems: double taps, 3D touch, text highlighting, and stray gestures.
  • Horizontal overflow: accidental body overflow causes side-scrolling and awkward interactions.
  • Jank / low or inconsistent FPS: choppy scrolling and animations.
  • Full-page refresh jank: blank white screens or color-scheme flashes during navigation.
  • Slow loading & blocking loaders: full UI stalls while waiting for network responses.
  • Non-instant mutations: actions with no immediate feedback (no optimistic UI).
  • Cumulative Layout Shift (CLS): elements popping into place and shifting visible content.
  • Address bar / viewport problems: mobile URL bar appearing/disappearing changes layout; 100vh issues.
  • Full-width scroll traps: embedded content (maps, iframes) capturing touch and preventing page scroll.

Practical fixes & recommendations

  • Inputs: set font-size >= 16px on form inputs for mobile to prevent auto-zoom.
    • Example: use a mobile media query → input, textarea { font-size: 16px; }
  • Disable selection/pointer interactions selectively:
    • Use user-select: none and pointer-events as needed on non-copyable elements (chips, buttons), but avoid blanket disabling (accessibility trade-offs).
  • Horizontal overflow:
    • Fix underlying element(s) causing overflow (wrap long words/links, use word-break/break-word).
    • Avoid blanket overflow-x: hidden unless you intentionally disable horizontal gestures.
  • Scrolling UI:
    • Use scroll-snap / overflow-x:auto / native scrolling strategies for carousels; keep it snappy.
  • Animations & jank:
    • Prefer transform/opacity animations (GPU-accelerated) over layout-changing properties (background-color on many elements is expensive).
    • Put frequently changing items into their own composited layer where appropriate.
  • FPS & consistency:
    • Aim for consistent frame rates (even if lower) rather than frequent drops — avoid heavy synchronous work during scroll.
    • DevTools: open FPS meter and rendering highlighter to spot repaint hotspots.
  • Avoid visible full-page refresh jank:
    • Implement an app shell / partial updates or show a smooth transition while waiting for server responses (prefetch/navigation caching).
  • Data & responsiveness:
    • Use local caching / client caching (TanStack Query/DB, SQLite strategies, local-first approaches) to make actions instant.
    • Implement optimistic UI for mutations and fallback handling when a request fails.
  • CLS:
    • Reserve space for images/ads/async content (width/height or aspect-ratio) and avoid late-injected banners that push content.
    • Fix hydration differences between server and client render to prevent content “dance.”
  • Viewport / address-bar:
    • Use new viewport units (DVH / SVH / LVH) to account for mobile browser chrome changes; add bottom padding for touch targets near address bars / home indicators.
    • Consider PWA / “Add to Home Screen” experience for a fullscreen app feeling that avoids the URL bar.
  • Scroll traps & embedded content:
    • Avoid traps: use explicit affordances to enter “map mode,” require two-finger pan by default, or provide a handle/overlay to prevent accidental capture.

Performance & debugging tips

  • Use DevTools:
    • FPS meter (Command/Ctrl + Shift + P → “Show FPS meter”), layer/highlight rendering to find repaints.
    • Profile long frames and identify expensive paint/layout/JavaScript.
  • Look for common pitfalls:
    • Excessive watchers/effect re-runs, transitions on many elements, large layout thrashing, heavy synchronous tasks on scroll/touch handlers.
  • Consistency > peak FPS: aim for a steady frame rate rather than fluctuating between 60 → 30 → 60.
  • Use session replay & analytics:
    • Tools like Sentry detect rage clicks / dead clicks (dead click ~ no UI reaction for ~250ms), and session replay helps reproduce the problem visually.

Tools & resources mentioned

  • Sentry (sentry.io): rage-click and dead-click detection, session replays, error and performance monitoring.
  • TanStack Query / TanStack DB: client caching and local-first approaches for faster UX and optimistic updates.
  • Browser DevTools: FPS meter, rendering/highlight layers, performance profiler.
  • New viewport units: DVH, SVH, LVH to handle mobile browser chrome.

Actionable checklist for mobile-friendly web apps

  • Test on actual phones (yours, family, others) and record first-time interactions.
  • Ensure mobile inputs use font-size >= 16px.
  • Reserve DOM space for async content (prevent CLS).
  • Use transform/opacity transitions; avoid painting-heavy properties on many elements.
  • Implement optimistic UI and local caching for frequently used data.
  • Avoid accidental horizontal overflow (wrap long links).
  • Add bottom padding for mobile toolbars / home indicator areas.
  • Audit embedded maps/iframes for scroll capture and provide proper affordance.
  • Use DVH etc. for full-height layouts; consider PWA install for fullscreen experience.
  • Instrument with Sentry or similar to capture rage-clicks, dead-clicks, replays, and performance issues.

Notable examples & anecdotes

  • OptumRx (example used repeatedly): redesign introduced severe jank, hydration/CSS/CLS issues, missing page titles, repeated loaders, and poor data caching — a demonstration of how even modern frameworks can ship a bad mobile experience.
  • Testing with kids/older relatives exposes many real-world interaction patterns (double taps, accidental zooms, unexpected gestures).

If you take one thing away: use your app on real mobile devices, instrument it, and address the small interaction/visual issues — most of the “web feels bad” complaints are fixable with attention to detail.