Performance decrease after switching to SWC

825 Views Asked by At

I switched my NextJS app to SWC (I removed Babel`s config, and enabled the emotion plugin). Now, I see that build time has increased from 80 s to ~200 s. Does anyone have a similar experience?

My next.config.js:

// @ts-check

const path = require('path')

const _ = require('lodash')

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
})

const withImages = require('next-optimized-images')
const withFonts = require('next-fonts')

const withTM = require('next-transpile-modules')([
  '@xxx/helpers',
  '@xxx/ui',
  '@xxx/api',
])

console.log('basePath   -', process.env.BASE_PATH)
console.log(`Fs cache ${process.env.ENABLE_FS_CACHE ? 'enabled' : 'disabled'}`)

/**
 * Filters out keys with undefined value to be compliant with Next's env type definition
 * @param {{ [key: string]: string | undefined }} envs
 * @returns {{ [key: string]: string}}
 */
const getEnvs = (envs) => {
  /** @type {{ [key: string]: string}} */
  const result = {}
  Object.entries(envs).forEach(([key, env]) => {
    if (env) result[key] = env
  })
  return result
}

/**
 * @type {import('next').NextConfig}
 */
const settings = {
  env: getEnvs({
    ...
  }),
  trailingSlash: true,
  poweredByHeader: false,
  basePath: process.env.BASE_PATH,
  baseUrl: process.env.BASE_URL,
  assetPrefix: process.env.ASSET_PREFIX,
  esModule: true,
  handleImages: ['jpeg', 'png', 'webp', 'gif'],
  // @ts-ignore fix images config to match next types. We need to extract images sizes from test setup
  images: {
    disableStaticImages: true,
    domains: ['images.ctfassets.net'],
    loader: 'custom',
  },
  eslint: {
    ignoreDuringBuilds: true,
  },
  experimental: {
    emotion: true,
  },
  swcMinify: true,

  distDir: 'dist',
  webpack: (config, { isServer }) => {
    config.module.rules.push({
      test: /\.svg$/,
      use: [
        {
          loader: '@svgr/webpack',
          options: {
            svgoConfig: {
              plugins: [
                {
                  name: 'removeViewBox',
                  active: false,
                },
                { name: 'cleanupIDs', active: false },
                { name: 'prefixIds', active: true },
              ],
            },
          },
        },
        'url-loader',
      ],
    })

    config.module.rules.push({
      test: /\.mp4$/,
      use: [
        {
          loader: 'file-loader',
          options: {
            publicPath: `${process.env.ASSET_PREFIX || ''}/_next/static/videos/`,
            outputPath: `${config.isServer ? '../' : ''}static/videos/`,
            name: '[name]-[hash].[ext]',
          },
        },
      ],
    })

    config.module.rules.push({
      test: /\.json(.*?)\.data$/,
      use: [
        {
          loader: 'file-loader',
          options: {
            publicPath: `${process.env.ASSET_PREFIX || ''}/_next/static/data/`,
            outputPath: `${config.isServer ? '../' : ''}static/data/`,
            name: '[name]-[hash].json',
          },
        },
      ],
    })

    if (!isServer) {
      config.resolve.fallback.fs = false
      config.resolve.fallback.path = false
      config.resolve.fallback.crypto = false
      config.resolve.fallback.readline = false
    }

    return config
  },
}

const enhanceConfig = _.flow([withImages, withFonts, withBundleAnalyzer, withTM])

module.exports = enhanceConfig(settings)
0

There are 0 best solutions below