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.

Related Reading: Are you committing these seven deadly sins of application quality? Get our eBook to find out >>

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 some of these Lodash functions.

So maybe there is a possibility to import only the particular Lodash functions we need, and thus make our code lighter. Let us find out.

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 Lodash 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 Lodash functions).
  • More readable usage: map() instead of _.map() later in the Javascript code.

Cons:

  • Every time we want to 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 Lodash 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 Lodash 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 Lodash benchmark bundle. You can also use source-map-explorer - a bundle analysis 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 these three methods to import Lodash libraries, 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 - a whole Lodash 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 Lodash import 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 Lodash import 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 Lodash bundle size, try to import only your used functions, with 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, as compared to Lodash. 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 Lodash 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 Babel Lodash plugin is the build time. In case we have a huge 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

The Lodash WebPack plugin performs amazing work. The total bundle size is only 121 KB for regular Lodash and 122 KB for Lodash-es! 

As with the previous case, the Lodash WebPack plugin 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

Below you will find a full table of results that I reached when comparing Lodash and Lodash-es imports. 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 Lodash plugin, and a build with the Lodash Webpack plugin. In each cell, you can see the result bundle size. Also, note that the bundle size is gzipped (in Kilobytes).

Lodash and Lodash-es Import Comparison Table

Bottom Line

Let’s accumulate our results and reach some conclusions. The first conclusion is that the most effective Lodash library import is one-by-one. The major disadvantage 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 Lodash 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, using the above plugins is possibly less productive, and the build time should be considered as more important than several kilobytes.

  • If you use a very small amount of Lodash 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, use Babel & WebPack plugins. But be aware that the build time could be probably too expensive for big projects.
  • If your Lodash usage 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 participate 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. Start testing today. 

Start Testing Now

 

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