Skip to content

Tree-Shaking

Use tree-shaking to automatically subset and include only the icons you’re using.

Beginning with the excellent tool Rollup.js by Rich Harris, the concept of tree-shaking attempts to eliminate any unused code. Webpack 2 now includes this as well.

Using Font Awesome with Tree-shaking

The Font Awesome icon packages support tree-shaking out of the box but only if your tool is tree-shaking compatible.

In this example, only faCoffee is imported from free-solid-svg-icons, so only that icon will be included in the production optimized bundle:

// Tree-shaking Example
import { faCoffee } from '@fortawesome/free-solid-svg-icons'

Alternative to Tree-shaking: Deep Imports

If your tool does not yet support tree-shaking you can still benefit from only importing the icons you use by following this example:

// Bullet-proof deep import example
import { faCoffee } from '@fortawesome/free-solid-svg-icons/faCoffee' // <-- note the extra faCoffee there

Known Issues with Tree-shaking

Production Mode

Webpack only performs tree-shaking when the --mode=production flag is used. This enables the UglifyJsPlugin which performs the optimization. To nerd out for a second; this plugin is actually doing “dead code elimination” which is a slower process than the canonical tree-shaking but the results are similar.

Rollup enables tree-shaking by default but it does so only with ES modules. Font Awesome provides ES modules in all of its NPM packages so you should be good-to-go.

Slow Build Times with Webpack 4, uglify-es@3 and uglify-js@3

You may experience surprisingly slow build times with Webpack 4, uglify-es@3 and uglify-js@3. For instance, when running a production build with Webpack 4, it might seem to hang for a long time with a status of: 92% chunk asset optimization. angular-cli 6.0 uses Webpack 4 under the hood, as does vue-cli 3.0, and perhaps other similar zero-configuration development framework tools.

Here’s more background: uglify-es is a minifier based on uglify-js. A minifier can eliminate unused code, and this is how Webpack achieves tree-shaking. It delegates dead code elimination to the minifier used for production bundles. Unfortunately, as of [email protected] and [email protected], there’s a significant performance problem in this minifier code base that happens to effect modules that are formatted like our icon packages. Also, the uglify-es project has transitioned ownership and been renamed terser.

We expect that future releases of Webpack will depend upon terser instead of uglify-es, and will include the performance fix that will make tree-shaking fast again in Webpack 4. In the meantime, if you’re facing this problem, there are a few workarounds that you might consider.

Workaround 1: Use deep imports - Each icon is available as a submodule in CommonJS format and can be imported like the example below. This avoids tree-shaking entirely.

// Bullet-proof deep import example
import { faCoffee } from '@fortawesome/free-solid-svg-icons/faCoffee' // <-- note the extra faCoffee there

Workaround 2: Switch to Babel Minify - Configure webpack to use babel-minify instead of uglify-es or uglifyjs, like this:

webpack.config.js
const BabelMinifyPlugin = require('babel-minify-webpack-plugin')
module.exports = {
// ...
optimization: {
minimizer: [
new BabelMinifyPlugin()
]
}
}

Workaround 3: Disable collapse_vars - Stick with uglify-es or uglify-js 3.x, but configure webpack to disable the collapse_vars compression option. This would impact your whole build, of course, not just the Font Awesome modules.

webpack.config.js
// Disable collpase_vars
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
// ...
optimization: {
minimizer: [
new UglifyWebpackPlugin({
uglifyOptions: {
compress: {
collapse_vars: false
}
}
})
]
}
}

Zero-configuration tools

If you’re using a tool like angular-cli that uses Webpack 4 under the hood, it may be necessary to eject from the tool’s configuration management if you want to make any of the Webpack configuration modifications suggested above.

If ejecting is too undesirable, then your best options are probably to either downgrade to a version of that tool set that uses Webpack 3 until the fix for this performance regression is available, or switch to using deep imports as described above until the fix is available.