From 755cf5a437ce45fec240e133a5602745ef56807d Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 10 Sep 2025 19:12:49 +0200 Subject: [PATCH 1/4] fix(components): always force speedy mode for emotion to avoid performance issues in dev mode --- packages/compass-components/src/force-emotion-speedy.ts | 2 ++ packages/compass-components/src/index.ts | 2 +- packages/compass-web/webpack.config.js | 7 ------- 3 files changed, 3 insertions(+), 8 deletions(-) create mode 100644 packages/compass-components/src/force-emotion-speedy.ts diff --git a/packages/compass-components/src/force-emotion-speedy.ts b/packages/compass-components/src/force-emotion-speedy.ts new file mode 100644 index 00000000000..d03ee37fe37 --- /dev/null +++ b/packages/compass-components/src/force-emotion-speedy.ts @@ -0,0 +1,2 @@ +import { sheet } from '@leafygreen-ui/emotion'; +sheet.speedy(true); diff --git a/packages/compass-components/src/index.ts b/packages/compass-components/src/index.ts index 7e4431ab956..7e0b768d3cf 100644 --- a/packages/compass-components/src/index.ts +++ b/packages/compass-components/src/index.ts @@ -1,5 +1,5 @@ +import './force-emotion-speedy'; export * from './components/leafygreen'; - export { default as emotion, flush, diff --git a/packages/compass-web/webpack.config.js b/packages/compass-web/webpack.config.js index e71d2f01f47..c76ff5cbc92 100644 --- a/packages/compass-web/webpack.config.js +++ b/packages/compass-web/webpack.config.js @@ -294,13 +294,6 @@ module.exports = (env, args) => { tls: 'commonjs2 tls', }, plugins: [ - // Always package dist with NODE_ENV set to production, otherwise @emotion - // dev mode behavior completely hangs code in the browser when applying - // dev build to locally running mms - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify('production'), - }), - // Only applied when running webpack in --watch mode. In this mode we want // to constantly rebuild d.ts files when source changes, we also don't // want to fail and stop compilation if we failed to generate definitions From 3e20b78660cbc8cffdef02b1aebcd2a60598280b Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 10 Sep 2025 17:32:58 -0400 Subject: [PATCH 2/4] chore: improve exiting of sync script --- .../compass-web/scripts/sync-dist-to-mms.js | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/compass-web/scripts/sync-dist-to-mms.js b/packages/compass-web/scripts/sync-dist-to-mms.js index cb1f3ee27e1..87ca17a4137 100644 --- a/packages/compass-web/scripts/sync-dist-to-mms.js +++ b/packages/compass-web/scripts/sync-dist-to-mms.js @@ -3,6 +3,7 @@ const fs = require('fs'); const path = require('path'); const child_process = require('child_process'); const os = require('os'); +const util = require('util'); const { debounce } = require('lodash'); if (!process.env.MMS_HOME) { @@ -58,11 +59,42 @@ const webpackWatchProcess = child_process.spawn('npm', ['run', 'watch'], { stdio: 'inherit', }); +const failProofRunner = () => + new (class FailProofRunner extends Array { + append(...fns) { + this.push(...fns); + return this; + } + + run() { + const errors = this.map((f) => { + try { + f(); + } catch (e) { + return e; + } + }).filter((e) => e); + + if (errors.length) { + fs.writeSync( + process.stdout.fd, + util.inspect(errors, { depth: 20 }) + '\n' + ); + } + + return errors.length; + } + })(); + function cleanup(signalName) { - distWatcher.close(); - webpackWatchProcess.kill(signalName); - fs.cpSync(tmpDir, destDir, { recursive: true }); - fs.rmSync(tmpDir, { recursive: true, force: true }); + const errorCount = failProofRunner() + .append(() => distWatcher.close()) + .append(() => webpackWatchProcess.kill(signalName)) + .append(() => fs.cpSync(tmpDir, destDir, { recursive: true })) + .append(() => fs.rmSync(tmpDir, { recursive: true, force: true })) + .run(); + fs.writeSync(process.stdout.fd, 'Exit compass-web sync...\n'); + process.exit(errorCount); } for (const evt of ['SIGINT', 'SIGTERM']) { From b5afa3fa0c98b7f3d97773c0b73cff3b5befafc8 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 11 Sep 2025 15:13:10 -0400 Subject: [PATCH 3/4] Add documentation Co-authored-by: Sergey Petushkov --- .../src/force-emotion-speedy.ts | 22 +++++++++++++++++++ packages/compass-components/src/index.ts | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/packages/compass-components/src/force-emotion-speedy.ts b/packages/compass-components/src/force-emotion-speedy.ts index d03ee37fe37..2a383452d49 100644 --- a/packages/compass-components/src/force-emotion-speedy.ts +++ b/packages/compass-components/src/force-emotion-speedy.ts @@ -1,2 +1,24 @@ import { sheet } from '@leafygreen-ui/emotion'; +/** + * Emotion will dynamically decide which style insertion method to use based on + * the "env" it is built for: in "development" mode it uses a method of + * inserting literal style tags with css as text inside of them for every `css` + * method call to apply styles to the page. This method is really slow, every + * single style tag insertion causes style recalculation that can end up + * blocking the main thread for multiple seconds, when accumulated this can + * result in minutes of unresponsive page behavior. In "production" mode the + * style insertion is done using a modern JS API that doesn't result in such + * drastic performance issues. + * + * Specifically when embedding compass-web in mms, there is a massive + * performance hit that can be observed when emotion is not running in "speedy" + * mode, so to work around that we are always forcing emotion to enable it. + * + * Historically "speedy" mode was only active in production because editing + * styles in the browser devtools didn't work otherwise, nowadays there is no + * reason to not use it always, so there should be no downsides to doing this. + * + * See also https://github.com/10gen/compass-data-explorer/pull/11 where we + * already ran into a similar issue. + */ sheet.speedy(true); diff --git a/packages/compass-components/src/index.ts b/packages/compass-components/src/index.ts index 7e0b768d3cf..ffacf0f8226 100644 --- a/packages/compass-components/src/index.ts +++ b/packages/compass-components/src/index.ts @@ -1,4 +1,9 @@ +// IMPORTANT: this import should always be the first one in compass-component +// main entrypoint to ensure that emotion is reconfigured before any component +// modules generate their stylesheets import './force-emotion-speedy'; +// ------------------------------- + export * from './components/leafygreen'; export { default as emotion, From dcd7e3f0b474e4d648d0e90a41b5c782c6c2b61e Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 11 Sep 2025 16:12:32 -0400 Subject: [PATCH 4/4] Update packages/compass-components/src/force-emotion-speedy.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packages/compass-components/src/force-emotion-speedy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-components/src/force-emotion-speedy.ts b/packages/compass-components/src/force-emotion-speedy.ts index 2a383452d49..8b7c8d74243 100644 --- a/packages/compass-components/src/force-emotion-speedy.ts +++ b/packages/compass-components/src/force-emotion-speedy.ts @@ -17,7 +17,7 @@ import { sheet } from '@leafygreen-ui/emotion'; * Historically "speedy" mode was only active in production because editing * styles in the browser devtools didn't work otherwise, nowadays there is no * reason to not use it always, so there should be no downsides to doing this. - * + * * See also https://github.com/10gen/compass-data-explorer/pull/11 where we * already ran into a similar issue. */