In the era of modern web development, we often ask ourselves: what's the best way to navigate between pages?
By "best," I mean providing a user experience that's as smooth and continuous as native apps have trained us to expect.
If you're a developer working with Next.js, you've probably noticed several features that support navigation.
You're likely using the next/link component for client-side navigation, similar to a single-page application.
And if you're staying current, you might have heard about exciting new web platform features like Speculation Rules and CSS View Transitions.
With all these options available, I wanted to answer a simple question:
What's the optimal way to navigate between pages in a Next.js application?
The Experiment
To answer this question, I built a comparison project testing different navigation strategies:
- Standard HTML navigation: Traditional anchor tags. Experiment link
- Next.js SPA navigation: Client-side routing. Experiment link
- Speculation Rules + CSS View Transitions: Experiment link
- Speculation Rules + Next.js Loading UI: Experiment link
- Quicklink + CSS View Transitions: Experiment link
- Quicklink + Next.js Loading UI: Experiment link
Source Code: https://github.com/ale-grosselle/view-transition-comparison
Demo homepage: https://view-transition-comparison.vercel.app/
Test Case Setup
The experiment simulates a real-world e-commerce scenario:
- A listing page displaying multiple products
- Product detail pages that load when clicking an item
- Products stored locally with a simulated 500ms loading delay to make differences visible. You can find the data layer implementation here:
src/lib/api.ts
How I Measured Performance
Beyond "my personal" visual observation, I used three key metrics to evaluate user experience:
1. TTFB (Time To First Byte)
The standard web metric measuring how long it takes to receive the first byte of data after requesting a page.
2. Transition Time (Custom Metric)
This measures the actual perceived loading time from the user's perspective:
- On
beforeunload, we store the current timestamp in a cookie (src/app/layout.tsx) - On the new page load, we calculate:
Date.now() - unloadTime - Implementation:
src/components/TransitionTracker.tsx
3. Skeleton Load Time (Custom Metric)
For tests using Next.js loading states, this measures navigation continuity:
- We record when the skeleton/loading component appears (
app/layout.tsx) - We calculate:
skeletonRenderTime - unloadTime - This shows how quickly users get visual feedback that navigation is happening
All metrics are displayed in the top-right corner of detail pages during testing

