Direct answer
Replace a physical device lab with three cheaper layers that each catch a different class of bug: real usage data to decide which devices and browsers actually matter, a cloud device or browser service for spot-checking the handful that do, and automated visual regression in CI so a human never has to manually re-check something that hasn't changed.
Step 1: get the data before guessing
Pull real device, browser, and viewport breakdowns from your own analytics, not generic market-share numbers, since your users' actual mix can differ sharply from the general web. This turns "test everything" into an evidence-based, short support matrix.
Step 2: tier your testing effort by that data
- Tier 1 (the bulk of real traffic): full manual passes on the key user flows, using a small number of real devices, your own or a colleague's actual phone for the top device or two, and a laptop for desktop.
- Tier 2 (a meaningful but smaller slice): automated-only coverage, visual regression plus a Lighthouse check, with manual review only if automation flags a real difference.
- Tier 3 (the long tail): accept graceful degradation rather than dedicated testing; chasing every combination in existence burns time nobody will benefit from.
Step 3: low-cost real-device coverage for the edge cases
Use a cloud device farm's free or low-cost tier for the specific old browser or unusual device your data says matters, rather than paying for broad, indefinite access nobody will fully use.
Step 4: automate the repeatable part
Visual regression snapshots per breakpoint on every pull request for key pages and shared components, an automated accessibility scan, and a performance budget check (Core Web Vitals) in CI. None of this should consume human QA time on every release; it should only surface a human when something actually changed.
Step 5: prioritize by risk, not by breadth
Put manual attention on shared design-system components first, since a bug there ships on every page that uses it, and on the highest-traffic or highest-revenue flows (checkout, sign-up), not evenly across every screen in the product.
Worked example
Suppose analytics show: 55% mobile Safari (recent iOS), 20% mobile Chrome (Android), 15% desktop Chrome, and 10% everything else, including a small enterprise slice on an older browser. Tier 1 becomes iOS Safari, Android Chrome, and desktop Chrome (85% of traffic combined): a full manual pass on three real devices, one iPhone, one mid-range Android phone, one laptop, plus automated visual regression on every pull request. Tier 2 is the remaining 15%: an automated cross-browser script run covering the next several browser and OS combinations, with a manual look only if the script flags a visual diff.
Trade-offs and pitfalls
100% device coverage is a false goal; chasing it spends QA time on combinations almost nobody uses instead of the ones that matter. A purely automated, emulator-only approach misses real interaction issues, touch-gesture conflicts, or an on-screen keyboard covering an input field, that only show up on physical hardware, so don't drop manual testing entirely. A closely related pitfall is assuming a resized desktop browser window is equivalent to a real phone; real mobile browsers have genuine behavioral differences (viewport height changing as browser chrome appears or hides, momentum scrolling) that a desktop emulation will not reproduce.