Introduction
This blog post is a bit of an amalgamation of a talk we gave on Optimising usage on Vercel, as well as snippets from our own code within Turbo Start Sanity. We wanted to get the content out there, as a reference point as well as a cheeky way of capitalising on some nice SEO for dropping thousands of characters worth of Next.js code.
Generic takeaways from Next.js
Some top-level advice I would advise following is to try to avoid use client
until strictly necessary. If you have to use it, make it so that it's a smaller part of a component, rather than essentially wrapping a good chunk of your app within a client component. This differs if you're building something like Linear where it's almost all client side, and very dynamic.
Alongside this, we would emphasise that more than ever, it's worth jumping on the Tailwind CSS bandwagon. Because of the above, you really don't want something heavy like Material UI, as it's going to tank performance, especially as your app scales.
Moreover, if you're thinking of building an application, you probably want us to be
Key Concepts in Next.js 15
Next.js 15 introduces several new features and improvements that enhance data fetching capabilities. These include server components, improved caching strategies, and more.
Server Components
Server components allow you to render parts of your application on the server, reducing client-side JavaScript and improving load times.
Fetching Patterns
Route Segment Config for Cache Control
Request-Level Cache Control (New in Next.js 15)
On demand
Advanced Caching Techniques
Parallel Data Fetching
Suspense for progressive loading
Error Handling and Fallbacks
Error Boundary at the Route Level
Handling Errors with Error Boundaries per Component
Type-Safe Error Handling with tryCatch Pattern
Error handling is a critical aspect of robust data fetching. Let's implement a type-safe utility function that elegantly handles asynchronous operations:
Using this pattern in your data fetching functions:
- This pattern has several advantages:
- Type safety with generics ensures proper type inference
- Consistent error handling across the application
- No try/catch blocks cluttering component logic
- Clear distinction between successful and error states
- Can be extended to include specific error types
You can also create specialized variants for specific use cases:
Working with Sanity CMS
Typed Queries with GROQ
Optimized Sanity Client
Next.js 15 Performance Features
Partial Prerendering (PPR)
React Cache with Infinite Nested Component Trees
Background Prefetching and Preloading
Headers and Edge Optimization
Custom Cache-Control Headers
Edge Runtime for Global Performance
Implementing ISR in Next.js 15
Time-based Revalidation
On-Demand Revalidation with Webhooks
Measuring Performance
Real User Monitoring with Vercel Analytics
Server Timing for Request Analysis
Image Optimization with Vercel
Next.js 15 with Vercel provides powerful built-in image optimization capabilities that significantly improve Core Web Vitals and user experience.
Configuring Next.js Image Optimization
Advanced Image Loading Strategies
Integrating with Sanity CMS
Runtime Optimization with Automatic Webp/AVIF Conversion
Vercel's Edge Network automatically serves optimized images in modern formats: