Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve tree-shaking of third-party dependencies #16395

Open
filipsobol opened this issue May 21, 2024 · 2 comments
Open

Improve tree-shaking of third-party dependencies #16395

filipsobol opened this issue May 21, 2024 · 2 comments
Labels
domain:dx This issue reports a developer experience problem or possible improvement. domain:performance This issue reports a problem or potential improvement regarding editor performance. type:debt This issue describes a technical debt. type:improvement This issue reports a possible enhancement of an existing feature.

Comments

@filipsobol
Copy link
Member

filipsobol commented May 21, 2024

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 and ckeditor5-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:

import 'ckeditor5';

This is the treemap chart generated from the esbuild bundle:

Treemap chart showing how much each packages added to the bundle

It shows that 280 out of 364 KiB come from CKEditor code, with almost 99% coming from ckeditor5-engine and ckeditor5-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 and turndown, as these dependencies are only needed when using the ckeditor5-markdown-gfm plugin. These two packages have side effects, so esbuild is not able to remove them from the bundle (Rollup can tree-shake turndown). 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 as external):

import 'ckeditor5-premium-features';

This is the treemap chart generated from the esbuild bundle:

Treemap chart showing how much each packages added to the 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 from protobufjs.

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 an eval 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 the compiledmessages.js file generated by protobufjs 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 of protobufjs (treat this as an uninformed suggestion).

@filipsobol filipsobol added the type:improvement This issue reports a possible enhancement of an existing feature. label May 21, 2024
@filipsobol filipsobol changed the title Improve tree-shaking Improve tree-shaking of third-party dependencies Jun 11, 2024
@filipsobol
Copy link
Member Author

filipsobol commented Oct 8, 2024

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.

@filipsobol filipsobol added domain:dx This issue reports a developer experience problem or possible improvement. domain:performance This issue reports a problem or potential improvement regarding editor performance. type:debt This issue describes a technical debt. labels Oct 8, 2024
@GG-Creations
Copy link

GG-Creations commented Nov 16, 2024

protobufjs i need this thing removed, any suggestions? i cannot uninstall it nor overridden thew sub dependency's that they are using it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:dx This issue reports a developer experience problem or possible improvement. domain:performance This issue reports a problem or potential improvement regarding editor performance. type:debt This issue describes a technical debt. type:improvement This issue reports a possible enhancement of an existing feature.
Projects
None yet
Development

No branches or pull requests

2 participants