Preact - Reduce by 60% the size of your Webpack bundle file

I was introduced to Preact due to my negotiation with the German startup ParcelLab. I was preparing myself with their stack and Preact was part of this stack.

Initially I thought that I will need to change React with Preact, but that was not the case. Preact is fully compatible with React and one can keep using React as that Preact doesn't exist at all. The only time Preact is used is when you generate your production build.

A file generated without Preact was 1.13 MB in size, while the file, which utilizes Preact, was mere 510KB.

Inferno as fresh alternative

Inferno is younger framework and has momentum and followers. It gives us the same optimization goodies as Preact, so there is a choice to make. In my case, Inferno did not work, but also found cases where Preact bundle act where not applicable.

Testing

Inferno and Preact are nice way to reduce drastically the size of the bundle, but this optimization comes at price. I would recommend performing end-to-end or manual test to ensure that at least one of Inferno and Preact works for your project.

How to include Preact in Webpack?

We need to add only this part:

resolve: {
        alias: {
            "react": "preact-compat",
            "react-dom": "preact-compat"
        }
    }

and run npm i -D preact-compat

webpack.prod.config.js

const env = require("dotenv-helper")
const keyword = env.getEnv("webpack")
const J = require("../common")
const outputDir = `${J.oneLevelUp(__dirname)}/prod/public/bundles`
const webpack = require("webpack")

J.lg(outputDir, keyword)

module.exports = {
    entry: `./src/${keyword}/_index.js`,
    output: {
        path: outputDir,
        filename: `${keyword}.js`
    },
    plugins: [
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production')
        })
    ],
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: "babel",
                include: __dirname,
                query: {
                    presets: [ "es2015", "react", "stage-1"],
                    plugins:["transform-decorators-legacy"]
                }
            },
            {
                test: /\.css$/,
                loaders: [
                    "style-loader",
                    "css-loader?importLoaders=1"
                ]
            }
        ]
    },
    resolve: {
        alias: {
            "react": "preact-compat",
            "react-dom": "preact-compat"
        }
    }
}

My blog