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

Remove source-map from Rollup bundle #2055

Merged
merged 3 commits into from
Mar 15, 2018

Conversation

mourner
Copy link
Contributor

@mourner mourner commented Mar 14, 2018

While digging through the source map generation, I noticed that the source-map dependency, which was only used for locating errors, can be easily replaced but using mappings directly. This makes the final Rollup bundle ~10% smaller.

# before
~/projects/rollup master → gz dist/rollup.js
orig: 839.13KB
gzip: 176.09KB

# after
~/projects/rollup master → gz dist/rollup.js
orig: 769.00KB
gzip: 158.63KB

Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great!

With the high performance work going on in the source maps library, I do wonder if we'd be better off trying to utilize this project more though in Rollup, but haven't investigated the source maps fully enough to be able to judge if there are other places it might be beneficial to utilize. Worth thinking about though.

src/Module.ts Outdated
line: location.line,
column: location.column
});
const line = sourcemap.mappings[location.line - 1];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could line be undefined here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added more checks in a follow-up commit.

src/Module.ts Outdated
let locationFound = false;

for (const segment of line) {
if (+segment[0] >= location.column) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the + coercion really necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it complains about values being strings. The original type issue here is that source map objects are typed as RawSourceMap, but mappings is actually decoded into arrays (while TypeScript assumes it's a single string). I'd suggest fixing the typing here in a separate type-cleaning PR because a proper fix might be quite involved.

@mourner
Copy link
Contributor Author

mourner commented Mar 14, 2018

With the high performance work going on in the source maps library, I do wonder if we'd be better off trying to utilize this project more though in Rollup, but haven't investigated the source maps fully enough to be able to judge if there are other places it might be beneficial to utilize. Worth thinking about though.

Note that the new version of source-map depends on WebAssembly, so you'd have to drop Rollup support for Node <8, IE11 and all but the newest browser versions.

Since magic-string seems to already work pretty well for Rollup, let's first look into optimizing that instead.

@@ -13,8 +13,7 @@ import extractNames from './ast/utils/extractNames';
import enhance from './ast/enhance';
import clone from './ast/clone';
import ModuleScope from './ast/scopes/ModuleScope';
import { encode } from 'sourcemap-codec';
import { RawSourceMap, SourceMapConsumer } from 'source-map';
import { RawSourceMap } from 'source-map';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we inline the RawSourceMap type we could remove source-map as a dependency entirely too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still used in tests, and it might be better to keep it there because it's a "reference" implementation, which is good for verifying source maps.

src/Module.ts Outdated
let locationFound = false;

if (line !== undefined) {
for (const segment of line) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this for (const segment of <[number, number, number, number][]>line) to get the types to work out without the coersions then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried something like this but TypeScript errored with "can't coerce a string into an array of numbers".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then defining line above as const line: any = ... could work along with the for typing. Then we can further look at fixing this up in due course.

@guybedford
Copy link
Contributor

Sure, sounds like a good start to me.

Do we have any performance numbers for this change?

@mourner
Copy link
Contributor Author

mourner commented Mar 14, 2018

Do we have any performance numbers for this change?

I didn't measure because this only happens on bundle errors, which is rare. It should be fast enough.

@guybedford
Copy link
Contributor

I didn't measure because this only happens on bundle errors, which is rare. It should be fast enough.

Sure!

@mourner
Copy link
Contributor Author

mourner commented Mar 14, 2018

@guybedford removed the coercions with any. Ready for another review :)

Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lukastaegert
Copy link
Member

Looks good. Curious finding: When I measure bundling performance now, the first tree-shaking runs seem to be significantly and consistently slower while graph analysis and other earlier steps seem to be faster by at least the same amount. No idea what could be behind this as the changed code is not even used.

@lukastaegert lukastaegert merged commit b7ca117 into rollup:master Mar 15, 2018
@lukastaegert lukastaegert added this to the 0.57.0 milestone Mar 15, 2018
@mourner mourner deleted the remove-source-map-dep branch March 15, 2018 06:49
@mourner
Copy link
Contributor Author

mourner commented Mar 15, 2018

first tree-shaking runs seem to be significantly and consistently slower

Perhaps the first, reference perf.json was an outlier (faster than usual)? I think this happened to me once too.

@lukastaegert
Copy link
Member

I would not think so as I was doing 10 runs and discarding 5 outliers in both cases (using npm run perf 10 5 instead of the --perf option). Would be interesting if others can confirm this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants