Open filipsobol opened 6 months ago
While lodash-es
is not causing so many issues as some other libraries, we should consider replacing it. It hasn't received an update in the last ~4 years and because it still supports IE10 and IE11, it doesn't make use of modern JavaScript features, which affects both the bundle size and performance.
Fortunately, there's a modern alternative called es-toolkit
. It has a smaller bundle size and better performance.
It comes in two “flavors” — es-toolkit
and es-toolkit/compact
. The former offers better performance and smaller bundle size, while the latter aims at providing full compatibility with lodash.
I checked the bundle size of all functions used by us that are supported by both libraries to see the bundle size difference, and these are the results:
lodash-es
— 33.9kB → 12.9kB (GZIP)es-toolkit
— 7.94kB → 2.82kB (GZIP)es-toolkit/compat
— 12.8kB → 4.39kB (GZIP)Below is the list of all lodash functions used in our codebase and compatibility with es-toolkit
.
Method | Compatibility | Additional comment |
---|---|---|
debounce | ✅ | |
cloneDeep | ✅ | |
isEqual | ✅ | |
set | ✅ | |
unset | ✅ | |
throttle | ✅ | |
isObject | ✅ | |
omit | ✅ | |
mapValues | ✅ | |
isFunction | ✅ | |
isPlainObject | ✅ | |
isEqualWith | ✅ | |
mergeWith | ✅ | |
startCase | ✅ | |
isString | ✅ | |
escape | ✅ | |
unescape | 📝 | |
clone | 📝 | |
escapeRegExp | 📝 | |
upperFirst | 📝 | |
identity | 📝 | |
map | ❌ | It's used only in one place, can be easily worked around |
isElement | ❌ | It can probably be replaced with this |
cloneDeepWith | ❌ | |
extend | ❌ | It's used in two places, can likely be worked around, renamed to assignIn in both lodash and es-toolkit |
Compatibility explanation from es-toolkit
website
The following emojis indicate the status of each feature:
✅: Completed (The function is fully implemented and has passed all tests with lodash test code.)
📝: In Review (The function is implemented but hasn't been tested with lodash test code yet.)
❌: Not Implemented (The function hasn't been implemented.)
Even if a feature is marked "in review," it might already be under review to ensure it matches lodash perfectly, and it could already offer the same functionality.
protobufjs i need this thing removed, any suggestions? i cannot uninstall it nor overridden thew sub dependency's that they are using it
This is a continuation of the task #16292, which you can refer to for more context and results of the initial work.
In it, we were able to improve tree shaking and reduce the number of side effects in
ckeditor5
andckeditor5-premium-features
by about 80% by doing about 20% of the work (80/20 rule strikes again). This task focuses on the remaining work needed to make CKEditor bundles as small and performant as possible.ckeditor5
The following code results in a bundle size of 197 Kib for Rollup/Vite and 365 KiB in esbuild:
This is the treemap chart generated from the esbuild bundle:
It shows that 280 out of 364 KiB come from CKEditor code, with almost 99% coming from
ckeditor5-engine
andckeditor5-utils
, which are probably needed in all CKEditor projects anyway.The remaining 85 KiB come from external dependencies:
lodash-es
,color-convert
,color-name
,marked
,turndown
,turndown-plugin-gfm
.The first three packages are also likely to be used in all CKEditor projects, so there's no point in optimizing them.
However, the same cannot be said for
marked
andturndown
, as these dependencies are only needed when using theckeditor5-markdown-gfm
plugin. These two packages have side effects, so esbuild is not able to remove them from the bundle (Rollup can tree-shaketurndown
). We should look for ways to remove them from the bundle, either by contributing to them, forking them, or replacing them with alternatives that provide better tree-shaking.ckeditor5-premium-features
The following code results in a bundle size of 64 KiB for Rollup/Vite and 74 KiB in esbuild (with all
ckeditor5
packages marked asexternal
):This is the treemap chart generated from the esbuild bundle:
It shows that 64 out of 74 KiB come from external dependencies and only 10 KiB from CKEditor itself (which can be ignored). Of those 64 KiB, 36 KiB are from
socket.io
or its dependencies and 21 KiB are fromprotobufjs
.The problem with these two packages is that both are only needed when using RTC features, but are added to the bundle regardless of whether RTC is used or not. In addition, the
protobufjs
contains aneval
which causes Rollup/Vite to log a warning when bundling, causes issues with Content Security Policy (CSP), and can raise security alerts in some automated tools. The size of thecompiledmessages.js
file generated byprotobufjs
it also an issue.An alternative to
protobufjs
called protobuf-es claims that it is fully tree-shakeable and produces small bundle size, but since I have very little knowledge of protobuf and how we use it, I can only confirm the "fully tree-shakeable" claim, and can't tell if we can use it instead ofprotobufjs
(treat this as an uninformed suggestion).