Test Conditions
All measurements were performed with:
- Network: Fast 4G throttling in Chrome DevTools
- CPU: 4x slowdown
- Browser Cache: Enabled
- 5 runs per strategy for statistical validity
Results & Analysis
Strategy 1: Standard HTML Navigation
Results:
Average Transition Time: 1,555ms
Average TTFB: 37.6ms
This is our baseline: traditional full-page reloads.
Nothing fancy, but it's the most reliable approach when dealing with complex external scripts, analytics, and third-party widgets.
Strategy 2: Next.js SPA Navigation
Results:
No page reload - instant content updates
The smoothest experience by far. Navigation feels instant because we never reload the page.
Important Considerations:
Memory Leaks: In a true SPA, memory leaks accumulate over time. In multi-page apps, each navigation "resets" memory.
Third-Party Scripts: Many external scripts (analytics, widgets, GTM) rely on page load events. These won't fire in a SPA, potentially breaking functionality.
SEO Metrics: Tools like Google PageSpeed Insights measure full page loads. SPA navigation bypasses these measurements after the initial load.
Strategy 3: Speculation Rules + CSS View Transitions
Implementation:
- Speculation Rules:
components/SpeculationRulesScript.tsx - View Transitions:
view-transition.css
Results (When Prefetched):
Average Transition Time: 970ms
Average TTFB: 3.2ms
This is where it gets exciting! Speculation Rules allow the browser to prefetch or prerender pages before users click.
Combined with CSS View Transitions, you get smooth, animated page changes.
I used prefetch with "moderate" eagerness rather than prerender. While prerender is more aggressive and faster, it loads entire pages in the background, which can be resource-intensive.
You can see the full implementation in components/SpeculationRulesScript.tsx.
User Experience:
- When prefetched: Near-instant with beautiful transitions
- When not prefetched: Still smooth with nice animations
Browser Support: Chrome 121+ and Edge (limited)
You can verify prefetching in Chrome DevTools:
Strategy 4: Speculation Rules + Next.js Loading UI
Results (When Prefetched):
Average Transition Time: 989ms
Average Skeleton Load: 127ms
Average TTFB: 3.4ms
This combines Speculation Rules with Next.js Loading UI, showing skeleton screens while content loads.
The Skeleton Load metric is crucial here, it shows navigation happens within ~127ms, giving users immediate feedback.
User Experience:
- When prefetched: Extremely smooth with instant skeleton feedback
- When not prefetched: Still responsive, skeleton appears quickly (<300ms)
My personal favorite for real-world applications.
Strategy 5 & 6: Quicklink Library
📺 View Transitions Demo | 📺 Loading UI Demo | 💻 Code
Quicklink is a library that prefetches links when they enter the viewport. I tested it as a cross-browser alternative to Speculation Rules.
Results (Quicklink + View Transitions):
Average Transition Time: 1,627ms
Average TTFB: 33.4ms
Results (Quicklink + Loading UI):
Average Transition Time: 811ms
Average Skeleton Load: 320ms
Average TTFB: 37.4ms
Verdict: While Quicklink has better browser support, it didn't match Speculation Rules' performance in my tests.
The loading UI variant performed better than view transitions, but still showed higher skeleton load times.
Possible reasons:
- Configuration may need optimization
- Viewport-based prefetching vs. browser-native speculation
- Additional JavaScript bundle overhead
🎬 Conclusion & Recommendations
After extensive testing with real-world metrics, here's what I learned about page navigation in Next.js:
My Recommendation Hierarchy
🥇 Speculation Rules + Loading UI - For Chrome/Edge users with Next.js, this is the winner. You get dramatic performance improvements with native browser support and clear user feedback through skeleton screens. This is my personal favorite for production applications.
🥈 Next.js SPA Navigation - Perfect for simple, controlled flows like thank you pages, wizards, or internal tools. Provides instant transitions and the smoothest experience, but watch out for memory leaks in complex apps and avoid if you're using external scripts or tracking pixels.
🥉 Speculation Rules + View Transitions - Deliver a smooth, polished, app-like experience with elegant animations. If you’re not using Next.js, this is probably the best option.
Standard HTML Navigation - Your fallback for maximum compatibility and when dealing with complex third-party integrations. Sometimes the traditional approach is the most reliable.
The web platform is evolving rapidly, and if your analytics show significant Chrome/Edge usage, these modern navigation strategies can transform your user experience with surprisingly little code.
🔗 Try It Yourself
- Live Demo: https://view-transition-comparison.vercel.app/
- Source Code: https://github.com/ale-grosselle/view-transition-comparison
I encourage you to test each strategy with your own use cases. Use Chrome DevTools' network throttling (Fast 4G) and CPU slowdown (4x) to see the differences clearly.
What's your preferred navigation strategy? Have you experimented with Speculation Rules or View Transitions? Share your experiences in the comments!
📚 Further Reading
- Next.js: Linking and Navigating
- Speculation Rules API
- CSS View Transitions
- Next.js Loading UI
- Quicklink Library
Testing environment: Fast 4G network, 4x CPU throttling, Chrome DevTools, cache enabled. All measurements represent averages of 5 runs per strategy.

Top comments (4)
I feel they should somehow bring SPA + View transition somehow, it would be a blast instant and also that smooth transition would be cherry on top...(I could be dumb talking abt that 😅)
Just to clarify, when you say "they”" do you mean the article or the Next.js / Chrome team? 😊
Not dumb at all, a true SPA + View Transitions combo would be a game changer: instant navigation with that smooth, native feel users love.
BUT as I wrote in the article, watch out for memory leaks in complex apps and avoid if you're using external scripts or tracking pixels.
I mean devs in general !!! But great article though !! 🙌
Some comments may only be visible to logged-in visitors. Sign in to view all comments.