https://www.causal.app/blog/next-js [61f289532e][623d980c68] We raised a $20m Series A led by Coatue + Accel! Click here to read the announcement. [61e96266d5] Causal for Finance Causal for FP&ACase Study: ClassDojoCase Study: Marley SpoonCase Study: PrefectCase Study: Inscribe TemplatesIntegrationsPricingCareersLoginCreate accountBook a demo LoginCreate accountBook a demo Engineering How We Improved React Loading Times by 70% with Next.js By switching from CRA to Next.js, we reduced our initial page load times by 70% and unlocked a new level of developer experience. Causal Causal October 23, 2022 Causal is a multidimensional spreadsheet that's capable of handling everything from basic arithmetic all the way up to billion-calculation financial models. The Causal frontend was built with Create React App (CRA) in 2019, and it served us well - it required minimal initial setup and allowed us to iterate quickly. As our customers grew in size and complexity, and performance became more of a concern, we reached the limits of what CRA was designed to support. Most importantly, CRA doesn't natively support route splitting across multi-page apps, so our page load times were frustratingly slow. To solve these problems, we switched to Next.js, reducing our initial page load times by as much as 70% and unlocking a new level of developer experience. Contents What is Next.js? Next.js is a framework that comes with build tools and runtime libraries for creating rich React applications. It has the same functionality as CRA, but also includes built-in support for key functionality that CRA is missing: page routing, intelligent pre-loading based on page contents, and hybrid static & server-side rendering. Migrating from CRA to Next.js In mid 2022, we determined that the benefits of migrating from CRA to Next.js would be worth the time investment. We were particularly excited about having its built-in page routing primitive, so we wouldn't have to manually configure our routing and Webpack builds. Routing We'd previously needed to set up our own in CRA using react-loadable and react-router + react-router-dom, including a large routes.tsx file that explicitly set up a routed component for each page in the app: import Loadable from "react-loadable"; import { Route, Switch } from "react-router-dom"; const EditorLoadable = Loadable({ loader: () => import(/* webpackChunkName: "routes-editor" */ "pages/editor"), loading: ChunkLoading, }); export function RouteSwitch() { return ( } /> ... ); } One of the advantages of Next.js over CRA is that Next.js ships with its own integrated linking & routing solution, next/router. Placing a file at pages/model/[:id]/edit.tsx with a default-exported React component is all Next.js needs to know to render a page at that path, with an id prop indicating the URL's id. Furthermore, the built-in Next.js Webpack configuration automatically splits pages out into their own bundles. That means visiting a page for local development only needs to build the bundle contents required for that page. Although CRA does support code splitting, in our experience the Next.js configuration is out-of-the-box much faster for local rebuilds. Styles Many of the older CSS files in the Causal codebase had been written prior to the team standardizing on CSS modules best practices. A number of those files utilized "impure" CSS selectors, meaning they could impact elements rendered by components elsewhere on the page. For example, our previous Button component unintentionally targeted all buttons on the page: // styles/button.scss button:disabled { cursor: not-allowed; } // components/Button.tsx import "styles/button.scss"; export function Button(props) { return