Rxjs: The `rxjs` package is bloated

Created on 28 May 2018  路  25Comments  路  Source: ReactiveX/rxjs

RxJS version: 6.2.0

The package is more than 6 MB. That is a lot for a utility library.

Why is src included in the package? Source maps and TS definition files are already included for each JS file, so I don't see the need to include the TS source files too.

There's also a lot of bloat related to browser support: bundles, _esm5, _esm2015 (3.8 MB in total). Would you consider publishing a separate package for Node.js usage without all the bloat? For example, rxjs-node.

screen shot 2018-05-28 at 11 40 13

high

Most helpful comment

I tried updating the build in #3760, so comments are preserved in d.ts files but removed in all .js files (even .cjs). With the changes in the PR and without legacy-reexports it looks like the size is reduced by 1.51 Mb. At least it's some progress on trying to "remove bloat" 馃槉

As a side note, removing comments from .cjs should make rxjs slightly faster to require() in node.

All 25 comments

I agree. :man_shrugging:

IIRC, src is included because of source map needs. I'm curious as to why you say it's not necessary. The build process is something I've been a little detached from recently.

Most of the bloat is us trying to support everyone's module styles needs without confusing the crap out of users. If we publish rxjs and rxjs-node, then why not rxjs-esm and rxjs-umd and so on? And then all of the examples publicly will be weird and confusing, some will import { fromEvent } from 'rxjs-node'; and others will improt { fromEvent } from 'rxjs';

I'm open to any and all proposed solutions (especially from people that want to help). I know @kwonoj would kill to get this smaller, because they use it with an Electron app over at SlackHQ, and they're including the whole package.

just fyi around Electron side, I made decisions around gave up to deal with node_modules size / loading time and moving toward to bundling (even in main nodejs process, yes) to dodge several cases we needed to handcraft some solutions per each cases.

@benlesh I suggest to set removeComments to true in tsconfig.base.json. Having comments in d.ts files is enough for e.g. VSCode to show tooltips and more. There is a lot of comments that are used to generate documentation, and removing them from ., _es5 and es2015 would reduce total size by a lot.

FWIW: There's an opportunity to try to change this for v7, as what I'm looking at doing there is currently in our experimental branch

@csvn's proposal is actually good point, we may able to have as non-breaking changes?

I made a small test, and then ran npm pack ./dist/package --dry-run. It seems to save 25% size, but not sure about the report from npm.

With comments
image

Without comments
image

@csvn want to send PR for those? 馃摝

@kwonoj Sure, I'll send a PR in moment

Another thing worth noting is all of the files left for v5 compat reasons will go away in the next version.

removeComments: true will actually strip the documentation comments from the .d.ts files as well. That's not desirable. Just tried it locally.

~... so you'll want to override that for the CJS build at least.~ (nevermind, that leaves the comments in the code, the .d.ts files never get the comments it seems)

We can probably figure out a way to strip comments from the src files as well.

I think that would be harder than it sounds, sourceMappings would have to be re-mapped to the correct lines, wouldn't they?

We might also look into minifying the different module type outputs. Although I'm not sure any one minifier is particularly good at that.

But you're right about the comments, I thought TS only removed from source code... but setting it for all configs except tsconfig.cjs.json would probably work? It's the only one that emits declaration files.

There's really no measure for how much I hate all the different module systems. haha

minifying the different module type outputs

This may need some evalutions, especially size of sourcemap to construct mapped stack trace will sacrifice most of size gain. Also, on node side having sourcemap support is somewhat flaky.

If we can just get Node to modernize and throw CJS out once and for all, we'd solve this whole problem. :D

I honestly can't remember why we needed both _esm5 and _esm2015, they seem redundant to me.

as far as I remember esm5 is CJS module only replaces module import to es, while esm2015 compilation target es2015.

es2015 code is smaller and may be more performant, since e.g. arrow functions and classes aren't transpiled. For those only targeting es2015+ it's pretty nice to be able to use it. Also one important factor may be that native customElement.define() only accepts classes. It throws errors with regular transpiled classes => function constructors.

Uhm.. the point about custom elements is not really relevant in this project. Ignore that 馃檮

I tried updating the build in #3760, so comments are preserved in d.ts files but removed in all .js files (even .cjs). With the changes in the PR and without legacy-reexports it looks like the size is reduced by 1.51 Mb. At least it's some progress on trying to "remove bloat" 馃槉

As a side note, removing comments from .cjs should make rxjs slightly faster to require() in node.

For anyone who doesn't need anything but the CommonJS modules:

7.x branch: https://github.com/react-native-community/rxjs/commit/65b60e545f59e7d3bd26bc10df045d3c24f511c2
6.x branch: https://github.com/react-native-community/rxjs/commit/ccf062110ffcdc893b46872da8d0eab869756695

You can use a 2 MiB (instead of 20 MiB) version with Yarn with this change in your package.json:

"resolutions": {
  "rxjs": "npm: @react-native-community/[email protected]"
}

7.0.0-alpha.1 works as well if you are on the latest edge.

I just checked a fresh install of create-react-app.

These are the stats of the rxjs package (6.5.5):

image

Looking at the directories, I don't really get why the original TypeScript sources (src) are included in the release package. Is there something I am missing? Maybe just the *.js and *.d.ts files would suffice.

The simplest approach to reduce the package size without changing the build process would be an .npmignore file which contains something like this:

*.js.map
*.ts
!*.d.ts

This should save around 2.5MB.

Including src is intentional to provide correct code navigations with declarationmap. There are some planned deprecations around esm exports which will cut some of sizes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

giovannicandido picture giovannicandido  路  4Comments

matthewwithanm picture matthewwithanm  路  4Comments

chalin picture chalin  路  4Comments

Agraphie picture Agraphie  路  3Comments

LittleFox94 picture LittleFox94  路  3Comments