🚀

lodash-esよりも軽量かつ高速なes-toolkitに移行してみる

2024/08/20に公開

es-toolkitとは

es-toolkitは配列・数値計算・オブジェクトや文字列操作などの機能を提供するJavaScriptのユーティリティです。公式の紹介文によると、lodashなどの代替品と比較して最大97%のバンドルサイズの削減、実行時パフォーマンスの2~3倍高速化、シンプルかつ堅牢なTypeScriptのサポートを特徴としています。バージョンv1.0.0が2024年5月末と新しいライブラリに関わらず(現在はv1.16.0)、GitHub Starは4.6kと期待のライブラリです。

検証内容/前提条件

今回はlodash(正確にはlodash-es)をあまり利用していないプロジェクトで移行を行い、効果を検証します。具体的には配列の比較にisEqual、ディープコピーにcloneDeep、オブジェクトのマージにmergeの全3関数を利用しているプロジェクトを対象とします。

インストール

インストールコマンドは以下のとおりです。lodash-esはTypeScriptで利用する際には@types/lodash-esをインストールする必要がありましたが、es-toolkitでは型が組み込まれているため追加の型インストールは不要でした。

npm install es-toolkit
# or
yarn add es-toolkit
# or
pnpm install es-toolkit

修正 / 検証

今回の対象関数は全て同名の関数が存在したためimport元を変更するだけで問題ありませんでした。概ね命名はlodashを意識していそうです。

// import { cloneDeep, isEqual, merge } from 'lodash-es'
import { cloneDeep, isEqual, merge } from 'es-toolkit'

機能移行にあたり簡単なテストを作成してそれぞれの関数の挙動を確認してみましたが、利用しているパターンでは挙動の差異は見当たりませんでした。以下はディープコピーの例となります。(テストのお行儀の悪さは目をつぶってください)

import * as lodash from 'lodash-es'
import * as es from 'es-toolkit'

test('cloneDeepの動作比較', () => {
  // コピー元配列を準備
  const date = new Date()
  const fn = () => {}
  const array = [1, 2, undefined, date, fn]

  // シャローコピー及びライブラリごとのディープコピーを行う
  const copyArray = array
  const lodashCopyArray = lodash.cloneDeep(array)
  const esCopyArray = es.cloneDeep(array)
  // コピー元配列の先頭を変更
  array[0] = 9

  // 検証
  expect(copyArray, 'arrayのシャローコピーとなっていること').toStrictEqual([9, 2, undefined, date, fn])
  expect(lodashCopyArray, '[lodash] 配列がコピー当時のarrayの値となること').toStrictEqual([1, 2, undefined, date, fn])
  expect(esCopyArray, '[es-toolkit] 配列がコピー当時のarrayの値となること').toStrictEqual([1, 2, undefined, date, fn])
})

ビルドサイズ検証

今回の検証対象であるisEqualcloneDeepmergeはシグネチャも命名も同一のため、以下のコードをビルドして比較検証してみます。

import { isEqual, cloneDeep, merge } from 'es-toolkit'
// import { isEqual, cloneDeep, merge } from 'lodash-es'

isEqual(1, 2)
cloneDeep([])
merge({a: 1}, {b: 2})

ビルド結果は以下の様になりました(ビルドの都合上、少し余分な処理も含まれています)。たった3関数でもかなりのバンドルサイズ削減効果がありますね。

es-toolkit lodash
ビルド後のサイズ 5.99kB 19.15kB
gzip 2.16kB 6.91kB

バンドルされたJavaScriptの中身が気になったためrollup-plugin-visualizerというrollup用のアナライザを利用して中身を見てみます。

  • lodash-es
    lodash-bundle

  • es-toolkit
    es-toolkit-bundle

どちらもTree Shakingは行われていますがes-toolkitは内部がかなりシンプルな構成になっていることが分かります。素人目にはlodash-esの様に細かく部品分けしてそれぞれ取り込んだ方が総バンドルサイズは小さくなる気もしますが、結果はご覧いただいたとおりです。

es-toolkitの公式ではlodash-esとの詳細なバンドルサイズの比較が紹介されています。気になる方はご参照ください。

https://es-toolkit.slash.page/bundle-size.html

所感

バンドルサイズの削減・TypeScriptの対応などパフォーマンスと扱いやすさを兼ね備えたライブラリで、ドキュメントも読みやすい素晴らしいライブラリだと感じました。ES Modulesが主流になる前から支えてくれたlodashなど偉大な先人に感謝しつつ、新規採用や移行を検討していこうと思います。

Discussion