Angular: Optimization Bundle Size with Brotli

Afif Alfiano
6 min readJun 17, 2023

--

Problem: The bundle size is too large and makes website slower

Reduce Bundle Size

Hi everyone, in this section I want to share my experience about optimization bundle size, especially in Angular using Brotli. The main problem why am I using Brotli rather than Gzip is because the bundle size is too large to serve to the client. So, I need to do more research about how to optimize the application, and walaaa, I got the Brotli.

So, what is Brotli? In short, the main task of Brotli is to compress bundle size, which has an algorithm itself. The advantage of using Brotli (br) is to make the website load faster. If you have ever heard about Gzip, the Brotli is the same thing as that, and Brotli was developed by Google. For more information, you can visit this link down below.

Actually, I have a lot of questions about Brotli but one question that I want to highlight is, “is it Brotli does support a lot of versions of the browser?” Then I got the information and it was great.

Supported Browser for Brotli
Supported Browser for Brotli

The next is you should know the comparison of some methods with Brotli. The image below is a summary to compare Brotli with gzip, bzip2, and xz.

A compression performance comparison between a number of different algorithms (Source: OpenCPU).
A compression performance comparison between a number of different algorithms (Source: OpenCPU).

We know that the compression time of Brotli is higher than Gzip, but for decompression time Brotli is smaller than Gzip. This is the reason why the bundle size can be smaller and can improve the performance of applications.

I also recommended a blog about Brotli with more detailed information.

Practice

I think enough for the explanation, Let’s practice together. In this section, I’m using projects from previous blogs. You can clone or maybe create your own project.

Make sure you are in the branch communication-data-input-output and then create a new branch with run this command

git checkout -b optimization-brotli

Just try to run the project with this command

npm run start

If the project running well, that’s good

Next, we need to install an additional library to support the Brotli in Angular.

npm install -D @angular-builders/custom-webpack compression-webpack-plugin brotli-webpack-plugin

Then, update angular.json

Before updating angular.json

Before updating angular.json
Before updating angular.json

After updating angular.json

After updating angular.json
After updating angular.json

Just updated the build lib and add customWebpackConfig on the options of build config.

Next, create the file webpack.config.js

const CompressionPlugin = require(`compression-webpack-plugin`);
const BrotliPlugin = require(`brotli-webpack-plugin`);
module.exports = {
plugins:[
new BrotliPlugin({
asset: '[fileWithoutExt].[ext].br',
test: /\.(js|css|html|svg|txt|eot|otf|ttf|gif)$/
}),
new CompressionPlugin({
test: /\.(js|css|html|svg|txt|eot|otf|ttf|gif)$/,
filename(info){
let opFile= info?.filename?.split('.'),
opFileType = opFile?.pop(),
opFileName = opFile?.join('.');
return `${opFileName}.${opFileType}.gzip`;
}
})
],
}

The above script is to add plugin compression from Webpack (Gzip) and Brotli. For Brotli config we only apply on file js|css|html|svg|txt|eot|otf|ttf|gif .

After that, create a file brotli-compress.js

const brotli = require('brotli')
const fs = require('fs')

const brotliSettings = {
extension: 'br',
mode: 0, // 0 = generic, 1 = text, 2 = font (WOFF2)
quality: 11, // 0 - 11
lgwin: 22 // window size
}

const path = 'dist/angular-tutorial-blogs';

fs.readdirSync(path).forEach(file => {
if (file.endsWith('.js') || file.endsWith('.css') || file.endsWith('.html')) {
const result = brotli.compress(fs.readFileSync(path + '/' + file), brotliSettings)
if (result) {
fs.writeFileSync(path + '/' + file + '.br', result)
}
}
})

The function file of brotli-compress is to compress the file with Brotli and write a file with extension .br

For the Brotli settings, you can check this link below

Then, we need a little adjustment on package.json

{
"name": "angular-tutorial-blogs",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build && npm run postbuild",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"postbuild": "node brotli-compress.js"
},
...
}

After that, try to build the project

npm run build

Finally, if your build is successful, there are files with extensions .js , .gzip, and .br

Compression File

Look at the size! That awesome.

After that just try to serve the project.

Serve Project Client Side

But, we have a problem, the content that serves it is still .js

Content-Encoding Brotli Not Working
Content-Encoding Brotli Not Working

Although we have several types files like .js , .gzip and .br . It’s still served in js if we serve the client side, the possible way to try the compression files is with server-side rendering or we create a server with express js.

To create a server, run this command.

npm i express express-static-gzip

After that, create a file server.js


const path = require('path');
const express = require('express');
const expressStaticGzip = require('express-static-gzip');

const serverPort = 7000;
const server = express();

server.use("/", expressStaticGzip(path.join(__dirname + '/dist/angular-tutorial-blogs'), {
enableBrotli: true
}));

server.get(/.*/, function (req, res, next) {
if (req.headers['x-forwarded-proto'] !== 'https' && process.env.NODE_ENV === 'production')
res.redirect('https://' + req.hostname + req.url);
else
res.sendFile(__dirname + '/dist/angular-tutorial-blogs/index.html');
});

server.listen(process.env.PORT || serverPort, function () {
console.log('Server. Port:%d', process.env.PORT || serverPort);
});

Then, just run node server.js to run angular from server.

node server.js

To make it easier, just update the package.json

  "scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build && npm run postbuild",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"postbuild": "node brotli-compress.js",
"ssr":"npm run build && npm run server",
"server": "node server.js"
},

This is an awesome result.

Content-Encoding Brotli

Conclusion

Finally, we have implemented Brotli compression in the angular project. There are several advantages to using brotli

  • Reduce bundle size
  • Easy to implement
  • Improve web performance

Last but not least, the image below is the compare load file with Brotli and without Brotli.

Compress with Brotli

Serve Content with Brotli

Compress without Brotli

Serve Content without Brotli

Thank you for your attention to reading this blog. You can check the repository for this project.

References:

#Angular #Express #Brotli #Optimization #BundleSize #Compression

--

--

Responses (4)