Repository navigation
perf: import ramda functions from per-function modules - #58
MarkusWendorf wants to merge 1 commit into
Conversation
Root imports from 'ramda' pull the whole library into bundles that don't tree-shake (e.g. Metro by default). Per-function 'ramda/src/*' imports keep only the used functions and are also the smallest with Expo's tree shaking enabled. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Recently there was an issue proposing the exact opposite: #49 However I need to admit I didn't do a throughout research, I just run one agent to confirm and fix the issue |
|
@5ZYSZ3K haha, that's interesting. I asked the creator of said issue to provide details so we know why tree-shaking was not working for him. |
|
@5ZYSZ3K maybe consider removing ramda entirely and ship equivalent code instead. Just had a go with Claude and it's ~100 LOC for the functions that are imported from ramda. Just an idea. |
|
@MarkusWendorf Yes, these days it actually sounds like a good idea, I'll consider that |
|
@MarkusWendorf I'm using My babel config: module.exports = (api) => {
api.cache(true)
return {
presets: [['babel-preset-expo', { jsxRuntime: 'automatic' }]],
plugins: [
[
'ramda',
{
useES: true,
},
],
],
}
} |
|
Before #50 this library used: import mapObjIndexed from 'ramda/src/mapObjIndexed'` and switched to import { mapObjIndexed } from 'ramda'To then be converted to import mapObjIndexed from 'ramda/es/mapObjIndexed'So the only change that happened was the subpath import Either way, I'm closing this PR and would advocate for shipping the lib without ramda in the future. |
|
For posterity, the difference for me was a decrease of about 6-8KB in production bundle size when using named imports with |
I noticed that root imports from
ramdapull the whole library into the bundle. This is not an issue if you have tree-shaking enabled, however by default Expo/Metro based projects do not have tree shaking enabled.EXPO_UNSTABLE_TREE_SHAKING=1can be used to enable it, but is marked as unstable for now.This PR changes to deep imports via
import x from 'ramda/src/xinstead of barrel imports.I setup some tests to see the difference. Not quite sure if
import x from 'ramda/src/xorimport x from 'ramda/es/xis the best way to go.If this is ok to be merged, maybe adding an ESLINT rule for imports would make sense. Let me know.
AI summary ahead ↓
Production app
Expo SDK 58, React Native 0.88, Android, Hermes bytecode.
import { x } from 'ramda'(current)import x from 'ramda/src/x'import { x } from 'ramda'(current)import x from 'ramda/src/x'The Hermes bundle column is the shipped bytecode; ramda's size comes from the minified-JS source map. Tree shaking is Expo's
experimental mode (
EXPO_UNSTABLE_TREE_SHAKING=1+EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH=1).Example app (already has tree shaking enabled)
apps/benchmarking(Android, minified JS). The app's ownimport { mean } from 'ramda'inBenchmark.jswas replaced with alocal helper so only the library is measured.
import { x } from 'ramda'(current)import x from 'ramda/src/x'import x from 'ramda/es/x'