Netlify build times are a black box for many, but understanding the levers can slash your build times from minutes to seconds.
Let’s look at a typical Next.js site on Netlify. Imagine this package.json:
{
"name": "my-next-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "13.4.19",
"react": "18.2.0",
"react-dom": "18.2.0",
"lodash": "4.17.21"
},
"devDependencies": {
"eslint": "8.48.0",
"eslint-config-next": "13.4.19",
"sass": "1.65.0"
}
}
And a netlify.toml:
[build]
command = "npm run build"
publish = ".next"
[build.environment]
NODE_VERSION = "18.17.0"
A common build might take 5 minutes. We want it under 2.
1. Dependency Management is Key
The most common culprit for slow builds is an overgrown node_modules directory and inefficient package installation. Netlify’s build image downloads and installs your dependencies on every run.
- Diagnosis: Check your
package-lock.json(oryarn.lock) for large or unnecessary packages. Look at the installation time in your Netlify build logs. - Fix: Prune unused dependencies. Run
npm prune --productionlocally and commit the updatedpackage-lock.json. If you have development-only dependencies that are massive (like large testing suites you don’t run on Netlify), consider a separatedevDependenciesinstall script or a monorepo setup. - Why it works: Fewer packages mean less to download and install, directly reducing the
npm installphase of your build.
2. Optimize Your Frontend Framework’s Build
Frameworks like Next.js have their own build optimizations. Not leveraging these is like leaving performance on the table.
- Diagnosis: Examine your Next.js build logs. Are there warnings about image optimization, unused code, or server-side rendering (SSR) bottlenecks?
- Fix: For Next.js, ensure you’re using the App Router if possible, as it’s generally more performant than the Pages Router. For image optimization, implement
next/imagewith appropriate sizes and formats. Disable SSR for pages that don’t need it by usingexport const dynamic = 'auto'orexport const dynamic = 'force-static'in your page/layout files. - Why it works: Framework optimizations reduce the amount of JavaScript, CSS, and HTML that needs to be generated and processed, leading to faster compilation.
3. Leverage Netlify’s Build Cache
Netlify caches dependencies and build artifacts between builds. If this isn’t configured correctly, you’re rebuilding more than necessary.
-
Diagnosis: Look for messages like "Restoring cached dependencies" or "Cache restored successfully" in your build logs. If you don’t see this, or if the cache is frequently invalidated, it’s a problem.
-
Fix: Ensure your
netlify.tomlexplicitly points to the correct cache directories. Fornpm, this is usuallynode_modules. Add this to yournetlify.toml:[build] command = "npm run build" publish = ".next" # Add this for caching [build.environment] NODE_VERSION = "18.17.0" # Cache node_modules and npm cache NETLIFY_BUILD_LFS_SKIP_SMUDGE = "true" NETLIFY_USE_YARN = "false" # if using npm NPM_CONFIG_LOGLEVEL = "warn" NPM_CONFIG_CACHE = "$HOME/.npm" # Explicitly set npm cache dirNetlify automatically caches
$HOME/.npmandnode_modules. -
Why it works: By preserving
node_modulesand the npm cache, Netlify can skip the full dependency download and installation step, drastically cutting down build time.
4. Optimize Asset Handling (Images, Fonts, etc.)
Large assets can significantly bloat your build process, especially if they need processing (like image compression or font optimization).
- Diagnosis: Check the size of your assets in the
publishdirectory (.nextfor Next.js). Are there unoptimized large images or many font files? - Fix: Use image optimization tools (like
sharpwhich Next.js uses under the hood, or external services) before committing. Compress images using tools like TinyPNG or ImageOptim. For fonts, use modern formats like WOFF2 and only load necessary weights. Consider lazy-loading images. - Why it works: Smaller assets mean less data to process, transfer, and store, leading to faster build and deployment times.
5. Concurrent Builds and Build Plugins
Netlify’s build environment can be configured for more power, and plugins can automate common tasks.
- Diagnosis: Observe CPU and memory usage in your build logs. If they are consistently maxed out, you might benefit from a more powerful build environment.
- Fix: For larger projects, consider upgrading to a Netlify plan that offers more build minutes or concurrent builds if you have multiple sites. Explore Netlify build plugins that can automate tasks like code linting or pre-compiling assets. For example, a plugin to pre-compile Sass can be beneficial.
- Why it works: More resources allow for faster execution of build commands. Plugins automate repetitive tasks, keeping your core build command focused and efficient.
6. Monorepo Considerations
If you’re using a monorepo (e.g., with Lerna or Nx), Netlify needs to be told which package to build and how to handle its dependencies.
-
Diagnosis: In a monorepo, Netlify might try to build the entire workspace, which is slow. Check your build logs for which directories are being processed.
-
Fix: Configure Netlify’s build command to target your specific application within the monorepo. For example, if your app is in
apps/web, yournetlify.tomlmight look like:[build] command = "cd apps/web && npm run build" publish = "apps/web/.next" # ... other settingsYou might also need to configure
npm cioryarn installto only install dependencies for the specific package. -
Why it works: By scoping the build to the relevant package and its dependencies, you avoid unnecessary work on other parts of the monorepo.
If you’ve addressed all these points, the next hurdle you’ll likely encounter is exceeding Netlify’s free tier build minute limits, forcing a decision on upgrading your plan or further optimizing your build process.