Skip to main content
Syntax

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

38 min episode · 2 min read

Episode

38 min

Read time

2 min

Topics

Design & UX, Software Development, Philosophy & Wisdom

AI-Generated Summary

Key Takeaways

  • Input Zoom Prevention: Set all input fields to 16 pixels or larger font size to prevent mobile browsers from automatically zooming when users tap form fields. Browsers zoom inputs smaller than 16px, leaving users stuck in a zoomed state with horizontal scroll after closing the keyboard. Use media queries to apply 16px specifically on mobile while maintaining smaller sizes on desktop.
  • Cumulative Layout Shift (CLS): Eliminate content jumping during page load by reserving space for dynamic elements like images, breadcrumbs, and banners before they render. Client-side hydration often causes multiple layout shifts as navigation elements and content populate sequentially. Use proper image dimensions, skeleton screens, and server-side rendering to prevent the page from shifting after initial paint, which creates a janky experience.
  • Viewport Height Units: Replace standard 100vh with dynamic viewport height (dvh) units to account for mobile browser address bars that appear and disappear during scrolling. Traditional viewport units cause content to extend beyond visible screen area when address bars are present. The dvh unit adjusts fluidly as browser chrome changes, while lvh and svh provide large and small fixed values for specific use cases.
  • Optimistic UI Updates: Make interfaces respond instantly to user actions by updating the UI before server confirmation, then rolling back only if the request fails. Native apps feel faster because they store data in local SQLite databases and sync in background. Implement local data caching with tools like TanStack Query to eliminate loading spinners and provide immediate feedback on button clicks and form submissions.
  • Frame Rate Consistency: Maintain consistent frame rates rather than chasing maximum FPS, as users notice dropped frames more than lower steady rates. Use Chrome DevTools command palette (Cmd+Shift+P) and type "FPS" to show the frames per second meter and identify performance bottlenecks. Transitions on background colors across many elements tank performance; use opacity transitions on pseudo-elements instead to maintain smooth 60fps scrolling.

What It Covers

Scott Tolinski and Wes Bos identify specific technical issues that make mobile web apps feel inferior to native apps. They cover input zooming, horizontal scrolling, text selection, layout shifts, loading performance, viewport units, and scroll traps. The hosts provide concrete CSS and JavaScript solutions developers can implement immediately to improve mobile web experiences.

Key Questions Answered

  • Input Zoom Prevention: Set all input fields to 16 pixels or larger font size to prevent mobile browsers from automatically zooming when users tap form fields. Browsers zoom inputs smaller than 16px, leaving users stuck in a zoomed state with horizontal scroll after closing the keyboard. Use media queries to apply 16px specifically on mobile while maintaining smaller sizes on desktop.
  • Cumulative Layout Shift (CLS): Eliminate content jumping during page load by reserving space for dynamic elements like images, breadcrumbs, and banners before they render. Client-side hydration often causes multiple layout shifts as navigation elements and content populate sequentially. Use proper image dimensions, skeleton screens, and server-side rendering to prevent the page from shifting after initial paint, which creates a janky experience.
  • Viewport Height Units: Replace standard 100vh with dynamic viewport height (dvh) units to account for mobile browser address bars that appear and disappear during scrolling. Traditional viewport units cause content to extend beyond visible screen area when address bars are present. The dvh unit adjusts fluidly as browser chrome changes, while lvh and svh provide large and small fixed values for specific use cases.
  • Optimistic UI Updates: Make interfaces respond instantly to user actions by updating the UI before server confirmation, then rolling back only if the request fails. Native apps feel faster because they store data in local SQLite databases and sync in background. Implement local data caching with tools like TanStack Query to eliminate loading spinners and provide immediate feedback on button clicks and form submissions.
  • Frame Rate Consistency: Maintain consistent frame rates rather than chasing maximum FPS, as users notice dropped frames more than lower steady rates. Use Chrome DevTools command palette (Cmd+Shift+P) and type "FPS" to show the frames per second meter and identify performance bottlenecks. Transitions on background colors across many elements tank performance; use opacity transitions on pseudo-elements instead to maintain smooth 60fps scrolling.

