Very poor compile performance when used in a browser

85 views
Skip to first unread message

a...@scirra.com

unread,
Jun 29, 2020, 2:06:26 PM6/29/20
to Closure Compiler Discuss
I need to get the JS version of Closure Compiler working in a browser web app. First of all this has been tricky - the documentation appears to only say it's possible, and little else, so I've been more or less reverse engineering my way to something that works in the browser. Some extra documentation on this would be handy.

Anyway I got it working by getting jscomp.js from `npm pack google-closure-compiler-js` which loads and runs in a browser, and jscomp.compile() works if you use the magic option { jsCode: [{ src: "..." }] }.

The problem is it's extremely slow. I know JS might not be as fast as the Java build, but the difference is extreme. Here's a performance test I put together quickly: https://www.dropbox.com/s/n8gll0ahl5zdeqp/closure-browser-perf.zip?dl=0

On a high-end development desktop machine, it takes about a minute to compile testinput.js (an ~800kb script that our web app would process). It's about the same in both Chrome and Firefox. An equivalent `npx google-closure-compiler` command takes 4-5 seconds. This means the browser version is over 10 times slower.

I'm kind of confused about this - isn't npx basically running the same code? Why would the same code be so much slower in the browser? It seems like either something must have gone wrong, or there is obvious low hanging fruit to improve the situation.

To compound the problem it's even slower in a web worker, taking several minutes in Chrome stable - but that seems to be an unrelated issue, it's roughly the same again in Chrome Canary.

Have I done something wrong here? Does anyone have any ideas about how to make Closure Compiler run faster in the browser?

Ashley

Laura Harker

unread,
Jun 29, 2020, 3:58:40 PM6/29/20
to Closure Compiler Discuss
No one has tuned the performance of the JS version of the compiler in the last few years, if not ever. It's very possible there is low hanging fruit. Code that is reasonably efficient in Java can become very inefficient after GWT transpilation. (e.g. http://codegwt.blogspot.com/2013/05/performance-tuning-on-gwt-applications.html).

Also - we (the Closure Compiler devs) have been wondering how valuable the JS version of Closure Compiler actually is to users. Like you said, the JS version is slower. It's also harder to debug any problems during compilation versus Java/Graal native version and there's a maintenance burden to supporting multiple build configurations. Could you share your use case for running the compiler in a browser?

a...@scirra.com

unread,
Jun 29, 2020, 4:17:57 PM6/29/20
to Closure Compiler Discuss
Hmm, I see. But that doesn't seem to explain why there seems to be such a big difference between running in node and running in a browser?

We make Construct 3, a game development IDE in the browser: https://www.construct.net
When users export their games, we optionally minify the generated JavaScript, which is dynamically put together depending on the modules they use. This means having a JavaScript minifier that runs in the browser. We previously used babel-minify, but it's got some nasty bugs, seems to have very little development going on any more, and doesn't do as advanced optimizations, so we wanted to move to closure compiler. It works but only if you hack it a bit (I also had to just tweak its code to get it to accept externs), and it's weirdly slow.

I guess we could hit the closure-compiler.appspot.com API, but I expect we'd hit some kind of reasonable usage limits. We could host our own service, but it's a bit of a pain for us, and slows down exports for users on slow connections, when we could just run it in their own browser.

Ashley

Nick Reid

unread,
Jun 30, 2020, 1:28:52 AM6/30/20
to Closure Compiler Discuss
You might consider setting up your own backend for this. The compiler is a pretty heavy process even on the server side.

Additionally, we really can't recommend a production workflow that hits the appspot endpoint. It's meant for experimental traffic and isn't specd (or expected) to be a critical dependency.

Nick Reid

unread,
Jun 30, 2020, 1:54:42 AM6/30/20
to Closure Compiler Discuss
Another out there option might be to create a WASM module using GRAAL, similar to the native image we release.

a...@scirra.com

unread,
Jun 30, 2020, 6:00:24 AM6/30/20
to Closure Compiler Discuss
I was just thinking about WebAssembly, that's probably the best way to go. I don't have any experience at all using GRAAL though, and I know from previous experience of WebAssembly setting up the bindings can be pretty complicated unless you know what you're doing. Is this something Google could consider putting together? I could have a stab at it myself but we're a small team developing a full game development IDE, to say we have other things to work on would be an understatement, so I can't really afford to spend a couple of weeks trying to hack something together.

Nick Reid

unread,
Jun 30, 2020, 12:23:25 PM6/30/20
to Closure Compiler Discuss
Sorry, we also have other priorities. Also, as Laura mentioned, we're looking to streamline our release process.

Jesper van den Ende

unread,
Apr 28, 2021, 3:16:28 PM4/28/21
to Closure Compiler Discuss
I'm looking for javascript/wasm builds for a similar use case. Did you end up getting this to work?

a...@scirra.com

unread,
Apr 29, 2021, 6:58:37 AM4/29/21
to Closure Compiler Discuss
When Closure dropped support for the JavaScript version we had to contract out a port ourselves, which ended up costing us around 15000 USD. I'm afraid I'm not at liberty to share the work.

Jesper van den Ende

unread,
Apr 29, 2021, 7:07:58 AM4/29/21
to Closure Compiler Discuss
Oof, ok that makes sense.
I was starting to look into porting it myself but now I doubt that will end up being a viable solution.

Reply all
Reply to author
Forward
0 new messages