You Know What I Mean.
This is a more complete version than You Don't Need Lodash/Underscore or You Might Not Need Lodash, with additional features:
- π¦ bundle size comparsion, powered by esbuild and bundlejs.com.
- π performance benchmark, powered by vitest.
A good lodash function alternative should be both smaller and faster. In some cases, here is no drop-in replacement, you have to modify your code a little bit.
// π¦ 1.87 kB (gzip)
// π 5.24 mHz
import chunk from 'lodash/chunk';
chunk(['a', 'b', 'c', 'd'], 2);
// π¦ 126 B (gzip), 93% smaller π
// π 7.41 mHz, 20% slower π
const chunk = (arr, chunkSize = 1, cache = []) => {
const tmp = [...arr];
if (chunkSize <= 0) return cache;
while (tmp.length) cache.push(tmp.splice(0, chunkSize));
return cache;
};
chunk(['a', 'b', 'c', 'd'], 2);
// π¦ 426 B (gzip)
// π 5.52 mHz
import compact from 'lodash/compact';
compact([0, 1, false, 2, '', 3]);
// π¦ 53 B (gzip), 87% smaller π
// π 14.5 mHz, 163% faster π
[0, 1, false, 2, '', 3].filter(Boolean);
// π¦ 1.27 kB (gzip)
// π 1.96 mHz
import concat from 'lodash/concat';
concat([1], 2, [3], [[4]]);
// π¦ 45 B (gzip), 96% smaller π
// π 3.63 mHz, 85% faster π
[1].concat(2, [3], [[4]]);
// π¦ 4.29 kB (gzip)
// π 3.33 mHz
import difference from 'lodash/difference';
difference([2, 1], [3, 2]);
// π¦ 77 B (gzip), 98% smaller π
// π 12.1 mHz, 264% faster π
const difference = (arr1, arr2) => arr1.filter((x) => !arr2.includes(x));
difference([2, 1], [3, 2]);
// π¦ 9.46 kB (gzip)
// π 1.05 mHz
import differenceBy from 'lodash/differenceBy';
differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], 'x');
// π¦ 162 B (gzip), 98% smaller π
// π 2.58 mHz, 146% faster π
const differenceBy = (arr1, arr2, iteratee) => {
if (typeof iteratee === 'string') {
const prop = iteratee;
iteratee = (item) => item[prop];
}
return arr1.filter((c) => !arr2.map(iteratee).includes(iteratee(c)));
};
differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], 'x');
TODO
// π¦ 1.42 kB (gzip)
// π 4.67 mHz
import drop from 'lodash/drop';
drop([1, 2, 3], 2);
// π¦ 60 B (gzip), 96% smaller π
// π 9.67 mHz, 107% faster π
const drop = (arr, n = 1) => arr.slice(n);
drop([1, 2, 3], 2);
// π¦ 483 B (gzip)
// π 4.95 mHz
import now from 'lodash/now';
now();
// π¦ 32 B (gzip), 93% smaller π
// π 11.4 mHz, 131% faster π
Date.now();
// π¦ 7.38 kB (gzip)
// π 0.39 mHz
import cloneDeep from 'lodash/cloneDeep';
const obj = {
string: 'abcdef',
number: 123.456,
array: [
{
name: 'WebInspector',
version: '537.36',
},
{
name: 'WebInspector',
version: '537.36',
},
],
};
cloneDeep(obj);
rfdc is a fully featured alternative of lodash/deepClone
.
But it is bigger in size compared to other alternative.
// π¦ 1.15 kB (gzip), 84.4% smaller π
// π 1.06 mHz, 172% faster π
import rfdc from 'rfdc';
const cloneDeep = rfdc();
const obj = {
string: 'abcdef',
number: 123.456,
array: [
{
name: 'WebInspector',
version: '537.36',
},
{
name: 'WebInspector',
version: '537.36',
},
],
};
cloneDeep(obj);
If you only need to clone simple JSON data (no symbols, prototypes, etc.), klona/json is a lighter choice.
// π¦ 0.31 kB (gzip), 95.8% smaller π
// π 2.19 mHz, 456% faster π
import { klona as cloneDeep } from 'klona/json';
const obj = {
string: 'abcdef',
number: 123.456,
array: [
{
name: 'WebInspector',
version: '537.36',
},
{
name: 'WebInspector',
version: '537.36',
},
],
};
cloneDeep(obj);
// π¦ 6.4 kB (gzip)
// π 1.61 mHz
import isEqual from 'lodash/isEqual';
isEqual({ a: 1, b: 2 }, { b: 2, a: 1 });
// π¦ 609 B (gzip), 91% smaller π
// π 4.16 mHz, 158% faster π
import isEqual from 'react-fast-compare';
isEqual({ a: 1, b: 2 }, { b: 2, a: 1 });