Notable Moment

The hosts tested whether native apps allow pinch-to-zoom on UI elements and discovered not a single native app supports it, yet nobody complains about accessibility. Users can increase text size through OS settings on both native and web platforms, making the common advice to never disable zoom on websites potentially misguided for app-like experiences.

Know someone who'd find this useful?

Episode Transcript

Your mobile apps might feel like crap. And we're gonna tell you what are the main things that make a mobile app feel worse than a native mobile app. All of our pet peeves, all of the things that web developers could be doing better to improve their web apps on mobile. My name is Scott Tolinski. I'm a developer from Denver. With me, as always, is Wes Bos. What's up, Wes? Hey. I I'm excited to talk about this because, like, I was talking to some people from, actually, from Google, and they're just like, like, why are everyone is still so hung up on, like, native being better? And there's some clear things like access to APIs and Sure. And whatnot. But I think, like, there's a lot of the reason why people like a mobile app better is simply just because it doesn't feel janky. And I I watch my kids use websites sometimes, and it's just like, oh my gosh. What have we done? You know? They're clicking the wrong thing. Yeah. They're three d touching everything. They're they're highlighting text by accident. It's just it's a nightmare. And these things are all fixable if you if you know what you're doing. So that's what we're gonna talk about today. That's right. And a lot of these things can be fixed with Sentry. This episode is presented by Sentry at sentry.io/syntax. I know you get two months for free. Use the coupon code tasty treat, all lowercase, all one word. But Sentry is really cool for a lot of these things like, rage click detection. Man, if you click a button a whole bunch of times, Sentry will alert you that, hey, your users are rage clicking this button and that's usually for a number of reasons. Your app is not responsive. Your app isn't, showing the user what it's doing. It's not making the button disabled while it's doing something. There's a number of reasons. As well. Do you know the difference between a dead click and a rage click, Scott? Tell me. A little trivia? School me. Speak on that. So a rage click is what you just expect explain. Right? People clicking over and over and over again. And a dead click is when somebody clicks something and there is no nothing happens after there's a certain threshold. I think it's, like, two hundred fifty milliseconds. So if there's no, like, UI that has has updated or there's no network detection, that has has been fired off, you know, there's you can't tell that something happened. That's that's called a dead click. So either literally nothing happened or you have like like we're talking about today, your UI sucks, and and you need to know that something's going on. And and maybe you don't have things wired up properly or your UI is is lacking. And the coolest part about all of this, you get access to a session replay which shows the …

Get the full transcript (7,352 words) + summary by email — free

One-time email with the complete transcript and AI summary of this episode. No account needed.

One email, no spam. We’ll also show you what SignalCast does.

Browse all Syntax transcripts →

You just read a 3-minute summary of a 35-minute episode.

Get Syntax summarized like this every Monday — plus up to 2 more podcasts, free.

Pick Your Podcasts — Free

Keep Reading

Books, tools, and gear mentioned in this episode

SignalCast may earn commission on purchases via these links.

Tools

  • Chrome DevToolsRecommended

    by Google

    Use Chrome DevTools command palette (Cmd+Shift+P) and type "FPS" to show the frames per second meter and identify performance bottlenecks.
  • TanStack QueryRecommended

    by TanStack

    Implement local data caching with tools like TanStack Query to eliminate loading spinners and provide immediate feedback on button clicks and form submissions.

company

  • by Sentry

    SPONSORS: [{"name": "Sentry", "url": "https://sentry.io/syntax"}]

More from Syntax

We summarize every new episode. Want them in your inbox?

Similar Episodes

Related episodes from other podcasts

Explore Related Topics

This podcast is featured in Best Cybersecurity Podcasts (2026) — ranked and reviewed with AI summaries.

Read this week's Software Engineering Podcast Insights — cross-podcast analysis updated weekly.

You're clearly into Syntax.

Every Monday, we deliver AI summaries of the latest episodes from Syntax and 192+ other podcasts. Free for one show.

Start My Monday Digest

No credit card · Unsubscribe anytime