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

Discovery: Faster build tool #126

Closed
jmbowman opened this issue Sep 8, 2022 · 15 comments
Closed

Discovery: Faster build tool #126

jmbowman opened this issue Sep 8, 2022 · 15 comments
Assignees
Labels
candidate for funding epic Large unit of work, consisting of multiple tasks

Comments

@jmbowman
Copy link

jmbowman commented Sep 8, 2022

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

  • Tutor rebuilds all MFEs relatively often, and this duration is increasing as the number of MFEs grows
  • JS minification is a fairly high percentage of setup and deployment time for edx-platform
  • MFEs often do less aggressive minification in CI than used in production to keep the test duration short, which means we're testing slightly different code than deployed to production.
  • The webpack bundler ecosystem requires a lot of plugins and dependencies, some of which have been abandoned and/or had long-lasting security vulnerabilities.

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

  • SWC is a very fast JavaScript/TypeScript compiler/bundler/minifier implemented in Rust which many other tools in the front end ecosystem are starting to utilize.
  • Parcel is a fast bundler which adopted SWC and claims to require much less configuration than webpack for most common use cases.
  • Next.js is a pretty comprehensive toolkit for using and deploying React which also recently adopted SWC.
  • esbuild Is a very fast Go-based bundler & minifier
  • I haven't yet found good benchmarks on the recent versions of each of these bundlers, but I did find some good benchmarks of the underlying minifiers.

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: webpack/webpack#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:

  • Does the replacement lack any important features our current webpack/uglify-js ecosystem provides?
  • Does the replacement gain us any useful features our current ecosystem lacks?
  • How much faster is the replacement?
  • How much configuration does the replacement need?
  • How many dependencies does the replacement have relative to our current stack, and how actively maintained are they?
  • How much work is it to replace what we currently use?

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
Copy link
Author

jmbowman commented Sep 8, 2022

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.

@jmbowman jmbowman moved this to Todo in FED-BOM Sep 8, 2022
@jmbowman jmbowman added this to FED-BOM Sep 8, 2022
@kdmccormick
Copy link
Member

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

We recently merged overhangio/tutor-mfe#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
Copy link

ormsbee commented Sep 9, 2022

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
Copy link
Member

^ 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.

@abdullahwaheed abdullahwaheed self-assigned this Sep 21, 2022
@abdullahwaheed abdullahwaheed moved this from Todo to In Progress in FED-BOM Sep 26, 2022
@arbrandes arbrandes moved this to In progress in Frontend Working Group Sep 30, 2022
@abdullahwaheed abdullahwaheed moved this from In Progress to Blocked in FED-BOM Oct 13, 2022
@arbrandes arbrandes added epic Large unit of work, consisting of multiple tasks candidate for funding labels Oct 20, 2022
@ghassanmas
Copy link
Member

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 MFE dynamic config 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 time1. (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).
  3. During my testing I found some plugins when disabled reduce the built time a bit, about ~2-4 seconds. BundleAnalyzer, SourceMap

  4. 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 webpack2 3 4 probaly bceause of reason relate to the previos point

Footnotes:

Footnotes

  1. Related check my discourse post about testing with tutor-mfe https://discuss.openedx.org/t/microfrontends-a-retrospective/6486/20

  2. 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.

  3. Next.js/Wepback Doc https://nextjs.org/docs/messages/webpack5

  4. Gatsby.JS/Webpack Doc https://www.gatsbyjs.com/docs/glossary/webpack/

@abdullahwaheed
Copy link

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

  • 45215 ms
  • 35220 ms
  • 33945 ms
  • 34578 ms

Babel Loader

  • 36459 ms
  • 37850 ms
  • 34899 ms

Frontend-app-learning

SWC Loader

  • 44397 ms
  • 39295 ms
  • 40113 ms
  • 39901 ms

Babel Loader

  • 51571 ms
  • 47508 ms
  • 43560 ms
  • 43892 ms
  • 44516 ms
  • 54750 ms

frontend-app-enterprise-public-catalog

SWC Loader

  • 40625 ms
  • 45901 ms
  • 53540 ms
  • 40331 ms
  • 39229 ms
  • 42961 ms

Babel Loader

  • 58605 ms
  • 55893 ms
  • 48538 ms
  • 48606 ms
  • 49579 ms

frontend-app-learner-portal-enterprise

SWC Loader

  • 87861 ms
  • 70771 ms
  • 65968 ms
  • 64352 ms
  • 64587 ms

Babel Loader

  • 77309 ms
  • 69084 ms
  • 79575 ms
  • 68856 ms
  • 76818 ms
  • 73496 ms

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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
Copy link

I'd be onboard with that, @jmbowman.

@abdullahwaheed abdullahwaheed moved this from Blocked to Todo in FED-BOM Feb 2, 2023
@sairion
Copy link

sairion commented Mar 27, 2023

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
Copy link

@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
Copy link
Author

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

@Mashal-m
Copy link

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

  • Rspack claims to be 10 or 30 times faster than webpack due to its implementation in Rust and also because of parallel architecture and incremental compilation features.
  • Rspack is still under upgrade plans and is relatively new. It aims to fulfill requirements and has the potential to become a strong lead in the future. Both Rspack and webpack offer flexibility in terms of framework usage.
  • Rspack may not support all the loaders that Webpack does at the moment, as it is still in its early stages,
  • webpack has a significant advantage in terms of the number of users as compared to any other bundler. It has been widely adopted by the community. Rspack, being relatively new, may not have the same level of community and tooling support.
  • Rspack is designed to work alongside the Webpack ecosystem, it lacks many of the functionalities of Webpack and is still in its early stages of development
  • Rspack plans to introduce lazy compilation support and consistent cache support, similar to Webpack. And some other tentative ideas for the future of the rspack roadmap

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
Copy link
Author

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).

@github-project-automation github-project-automation bot moved this from Todo to Done in FED-BOM May 24, 2023
@github-project-automation github-project-automation bot moved this from In progress to Closed in Frontend Working Group May 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
candidate for funding epic Large unit of work, consisting of multiple tasks
Projects
Status: Closed
Development

No branches or pull requests

8 participants