openedx / wg-frontend

Open edX Frontend Working Group
4 stars 1 forks source link

Discovery: Faster build tool #126

Closed jmbowman closed 1 year ago

jmbowman commented 2 years ago

The duration of front end asset bundling and minification has been flagged several times as a source of friction in development and deployment:

We currently use webpack for bundling and uglify-js for minification, but there are now much faster alternatives to both tools:

There have been initial conversations around utilizing SWC in webpack also, but there doesn't seem to be much actual code to that end yet: https://github.com/webpack/webpack/issues/13425 .

As a first step towards optimizing our development feedback loops and deployment time, please do some discovery on which if any of these alternatives could satisfactorily meet our needs and allow us to completely remove our dependency on webpack and/or uglify-js in most MFEs (and ideally edx-platform as well). In particular, we want to know:

We don't need extremely accurate and detailed answers to these questions, but we need enough of an idea to make a call on whether or not to go ahead with a pilot implementation, and if so which tool(s) to use.

jmbowman commented 2 years ago

Already found another contender currently being rewritten in Rust, doesn't seem as widely used as the others but may also be worth a look: https://rome.tools/ . What caught my attention is that it might serve as a faster replacement for eslint.

kdmccormick commented 2 years ago

Tutor rebuilds all MFEs relatively often, and this duration is increasing as the number of MFEs grows

We recently merged https://github.com/overhangio/tutor-mfe/pull/58, which significantly speeds up the dev MFE build (should be a matter of seconds now, no matter how many MFEs are installed). I am also working on https://github.com/overhangio/2u-tutor-adoption/issues/87, which should provide a generic production-ready base MFE image and thus reduce the need to build for production users.

All that being said, I think a faster build tool is still warranted!

ormsbee commented 2 years ago

It's outdated by this point, but I have an old asset compilation audit doc from late 2017 that goes over some of the bottlenecks in edx-platform static asset processing. We've fixed a number of items on that list, but I suspect that at least some of these are still issues.

kdmccormick commented 2 years ago

^ Nice. Tutor works around many of those with a custom re-implemtation of update_assets that is noticeably quicker, but it still hits some of the underlying bottlenecks like xmodule_assets.

ghassanmas commented 2 years ago

There are a lot to unpack here, I have some comments and inquries as well.

