The Correct Way to Import Lodash Libraries - A Benchmark
April 21, 2021

The Correct Way to Import Lodash Libraries: A Benchmark

Test Automation

Optimizing how we use code libraries like Lodash is a great way to avoid common problems during software development. For those of us familiar with using Lodash and other third-party libraries, we are all too familiar with running into these common scenarios:

  • 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.

Explore Lodash documentation. 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?

Table of Contents:

What is Lodash?

Lodash is a popular JavaScript library that helps facilitate web development by providing utility functions for common programming tasks.

With a wide range of helper functions such as deep equality checks and function binding, Lodash can be used directly inside a browser and with Node.js.  

3 Ways to Import Functions From Lodash

There are three methods for importing from Lodash, without using external plugins:

1. Import the Whole Lodash Library

import _ from 'lodash';

 

Pros:

  • Only one import line

 

Cons:

  • It seems like the import of a whole library will lead to the largest bundle size
  • Less readable usage in the javascript code

 

2. Import Specific Methods Inside of Curly Brackets:

 

import { map, tail, times, uniq } from 'lodash';

 

 

Pros:

  • Only one import line (for a decent amount of functions)
  • More readable usage: map() instead of _.map() later in the javascript code

 

Cons:

  • Every time we want use a new function or stop using another - it needs to be maintained and managed

 

3. Import Specific Methods Individually

 

import map from 'lodash/map';
import tail from 'lodash/tail';
import times from 'lodash/times';
import uniq from 'lodash/uniq';

 

 

Pros:

  • Seems to be the smallest bundle size.
  • More readable usage: map() instead of _.map()

 

Cons:

  • 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:

const numbers = [1, 5, 8, 10, 1, 5, 15, 42, 5];

const uniqNumbers = _.uniq(numbers);
Result: [1, 5, 8, 10, 15, 42]

const tailNumbers = _.tail(numbers);
Result: [5, 8, 10, 1, 5, 15, 42, 5]

const getRandomNumber = () => { return Math.round(Math.random() * 100); };

const randomNumbers = _.times(8, getRandomNumber);
Result: [58, 9, 98, 54, 96, 24, 25, 74]

 

Step 3 - Build the Comparison

Before comparing, let’s check a clean package build size: 115 KB.

Clean package build size for Lodash import benchmark

Figure 1: A clean bundle view

 

Let’s use the first method - whole library import:

 

import _ from "lodash";

 

 

Full Lodash import view

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:

 

import { map, uniq, tail, times } from "lodash";

 

 

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:

import map from "lodash/map";
import tail from "lodash/tail";
import times from "lodash/times";
import uniq from "lodash/uniq";

 

Modules import view

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.

Importing Lodash-es

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.

  1. Full import: 256.4 KB
  2. Curly brackets: 256.54 KB
  3. 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.

Importing Lodash with the Lodash Babel plugin.

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 the 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.

Importing Lodash with the WebPack plugin

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).

Lodash and Lodash-es Import Comparison Table

Conclusions

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 the 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 potential build time increase.

Lodash-es modules don’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.

Bottom Line

  • 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.

Start Testing Now

 

This blog was originally published on March 21, 2018, and has since been updated for accuracy and relevance.