The Correct Way to Import Lodash Libraries - A Benchmark
If you use various 3rd-party libraries when developing, you might have encountered several unpleasant effects, for example:
- increasing build time and complexity
- our bundle size grows exponentially
- larger response time
- users waste more time waiting for the page to load
There are many ways to optimize our code to overcome these problems. One of these is optimizing how we use libraries. In this article we’ll talk about ways and methods to optimize imports of the Lodash library both with and without external plugins. We will also compare Lodash to the Lodash-es library.
The Lodash documentation can be found at https://lodash.com/. It has dozens of useful functions for working with arrays, objects, strings and many others. But when developing, we only need to use a part of them. So maybe there is a possibility to import only the particular functions we need, and thus make our code lighter?
3 Ways to Import Functions From Lodash
There are three methods for importing from Lodash, without using external plugins:
1. Import the whole library:
- Only one import line
- It seems like the import of a whole library will lead to the largest bundle size
2. Import specific methods inside of curly brackets:
- Only one import line (for a decent amount of functions)
- Every time we want use a new function or stop using another - it needs to be maintained and managed
3. Import specific methods one by one:
- Seems to be the smallest bundle size.
- More readable usage: map() instead of _.map()
- The import maintenance is much more complicated than the previous options
- Lots of import lines in the head of the file don’t look nice and readable.
So, we want to investigate how we can optimize our bundle size and make imports as simple as possible.
So let’s benchmark the various methods for importing Lodash.
Lodash Import Benchmark
Step 1 - Create a React App
Let’s use a create-react-app cli tool for creating a benchmark bundle. You can also use source-map-explorer - a bundle analyse tool, which will help us a little to visualize the results.
Step 2 - Checking all three import options
I decided to use four functions from the lodash library to create a simple page that demonstrates their usage:
Step 3 - Build the Comparison
Before comparing, let’s check a clean package build size: 115 KB.
Figure 1: A clean bundle view
Let’s use the first method - whole library import:
Figure 2: A full Lodash import view
As we see, the bundle size is about 190 KB. The Lodash size is about 72.5 KB.
The second method - using curly brackets:
Surprisingly, the result of this method is the same bundle size: 190 KB. This means that this method doesn’t have any advantages over importing the complete library.
The third method - one-by-one or ‘modules’ import:
Figure 3: Modules import view
Well, this method provides us with much better results: the bundle size is about 140 KB.
At this point we can arrive at our first conclusion: if you want to minimize your bundle size - try to import only your used functions, each function by its own module.
Another option you can use is lodash-es: the Lodash library exported as ES modules. Some of us might say that this is a preferred option. So, let’s check the bundle size for lodash-es.
- Full import: 256.4 KB
- Curly brackets: 256.54 KB
- Module imports: 142.39 KB
The result is that the build size is much bigger with lodash-es. So, I don’t see any reason to use it.
But maybe there are some other tools for optimizing import and bundle size?
Using the Lodash Babel Plugin
The Lodash Babel plugin performs a simple transform that cherry-picks Lodash modules. As a result, all three methods give us a build size of 140 KB - the same as the one we got with the one-by-one module imports.
This way, we can use the pros of a full import without caring about each import’s maintenance.
When using Lodash-es, the build size is a little bigger: 143 KB.
Unfortunately, this method also has restrictions:
- You must use ES2015 imports to load Lodash
- Babel < 6 & Node.js < 4 aren’t supported
- Chain sequences aren’t supported
Another thing to consider when using this plugin is the build time. In case we have a very large codebase, it could take quite a long time to build, which could be critical for overall build/test/integration/delivery process.
But, on this plugin’s page we also see a piece of advice: “Combine with lodash-webpack-plugin for even smaller cherry-picked builds!”
Using the Lodash WebPack Plugin
This plugin performs amazing work. The total bundle size is only 121 KB for regular Lodash and 122 KB for Lodash-es! A very impressive result, isn’t it?
As with the previous case, it has the same restrictions, but it brings us a really small bundle size, so it might be worth it for you. Of course, build time growth should also be considered.
Lodash and Lodash-es Import Comparison Table
Here is the full table of results that I reached during the tests. Each import method has been tested for using one function and four functions. Each import method has been tested for a regular build, a build with the babel plugin and a build with the webpack plugin. In each cell you can see the result bundle size and also its gzipped (in Kilobytes).
Let’s accumulate our results and reach some conclusions. The first conclusion is that the most effective import is one-by-one. The cons of this method is the need to import each function every time we want to use it, which makes our import block in js file quite long (in case we use several functions). This kind of import doesn’t look very nice and is not very comfortable to maintain.
The smallest bundle size could also be reached by using the babel-plugin-lodash together with lodash-webpack-plugin for cherry-picking only the used functions. In this case we can import the full Lodash library only once at the beginning of the file, and the plugins will take care of the rest during the build. The possible cons that should be considered is a potencial build time increase.
Lodash-es modules doesn’t have any positive effect on the build size. Quite opposite, it’s even bigger in all cases.
Another important thing to consider: usually, web servers send a gzipped bundle to a client. Gzipping makes bundles much smaller, and the difference between bundle sizes of different kinds of import is much smaller. So, if we use a huge amount of functions so that the whole library should be included, the gzipped size difference could be insignificant. In this case, the usage of the above plugins is possibly less productive, and the build time should be considered as more important than several kilobytes.
Points to Take Away
- If you use a very small amount of functions - you should only import them one-by-one.
- If you use dozens of functions, but still don’t want to have the whole Lodash in your bundle - then use Babel & WebPack plugins. But be aware that the build time could be probably too expensive for big projects.
- If your usage of lodash has a lot of chain sequences, then consider the cost of refactoring or using alternatives. In several cases it can be too expensive, and you might prefer including the complete Lodash instead of refactoring huge projects.
Developers, join the JMeter Slack community and take part in the JMeter conversation - ask and answer questions, collaborate on projects and get JMeter resources.
If you are a developer who does load testing (which you probably are), you can try out BlazeMeter, a SaaS performance testing tool that scales and runs JMeter tests in the cloud. Just out your URL in the box below and your test will start in minutes.