My background on this

  1. I've been doing some testing on this topic every now and then, and we were able have a workig concept of tutor-mfe prebuilt image that works for everyone (which doesn't need to rebuilt for changing config value only). Also relate to @kdmccormick comment above. See overhangio/tutor-mfe#69.

  2. I think we have to consider install time as well, in my testing with tutor-mfe I found that npm install might take around 1/3 to 1/2 of total build time[^4]. (Note this might not quite noticaiable on local dev testing because):

    • In local dev, probably tester focus npm run build beacuse node_modules already exists
    • in local dev, there is a .npm cache which can boost the install while this doesn't exists on tutor base image (or really any fresh node Docker image).
    1. During my testing I found some plugins when disabled reduce the built time a bit, about ~2-4 seconds. BundleAnalyzer, SourceMap

    2. I think its important to mention SASS/SCSS, files, I think its play a major role in the build time.

    Inquirues:

    1. Regarding uglify-js, I beleive @jmbowman probably you were referring to babel (and it's set of plugin)? I think uglify-js is used in edx-platform but not in frontend-build.

Webpack Alternative:

  1. Do any of the alternaive support module federation, I know we don't use this featuer but we might be near future
  2. Do any of alternative support code splitting, dynamic import, bundle chunks...etc Those are important for app perforamnce, while MFEs might not 100% utilize them but I think ultimately we should aim to...
  3. Let's take the case of Gatsby.js/Next.js both are competing website building framework, one metric that they both are competeing with is the site build-time, however both use and still rely heavily on using webpack[^1] [^2] [^3] probaly bceause of reason relate to the previos point

    Footnotes:

[^1]: While Next.js use SWC, but still SWC doesn't really replace weback for them, its more or less replace part of babel (as to my qucik checking). Another point is Next.js last year hired the author of Webpack check his tweet https://twitter.com/wSokra/status/1381860800533528576. [^2]: Next.js/Wepback Doc https://nextjs.org/docs/messages/webpack5 [^3]: Gatsby.JS/Webpack Doc https://www.gatsbyjs.com/docs/glossary/webpack/ [^4]: Related check my discourse post about testing with tutor-mfe https://discuss.openedx.org/t/microfrontends-a-retrospective/6486/20

abdullahwaheed commented 2 years ago

I have done some testing by replacing babel-loader with swc-loader keeping the webpack. There was average 1 second difference in both build times. The branch with swc loader in frontend build is up. Following are the build times some of the MFEs of :

Frontend App Account

SWC Loader

Babel Loader

Frontend-app-learning

SWC Loader

Babel Loader

frontend-app-enterprise-public-catalog

SWC Loader

Babel Loader

frontend-app-learner-portal-enterprise

SWC Loader

Babel Loader

P.S: All of these are tested on MacBook Pro 2018, 2.8 GHz Quad-Core Intel Core i7 with 16 GB 2133 MHz Memory

jmbowman commented 1 year ago

Hmm, that branch looks like it's just replacing Babel with SWC for transpiling. I suspect it's still using terser for minification, and that a good chunk of the time is being spent on that. And it's still using webpack for the overall orchestration.

The experiments I'm most curious about are:

  1. Can we also use SWC for minification, and does that help?
  2. Can we use SWC instead of uglify-js in edx-platform, and does that help performance?
  3. Can we replace webpack completely with SWC, and is that simpler and/or faster?
jmbowman commented 1 year ago

Like I discovered and mentioned in our meeting just now, it looks like SWC is currently working on its own bundler to replace webpack: https://swc.rs/docs/usage/bundling . If the gains from switching over MFEs are relatively modest, maybe we should wait until that's production ready to consider any move away from webpack? In that case, we may just want to focus for now on trying to swap out uglify-js in edx-platform for a faster minifier.

jmbowman commented 1 year ago

Also, there are even more candidates to consider now, one of which plans to allow for incremental upgrades from Webpack and is being worked on by the original Webpack author:

How about we create a new issue to use a faster minifier in edx-platform, close this discovery issue, and revisit the topic later in the year to see if there's a smoother migration path and/or a more obvious choice to move forward with?

arbrandes commented 1 year ago

I'd be onboard with that, @jmbowman.

sairion commented 1 year ago

You might have heard about it already, but there's rspack - Webpack-compliant bundler, fast, but still a bit of an early stage (they claim to use it in Bytedance in production)

Benchmark is interesting, because using swc-loader and babel-loader with Webpack didn't yield much differences. But using faster bundler changed score a lot.

arbrandes commented 1 year ago

@sairion, I hadn't heard of rspack. As a potential drop-in replacement, it looks very interesting. I just wish the project itself wasn't so new. I think we're going to have to wait a bit before we can consider it seriously.

jmbowman commented 1 year ago

@abdullahwaheed Could you please follow up on the recommendation above to create a new edx-platform minifier issue and close this one?

Mashal-m commented 1 year ago

Hey, I have done some research on rspack, following are the insights from R&D.

Conclusion:

Migrating from Webpack to Rspack raises concerns due to Rspack's relative newness and lack of maturity. While Rspack promises improved performance and flexibility, However, we cannot continue relying on Rspack fully, at least until sometime in the future.

Suggestion:

we can implement it in parallel with Webpack and see how it goes.

jmbowman commented 1 year ago

Reiterating my comments from January 20th and April 14th - I think we should completely shelve this discovery work for a few months until the alternatives mature a bit further. I'm going to go ahead and close this issue now. I still think it could be useful just to replace uglify-js in edx-platform with a faster minifier, but I'm going to skip creating that issue because I'm worried it'll just be another distraction from making real progress on ripping out the rest of the legacy UI code from edx-platform (so there would no longer be a need to minify anything).