Next.js: Just another framework?
About every 10 years, new technology emerges that brings about a change in the way we develop software. Is Next.js this new technology? Or is it just another framework that will be outdated a year from now? To provide a better answer to this question, in this blog post, we will take you on a journey through the history of the web.
The early days of the internet
In the early days of the internet, web-applications consisted of several documents, connected to eachother through links. When you visited a page with your browser, the browser would send a request to the server to get the page. The server would then find the html-page on its hard drive and send it back to the browser.
This was a very simple and relatively fast process, mainly because everything was static. Every user would get to see the exact same static page.
Is Next.js the solution for your project?
Next.js tries to bundle all the advantages of available web technologies. Therefore, there is a good chance that it will be a good match for your next project.
A bit more dynamic
Not long after that, everything became a bit more dynamic because the server had the ability to pre-process the HTML pages before sending them back to the client (the browser).
Each time the browser requested a page, the server would prepare the HTML based on user cookies or authentication headers, and then send a customized page back to the browser. This made it possible to build a unique experience for each user.
But something was still missing. While the pages were now dynamically generated on the server, the end user experience was still static.
An interactive experience
However, the language had enough potential to have an innovative effect on the user experience.
Ajax: a new game-changer
This change made it possible to build truly interactive applications for the web. However, many developers at the time had only a vague idea of what they were doing.
The start of modern frameworks
In 2011, a developer named "Misko Hevery" had had enough. The past 12 years had seen improvements in browsers' speed and functionality, but the way web applications were being developed was still based on the same Ajax method. There had been some help from jQuery, a library that made developing Ajax applications a bit easier, but that was about it. So, Misko developed Angular.js, a framework that brought about change.
HTML is good at describing static pages but falls short in handling dynamic content. Angular.js allowed developers to extend the syntax of HTML to overcome these limitations.
Angular.js paved the way for the development of React, a library that took things a step further.
React.js is innovative because it treats the visual layer as a function of the "application state." This means that as a developer, you only need to worry about the data in your application, and React will handle adapting the visual layer to it. This core idea was then wrapped in a component-based API, allowing developers to intuitively compose components.
All of this sounds great, but there was still a problem. React is great at what it's built for, but it doesn't care about anything else. However, few applications are satisfied with just a visual layer, and more is needed. As a developer, you needed a PhD in Computer Science to figure out how to make it useful.
A team at Facebook came up with Create-React-App, a tool that reduced setting up a production-ready React application to a single command. No more fussing with webpack configs or things like Babel. You could focus on building the application, rather than configuring it.
SPA (no, not the water)
Angular.js and React.js were built for one reason: they were optimized for building Single Page Applications (SPAs). Instead of making a request to the server every time a user visits a page, SPAs load all the necessary JS, CSS, and HTML on the first request. Any form of navigation or interaction that happens thereafter occurs on the client. If the SPA is developed according to best practices, this leads to a fast and intuitive app experience, guaranteeing a very good, "snappy" user experience. However, if those best practices are not followed properly, it can have the opposite effect.
- Downloading the entire bundle on the initial request enables good caching. Users can start using the application while offline and once the bundle is cached, less data will need to be fetched.
- While navigating through the application, an SPA only updates the necessary content instead of reloading the entire page. This results in a faster and more responsive application.
- For developers, SPAs offer faster development time, more and better debugging options, and out-of-the-box cross-platform compatibility.
- SPAs tend to enforce a larger "bundle size" (the amount of data that needs to be downloaded on the initial request). For users with slower internet connections, this means waiting longer for the application to load.
- In SPAs, data is typically requested on-demand. This can lead to an overabundance of loading spinners.
SPAs have their usefulness, but it's not always sunshine and rainbows.
Then what is the solution?
Next.js tries to provide a solution to this story by simplifying the way apps are developed, just like Create-React-App did. Not only that, but it also attempts to merge the way the web was originally developed with the new and innovative technology that is available.
Next.js combines the simplicity of the static documents with which it all began, the power of server-side dynamics, the composition capabilities of React.js, and the user experience that SPAs can offer. It does this while minimizing the trade-offs that each of these steps in the history of the web brought with it.
How does Next.js do this?
Next.js is a framework built on top of React.js. It appreciates React for what it is and ignores it for what it is not.
Just like with Create-React-App, you can set up a Next.js application with one command.
Adding a page is as simple as creating a file in the "pages" directory, in which you add a component that describes how that page should look.
Next.js will statically generate this page on the server (at build-time) and send it to the client on every request, as it used to be done. If you need data that already exists on the server (at build-time), Next.js can provide static pages based on this data, which can then be sent to the client on request.
If the page requires data that the server does not yet have during application build (data that may need to be calculated or assembled at runtime), Next.js offers several options. You can let Next.js assemble the page on the server when the request comes in, or you can fetch the data on the client, like a traditional SPA.
Next.js thus offers the flexibility to inject data into your application when you need it: at build-time, on the server, or while users use your application.
As an additional option, you can also statically build your applications, regenerate a page on request, and then offer it statically.
More interesting features!
Next.js ensures that each page in your application (each file in the pages folder) is split into its own bundle. Users only download what they need.
Automatic image optimization is another great feature in Next.js. Images are automatically served at a size suitable for the viewport in which they are viewed. They are also only loaded when they come into the viewport.
Since Next.js is not just a frontend framework, there is also the possibility of adding API routes. You can build the entire API of your application in Next.js. Each file in the pages/api folder is considered an API endpoint. It becomes a server-side bundle and has no impact on the client-side bundle size.