Join the Effort to Speed Up Meteor bundler

It’s likely that many Meteor applications will still lack clearly defined entry points for client and server code. In other words, the meteor.mainModule keys in the package.json may not specify the initial files to load for both the client and server. If you create a new Meteor app using meteor create, you’ll see an example of how this configuration should look in the package.json.

The first step in improving performance is to define these entry points. By doing so, the Meteor bundler skip eagerly loading JavaScript modules, so identifying all modules used in the app, even those not directly referenced.

If you’re unable to modify the entry points or just want to compare performance without them first, you can use the METEOR_CLIENT_ENTRYPOINT and METEOR_SERVER_ENTRYPOINT environment variables. These variables should point to the initial client and server files or any other client-only and server-only files you wish to test. The profiling script then makes a change to these files, adding and removing a line, to simulate changes and trigger a rebuild for the time to be measured.

Let me know if you’ve tried profiling using these environment variables and whether defining entry points improves performance.

I think it’s not 60% faster. It’s 3 times faster or 200% faster than the original (3.2)

1 Like

You’re absolutely right! I refer instead on the percentage of execution time decreased. Let me update that quickly. Thanks!

1 Like

Thank you.
I created an empty main.js on the client and one on the server.

Result :

===============================
 Meteor version - METEOR@3.2
===============================
 Meteor options - --settings settings.json --exclude-archs web.browser.legacy,web.cordova
===============================
===============================
Metrics - Cold start
===============================
 - Meteor(resolveConstraints): 3788 ms       |
 - Meteor(prepareProjectForBuild): 30741 ms
 - Meteor(Build App): 70443 ms
 - Meteor(Server startup): 4647 ms
 * Total(Meteor): 109619 ms
===============================
Metrics - Cache start
===============================
 - Meteor(resolveConstraints): 921 ms        /
 - Meteor(prepareProjectForBuild): 4411 ms
 - Meteor(Build App): 36184 ms
 - Meteor(Server startup): 4260 ms
 * Total(Meteor): 45776 ms                   -
===============================
Metrics - Rebuild client
===============================
 - Meteor(resolveConstraints): 908 ms        |
 - Meteor(prepareProjectForBuild): 4659 ms
 - Meteor(Build App): 34327 ms
 - Meteor(Server startup): 4138 ms
 - Meteor(Rebuild App): 3781 ms
 - Meteor(Rebuild App)#2: 3340 ms
 * Total(Meteor): 51153 ms                   /
===============================
Metrics - Rebuild server
===============================
 - Meteor(resolveConstraints): 908 ms        \
 - Meteor(prepareProjectForBuild): 4477 ms
 - Meteor(Build App): 34393 ms
 - Meteor(Server startup): 4081 ms
 - Meteor(Rebuild App): 5459 ms
 - Meteor(Rebuild App)#2: 5164 ms
 * Total(Meteor): 54482 ms                   /

And il the log file :

| Top leaves:
| Babel.compile...........................................38,930 ms (3188)
| jsAnalyze.parse..........................................6,429 ms (9750)
| other plugin templating-compiler.........................5,473 ms (1)
| getPrelinkedFiles toStringWithSourceMap..................2,446 ms (354)
| linker File#getPrelinkedOutput...........................1,857 ms (6993)
| other linker File#computeAssignedVariables...............1,206 ms (7008)
| files.readFile...........................................1,114 ms (10730)
| files.writeFile..........................................1,066 ms (9014)
| other reifyCompileWithCache................................958 ms (688)
| other linker Module#getPrelinkedFiles......................755 ms (354)
| other PackageSourceBatch#_linkJS...........................644 ms (354)
| files.readdirWithTypes.....................................589 ms (13156)
| files.stat.................................................581 ms (19667)
| sha1.......................................................447 ms (43644)
| other ImportScanner#resolve................................396 ms (6784)
| other ImportScanner#findImportedModuleIdentifiers..........381 ms (5537)
| other Target#_emitResources................................335 ms (2)
| other ClientTarget#write...................................290 ms (1)
| files.rm_recursive.........................................290 ms (357)
| other ImportScanner#scanImports for webapp.................282 ms (2)
| other ImportScanner#scanImports for universe:i18n..........255 ms (2)
| findImportedModuleIdentifiersVisitor.......................249 ms (3729)
| other ImportScanner#realPath...............................225 ms (9022)
| files.rename...............................................212 ms (2746)
| other JsImage#write........................................212 ms (1)
| other ImportScanner#scanImports for rationalk:erp..........202 ms (2)
| files.watchFile............................................201 ms (19187)
| other linker.fullLink......................................193 ms (354)
| other PackageSource#_findSources for os....................192 ms (1)
| files.lstat................................................191 ms (16310)
| other PackageSourceBatch.computeJsOutputFilesMap...........168 ms (2)
| other bundler writeSiteArchive.............................156 ms (1)
| sha512.....................................................139 ms (5176)
| other Builder#copyNodeModulesDirectory.....................126 ms (39)
| other safeWatcher.watch....................................121 ms (42737)
| other compileUnibuild (the app)............................109 ms (3)
| other bundler writeFile....................................100 ms (3274)
| 
| (#3) Total: 70,443 ms (Build App)
1 Like

Thanks for sharing your profiles. I’m curious about the main entry points for meteor.mainModule in your app. For example, a configuration in package.json might look like this:

{
  ...
  "meteor": {
    "mainModule": {
      "client": "ui/main.jsx",
      "server": "api/main.js"
    }
  }
  ...
}

These entry points act as the files that load all the other modules for the client and server. Using these entry points ensures only the “tree” files that are actually imported by these files get loaded, rather than eagerly loading every JS file in your project folder. Setting this up could be a helpful improvement, and I’d like to know if it makes any difference in the profiles. Could you try this and get again the profiles? Or is there a particular limitation preventing you from configuring it this way?

Hello,
Our app is very large and I do not know how to convert our actual structure to the one you describe using entry files

How we do it now :

EDIT : I have just realized that creating empty entry points break our apps… I will revert to NO entry points

I tried running meteor profile XXX instead of meteor run XXX for our app, but it crashed after a while. Is there any additional diagnostic output I can enable?

The error in the log file is:
/…/node_modules/.cache/meteor/performance/scripts/monitor-bundler.sh: line 189: 59655 Killed: 9 METEOR_PROFILE=“${METEOR_PROFILE:-1}}” METEOR_PACKAGE_DIRS=“${METEOR_PACKAGE_DIRS}” ${meteorCmd} run ${meteorOptions}

The output on the command line (slightly redacted):

===============================               
 Profile script
===============================
 - App path: /PATH
 - App port: 3000
 - Logs file: /PATH/logs/1743447797259-refapp-bundle.log
===============================
===============================
 Full log details at /PATH/logs/1743447797259-refapp-bundle.log
===============================
 * Profiling "Cold start"...                 |
===============================              -
 An error occurred when profiling. For more details, check at /PATH/logs/1743447797259-refapp-bundle.log
===============================
zsh: killed     yarn debug:nointegrations:profile

From cold start the profiler crashes on me:

| (#3) Profiling: Build App
/home/storyteller/Web/Literary-Universe/app/node_modules/.cache/meteor/performance/scripts/monitor-bundler.sh: line 189: 1051493 Killed 

Entrypoints should be files that serve as the starting point for importing the rest of the project. Due to the nature of the project (possibly related to Blaze or FlowRouter), it might not support entrypoints. Since I’m not familiar with that stack, I can’t confirm. Perhaps @jkuester or @harry97 could provide more insight. Have you seen any Blaze projects defining “meteor.mainModule” entrypoints?

Thanks for adding this feature, the profiler works well in this 2019 app upgraded all the way to Meteor 3.2 :rocket: with the entrypoints in package.json

[Edit] updating the relevant parts here :

| Top leaves:
| other bundler.bundle....................................27,707 ms (1)
| Babel.compile...........................................14,734 ms (1646)
| other ImportScanner#scanImports for the app..............2,117 ms (3)
| other sqlite query.......................................1,902 ms (6)
| jsAnalyze.parse..........................................1,744 ms (6317)
| files.readFile...........................................1,263 ms (19076)
| getPrelinkedFiles toStringWithSourceMap..................1,079 ms (343)
| other ImportScanner#scanImports for allohouston:ys-crossfilter.700 ms (2).  <- custom package
| other plugin templating-compiler...........................647 ms (2)
| linker File#getPrelinkedOutput.............................558 ms (6890)
| files.writeFile............................................510 ms (3672)
| files.readdirWithTypes.....................................508 ms (24876)
| other linker File#computeAssignedVariables.................478 ms (5663)
| other ImportScanner#scanImports for allohouston:general....430 ms (3) <- custom package
| other ImportScanner#resolve................................420 ms (11854)
| files.stat.................................................313 ms (19709)
| other reifyCompileWithCache................................301 ms (2319)
| other PackageSourceBatch#_linkJS...........................278 ms (343)
| files.rename...............................................215 ms (2783)
| other compileUnibuild (the app)............................205 ms (3)
| CssTools.stringifyCss......................................201 ms (664)
| other ImportScanner#scanImports for universe:i18n..........156 ms (3)
| other ImportScanner#scanImports for base64.................147 ms (3)
| other ImportScanner#findImportedModuleIdentifiers..........140 ms (5426)
| other ImportScanner#realPath...............................133 ms (6061)
| files.watchFile............................................121 ms (20717)
| other PackageSource#_findSources for os....................109 ms (2)
| files.rm_recursive.........................................108 ms (347)
| 
| (#3) Total: 29,823 ms (Build App)



===============================
Metrics - Cold start
===============================
 - Meteor(resolveConstraints): 2111 ms
 - Meteor(prepareProjectForBuild): 8703 ms
 - Meteor(Build App): 32479 ms
 - Meteor(Server startup): 1760 ms
 * Total(Meteor): 45053 ms
===============================
Metrics - Cache start
===============================
 - Meteor(resolveConstraints): 376 ms
 - Meteor(prepareProjectForBuild): 1292 ms
 - Meteor(Build App): 11219 ms
 - Meteor(Server startup): 852 ms
 * Total(Meteor): 13739 ms
===============================
Metrics - Rebuild client
===============================
 - Meteor(resolveConstraints): 285 ms
 - Meteor(prepareProjectForBuild): 624 ms
 - Meteor(Build App): 8632 ms
 - Meteor(Server startup): 815 ms
 - Meteor(prepareProjectForBuild #1): 39 ms
 - Meteor(Rebuild App #1): 1128 ms
 - Meteor(prepareProjectForBuild #2): 42 ms
 - Meteor(Rebuild App #2): 874 ms
 * Total(Meteor): 12439 ms
===============================
Metrics - Rebuild server
===============================
 - Meteor(resolveConstraints): 371 ms
 - Meteor(prepareProjectForBuild): 1151 ms
 - Meteor(Build App): 9272 ms
 - Meteor(Server startup): 1154 ms
 - Meteor(prepareProjectForBuild #1): 32 ms
 - Meteor(Rebuild App #1): 1505 ms
 - Meteor(Server startup #1): 826 ms
 - Meteor(prepareProjectForBuild #2): 29 ms
 - Meteor(Rebuild App #2): 1298 ms
 - Meteor(Server startup #2): 805 ms
 * Total(Meteor): 16443 ms


===============================              -
 Npm packages
===============================
                                             \
📦️  Dependencies

┌─────────┬───────────────────────────┬──────────────────────────────┬──────────────────────────────┬───────────────────────┐
│ (index) │ 0                         │ 1                            │ 2                            │ 3                     │
├─────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────┼───────────────────────┤
│ 0       │ '@babel/runtime@^7.26.10' │ 'autoprefixer@^8.6.3'        │ 'cidr-tools@^11.0.3'         │ 'clamscan@^2.1.2'     │
│ 1       │ 'console-stamp@^3.1.2'    │ 'core-js@^2.5.3'             │ 'crossfilter2@^1.4.7'        │ 'crypto-js@^4.1.1'    │
│ 2       │ 'd3@^6.7.0'               │ 'dc@^3.1.5'                  │ 'faker@^4.1.0'               │ 'file-saver@^1.3.8'   │
│ 3       │ 'intl@^1.2.5'             │ 'jquery@^3.4.1'              │ 'js-yaml@^3.13.1'            │ 'js2xmlparser@^4.0.0' │
│ 4       │ 'kafka-node@^5.0.0'       │ 'meteor-accounts-t9n@^2.5.2' │ 'meteor-node-stubs@^1.2.5'   │ 'moment@^2.29.4'      │
│ 5       │ 'papaparse@^5.3.1'        │ 'postcss@^8.5.3'             │ 'postcss-load-config@^6.0.1' │ 'select2@^4.0.3'      │
│ 6       │ 'simpl-schema@^1.5.5'     │ 'snappy@^6.0.1'              │ 'striptags@^3.2.0'           │ 'sweetalert2@^11.1.9' │
│ 7       │ 'tippy.js@^6.3.7'         │ 'unescape@^1.0.1'            │ 'xml2js@^0.6.2'              │ 'xss@^0.3.7'          │
└─────────┴───────────────────────────┴──────────────────────────────┴──────────────────────────────┴───────────────────────┘

🛠️  DevDependencies

┌─────────┬────────────────────────────────────┬────────────────────────────────────────────┬────────────────────────────────────────┬────────────────────────────────┐
│ (index) │ 0                                  │ 1                                          │ 2                                      │ 3                              │
├─────────┼────────────────────────────────────┼────────────────────────────────────────────┼────────────────────────────────────────┼────────────────────────────────┤
│ 0       │ '@babel/eslint-parser@^7.23.10'    │ '@babel/preset-react@^7.16.7'              │ '@types/meteor@^2.9.8'                 │ '@types/react@^18.2.65'        │
│ 1       │ '@types/react-router-dom@^5.3.3'   │ '@typescript-eslint/eslint-plugin@^5.62.0' │ '@typescript-eslint/parser@^5.62.0'    │ 'chai@^5.2.0'                  │
│ 2       │ 'eslint@^8.57.0'                   │ 'eslint-config-prettier@^9.1.0'            │ 'eslint-import-resolver-meteor@^0.4.0' │ 'eslint-plugin-import@^2.29.1' │
│ 3       │ 'eslint-plugin-jsx-a11y@^6.8.0'    │ 'eslint-plugin-meteor@^7.3.0'              │ 'eslint-plugin-promise@^7.1.0'         │ 'eslint-plugin-react@^7.33.2'  │
│ 4       │ 'eslint-plugin-react-hooks@^4.6.2' │ 'husky@^4.3.8'                             │ 'prettier@^3.0.3'                      │                                │
└─────────┴────────────────────────────────────┴────────────────────────────────────────────┴────────────────────────────────────────┴────────────────────────────────┘
===============================
===============================
 Meteor packages
===============================

☄️  Atmosphere

┌─────────┬─────────────────────────────────────┬─────────────────────────────────────┬────────────────────────────────────────────┬─────────────────────────────────────────┐
│ (index) │ 0                                   │ 1                                   │ 2                                          │ 3                                       │
├─────────┼─────────────────────────────────────┼─────────────────────────────────────┼────────────────────────────────────────────┼─────────────────────────────────────────┤
│ 0       │ 'accounts-base@3.1.0'               │ 'accounts-oauth@1.4.6'              │ 'accounts-password@3.1.0'                  │ 'aldeed:collection2@4.1.1'              │
│ 1       │ 'aldeed:simple-schema@1.13.1'       │ 'aldeed:template-extension@0.1.0'   │ 'allohouston:sso@3.0.0'                │ 'allohouston:general@3.3.0'             │
│ 2       │ 'allohouston:login@0.1.0'           │ 'allohouston:tools@0.1.0'           │ 'allow-deny@2.1.0'                         │ 'autoupdate@2.0.0'                      │
│ 3       │ 'babel-compiler@7.11.3'             │ 'babel-runtime@1.5.2'               │ 'base64@1.0.13'                            │ 'binary-heap@1.0.12'                    │
│ 4       │ 'blaze@3.0.2'                       │ 'blaze-html-templates@3.0.0'        │ 'blaze-tools@2.0.0'                        │ 'boilerplate-generator@2.0.0'           │
│ 5       │ 'caching-compiler@2.0.1'            │ 'caching-html-compiler@2.0.0'       │ 'callback-hook@1.6.0'                      │ 'check@1.4.4'                           │
│ 6       │ 'core-runtime@1.0.0'                │ 'cultofcoders:grapher@2.0.0-beta.1' │ 'dburles:mongo-collection-instances@1.0.0' │ 'ddp@1.4.2'                             │
│ 7       │ 'ddp-client@3.1.0'                  │ 'ddp-common@1.4.4'                  │ 'ddp-rate-limiter@1.2.2'                   │ 'ddp-server@3.1.0'                      │
│ 8       │ 'diff-sequence@1.1.3'               │ 'dynamic-import@0.7.4'              │ 'ecmascript@0.16.10'                       │ 'ecmascript-runtime@0.8.3'              │
│ 9       │ 'ecmascript-runtime-client@0.12.3'  │ 'ecmascript-runtime-server@0.11.1'  │ 'ejson@1.1.4'                              │ 'email@3.1.2'                           │
│ 10      │ 'es5-shim@4.8.1'                    │ 'facts-base@1.0.2'                  │ 'fetch@0.1.6'                              │ 'fortawesome:fontawesome@4.7.0'         │
│ 11      │ 'froala:editor@2.8.5'               │ 'froala:editor-reactive@2.8.5'      │ 'geojson-utils@1.0.12'                     │ 'herteby:denormalize@0.7.0-rc.1'        │
│ 12      │ 'hot-code-push@1.0.5'               │ 'html-tools@2.0.0'                  │ 'htmljs@2.0.1'                             │ 'http@1.4.4'                            │
│ 13      │ 'id-map@1.2.0'                      │ 'inter-process-messaging@0.1.2'     │ 'jquery@3.0.2'                             │ 'lai:collection-extensions@1.0.0'       │
│ 14      │ 'launch-screen@2.0.1'               │ 'less@4.1.1'                        │ 'localstorage@1.2.1'                       │ 'logging@1.3.6'                         │
│ 15      │ 'matb33:collection-hooks@2.0.0'     │ 'mdg:validated-method@1.3.0'        │ 'meteor@2.1.0'                             │ 'meteor-base@1.5.2'                     │
│ 16      │ 'meteortesting:browser-tests@1.7.0' │ 'meteortesting:mocha@3.2.0'         │ 'meteortesting:mocha-core@8.2.0'           │ 'minifier-css@2.0.1'                    │
│ 17      │ 'minifier-js@3.0.1'                 │ 'minimongo@2.0.2'                   │ 'mobile-experience@1.1.2'                  │ 'mobile-status-bar@1.1.1'               │
│ 18      │ 'modern-browsers@0.2.1'             │ 'modules@0.20.3'                    │ 'modules-runtime@0.13.2'                   │ 'mongo@2.1.1'                           │
│ 19      │ 'mongo-decimal@0.2.0'               │ 'mongo-dev-server@1.1.1'            │ 'mongo-id@1.0.9'                           │ 'montiapm:agent@3.0.0-beta.14'          │
│ 20      │ 'montiapm:meteorx@2.3.1'            │ 'msavin:sjobs@5.0.0'                │ 'npm-mongo@6.10.2'                         │ 'oauth@3.0.2'                           │
│ 21      │ 'oauth2@1.3.3'                      │ 'observe-sequence@2.0.0'            │ 'ordered-dict@1.2.0'                       │ 'ostrio:cookies@2.8.1'                  │
│ 22      │ 'ostrio:files@3.0.0-beta.6'         │ 'ostrio:flow-router-extra@3.12.0'   │ 'percolate:migrations@2.0.0'               │ 'percolate:momentum@0.7.3'              │
│ 23      │ 'promise@1.0.0'                     │ 'raix:eventemitter@1.0.0'           │ 'random@1.2.2'                             │ 'rate-limit@1.1.2'                      │
│ 24      │ 'react-fast-refresh@0.2.9'          │ 'reactive-dict@1.3.2'               │ 'reactive-var@1.0.13'                      │ 'reload@1.3.2'                          │
│ 25      │ 'retry@1.1.1'                       │ 'reywood:publish-composite@1.8.12'  │ 'roles@1.0.1'                              │ 'routepolicy@1.1.2'                     │
│ 26      │ 'service-configuration@1.3.5'       │ 'session@1.2.2'                     │ 'sha@1.0.10'                               │ 'shell-server@0.6.1'                    │
│ 27      │ 'socket-stream-client@0.6.0'        │ 'spacebars@2.0.0'                   │ 'spacebars-compiler@2.0.0'                 │ 'standard-minifier-css@1.9.3'           │
│ 28      │ 'standard-minifier-js@3.0.0'        │ 'templating@1.4.4'                  │ 'templating-compiler@2.0.0'                │ 'templating-runtime@2.0.1'              │
│ 29      │ 'templating-tools@2.0.0'            │ 'tracker@1.3.4'                     │ 'typescript@5.6.3'                         │ 'underscore@1.6.4'                      │
│ 30      │ 'universe:i18n@3.0.1'               │ 'url@1.3.5'                         │ 'useraccounts:core@1.17.2'                 │ 'useraccounts:flow-routing-extra@1.1.0' │
│ 31      │ 'useraccounts:unstyled@1.14.2'      │ 'webapp@2.0.5'                      │ 'webapp-hashing@1.1.2'                     │ 'xolvio:cleaner@0.3.0'                  │
│ 32      │ 'yellowsquare:ys-crossfilter@0.1.0' │ 'ziarno:restrict-mixin@0.0.5'       │ 'zodern:meteor-package-versions@0.2.2'     │ 'zodern:types@1.0.13'                   │
└─────────┴─────────────────────────────────────┴─────────────────────────────────────┴────────────────────────────────────────────┴─────────────────────────────────────────┘

@permb and @storyteller: Could you try running the profile with a higher idle timeout, such as with the env METEOR_IDLE_TIMEOUT=360?

The default is 1.5 minutes (METEOR_IDLE_TIMEOUT=90), but it seems possible that some apps, especially during cold starts without a cache, might take longer. Increasing the timeout will help confirm if that’s the case. I’ve suggested a higher value above to rule out other issues, though hopefully it won’t take more than six minutes for you.:sweat_smile: In any case, SWC will help significantly. :crossed_fingers:

The summary will be enough for now. Including the initial (#3) Total: xx ms (Build App) section with the Top leaves would help confirm the most common profile processes. It’s likely they’ll match what we and others typically see, but it’s worth checking in case something different shows up.

In any case, we’ll see the new results once the first 3.3 beta is available with SWC and other optimizations. Thank you for your help!

Your question got me opening up the project I spoke of on here and yes we’re using entrypoints:

"meteor": {
        "mainModule": {
            "client": "imports/startup/client/index.js",
            "server": "imports/startup/server/index.js"
        }
    },

EDIT: We’re currently on 3.1 but I’ll definitely work on updating our application to the latest version so we can help in the bundle improvements efforts.

1 Like

Whether using Blaze or React, entry points define where your application starts running on both the client and server sides. These are specified in your package.json file under the "meteor" section. You can take a look at our tutorial app to understand it.

This tells Meteor which files to execute first when the application starts:
package.json

"meteor": {
    "mainModule": {
      "client": "client/main.js",
      "server": "server/main.js"
    },
  },

This is the starting point for all client-side code:
client/main.js

import '../imports/ui/App.js';

Here, you should import UI components and client-specific modules.


This is where server-side code begins execution:
server/main.js

import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { TasksCollection } from '/imports/db/TasksCollection';
import '/imports/api/tasksMethods';
import '/imports/api/tasksPublications';
...

Here, you should import server-specific code like database collections, methods, and publications.

1 Like

@nachocodoner Here is the command and output:

~/Web/Literary-Universe/app git:[develop]
METEOR_IDLE_TIMEOUT=360 meteor profile --settings settings.local.json --port 4200 --exclude-archs web.browser.legacy,web.cordova
===============================              \
 Profile script
===============================
 - App path: /home/storyteller/Web/Literary-Universe/app
 - App port: 4200
 - Logs file: /home/storyteller/Web/Literary-Universe/app/logs/1743520020900-app-bundle.log
===============================
===============================
 Full log details at /home/storyteller/Web/Literary-Universe/app/logs/1743520020900-app-bundle.log
===============================
 * Profiling "Cold start"...                 |
 * Profiling "Cache start"...                /
 * Profiling "Rebuild client"...             |
 * Profiling "Rebuild server"...             -
===============================              /
 Npm packages
===============================

📦️  Dependencies

┌─────────┬────────────────────────────────────────┬─────────────────────────────────────────┬─────────────────────────────────────────┬────────────────────────────────────────────┐
│ (index) │ 0                                      │ 1                                       │ 2                                       │ 3                                          │
├─────────┼────────────────────────────────────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼────────────────────────────────────────────┤
│ 0       │ '@apollo/client@3.13.5'                │ '@apollo/server@4.11.3'                 │ '@ariakit/react@0.4.15'                 │ '@babel/runtime@7.27.0'                    │
│ 1       │ '@graphql-tools/merge@9.0.24'          │ '@graphql-tools/schema@10.0.23'         │ '@graphql-tools/utils@10.8.6'           │ '@hello-pangea/dnd@18.0.1'                 │
│ 2       │ '@ladjs/country-language@1.0.3'        │ '@literary-universe/styled-icons@0.8.2' │ '@meteorjs/ddp-graceful-shutdown@0.9.2' │ '@stripe/connect-js@3.3.21'                │
│ 3       │ '@stripe/react-connect-js@3.3.21'      │ '@stripe/react-stripe-js@3.5.1'         │ '@stripe/stripe-js@6.1.0'               │ '@tiptap/extension-character-count@2.11.7' │
│ 4       │ '@tiptap/extension-focus@2.11.7'       │ '@tiptap/extension-font-family@2.11.7'  │ '@tiptap/extension-image@2.11.7'        │ '@tiptap/extension-link@2.11.7'            │
│ 5       │ '@tiptap/extension-placeholder@2.11.7' │ '@tiptap/extension-table@2.11.7'        │ '@tiptap/extension-table-cell@2.11.7'   │ '@tiptap/extension-table-header@2.11.7'    │
│ 6       │ '@tiptap/extension-table-row@2.11.7'   │ '@tiptap/extension-text-align@2.11.7'   │ '@tiptap/extension-text-style@2.11.7'   │ '@tiptap/extension-underline@2.11.7'       │
│ 7       │ '@tiptap/pm@2.11.7'                    │ '@tiptap/react@2.11.7'                  │ '@tiptap/starter-kit@2.11.7'            │ 'bcrypt@5.1.1'                             │
│ 8       │ 'filestack-adaptive@1.4.0'             │ 'filestack-js@3.39.5'                   │ 'final-form@4.20.10'                    │ 'final-form-arrays@3.1.0'                  │
│ 9       │ 'final-form-calculate@1.3.2'           │ 'final-form-focus@1.1.2'                │ 'graphql@16.10.0'                       │ 'graphql-depth-limit@1.1.0'                │
│ 10      │ 'graphql-scalars@1.24.2'               │ 'immutable@5.1.1'                       │ 'input-otp@1.4.2'                       │ 'match-sorter@8.0.0'                       │
│ 11      │ 'message-box@1.0.0'                    │ 'meteor-node-stubs@1.2.13'              │ 'mjml@4.15.3'                           │ 'polished@4.3.1'                           │
│ 12      │ 'react@19.1.0'                         │ 'react-accessible-accordion@5.0.0'      │ 'react-dom@19.1.0'                      │ 'react-final-form@6.5.9'                   │
│ 13      │ 'react-final-form-arrays@3.1.4'        │ 'react-helmet-async@2.0.5'              │ 'react-intl@7.1.10'                     │ 'react-responsive@10.0.1'                  │
│ 14      │ 'react-router-dom@6.30.0'              │ 'regenerator-runtime@0.14.1'            │ 'stripe@17.7.0'                         │ 'strman@2.0.1'                             │
│ 15      │ 'styled-components@6.1.16'             │ 'styled-tools@1.7.2'                    │ 'validator@13.15.0'                     │ 'victory@37.3.6'                           │
│ 16      │ 'xml2js@0.6.2'                         │ 'xss@1.0.15'                            │                                         │                                            │
└─────────┴────────────────────────────────────────┴─────────────────────────────────────────┴─────────────────────────────────────────┴────────────────────────────────────────────┘

🛠️  DevDependencies

┌─────────┬─────────────────────────────────────────────────────────────┬──────────────────────────────────────────────┬─────────────────────────────────────────────────┬───────────────────────────────────────────┐
│ (index) │ 0                                                           │ 1                                            │ 2                                               │ 3                                         │
├─────────┼─────────────────────────────────────────────────────────────┼──────────────────────────────────────────────┼─────────────────────────────────────────────────┼───────────────────────────────────────────┤
│ 0       │ '@babel/core@7.26.10'                                       │ '@babel/preset-env@7.26.9'                   │ '@babel/preset-react@7.26.3'                    │ '@biomejs/biome@1.9.4'                    │
│ 1       │ '@chromatic-com/storybook@3.2.6'                            │ '@cypress/code-coverage@3.14.0'              │ '@storybook/addon-a11y@^8.6.11'                 │ '@storybook/addon-designs@^8.2.1'         │
│ 2       │ '@storybook/addon-essentials@^8.6.11'                       │ '@storybook/addon-interactions@^8.6.11'      │ '@storybook/addon-links@^8.6.11'                │ '@storybook/addon-mdx-gfm@^8.6.11'        │
│ 3       │ '@storybook/addon-onboarding@^8.6.11'                       │ '@storybook/addon-themes@^8.6.11'            │ '@storybook/addon-webpack5-compiler-swc@^1.0.6' │ '@storybook/blocks@^8.6.11'               │
│ 4       │ '@storybook/react@^8.6.11'                                  │ '@storybook/react-webpack5@^8.6.11'          │ '@storybook/test@^8.6.11'                       │ '@storybook/theming@^8.6.11'              │
│ 5       │ '@testing-library/cypress@10.0.3'                           │ '@types/final-form-focus@1.1.7'              │ '@types/meteor-sjobs@4.0.8'                     │ '@types/mjml@4.7.4'                       │
│ 6       │ '@types/node@22.13.16'                                      │ '@types/react@19.0.12'                       │ '@types/react-dom@19.0.4'                       │ '@types/stripe-v3@3.1.33'                 │
│ 7       │ '@types/strman@2.0.3'                                       │ '@types/validator@13.12.3'                   │ '@types/xml2js@0.4.14'                          │ '@whatwg-node/node-fetch@0.7.17'          │
│ 8       │ 'babel-plugin-istanbul@7.0.0'                               │ 'babel-plugin-jsx-remove-data-test-id@3.0.0' │ 'babel-plugin-macros@3.1.0'                     │ 'babel-plugin-object-to-json-parse@0.2.3' │
│ 9       │ 'babel-plugin-react-compiler@^19.0.0-beta-e993439-20250328' │ 'babel-plugin-styled-components@2.1.4'       │ 'chai@^5.2.0'                                   │ 'cypress@14.2.1'                          │
│ 10      │ 'storybook@^8.6.11'                                         │ 'storybook-addon-remix-react-router@^3.1.0'  │ 'storybook-react-intl@^3.2.3'                   │ 'typescript@5.8.2'                        │
│ 11      │ 'webpack@5.98.0'                                            │                                              │                                                 │                                           │
└─────────┴─────────────────────────────────────────────────────────────┴──────────────────────────────────────────────┴─────────────────────────────────────────────────┴───────────────────────────────────────────┘
===============================
===============================
 Meteor packages
===============================

☄️  Atmosphere

┌─────────┬──────────────────────────────────────────────┬────────────────────────────────────────────────┬───────────────────────────────────────────────┬───────────────────────────────────────┐
│ (index) │ 0                                            │ 1                                              │ 2                                             │ 3                                     │
├─────────┼──────────────────────────────────────────────┼────────────────────────────────────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────┤
│ 0       │ 'accounts-2fa@3.0.1'                         │ 'accounts-base@3.1.0'                          │ 'accounts-facebook@1.3.4'                     │ 'accounts-google@1.4.1'               │
│ 1       │ 'accounts-meteor-developer@1.5.1'            │ 'accounts-oauth@1.4.6'                         │ 'accounts-password@3.1.0'                     │ 'accounts-twitter@1.5.2'              │
│ 2       │ 'aldeed:collection2@4.1.1'                   │ 'aldeed:schema-deny@4.0.2'                     │ 'aldeed:schema-index@4.0.0-beta.5'            │ 'aldeed:simple-schema@2.0.0'          │
│ 3       │ 'allow-deny@2.1.0'                           │ 'apollo@5.0.1-beta.0'                          │ 'audit-argument-checks@1.0.8'                 │ 'autoupdate@2.0.0'                    │
│ 4       │ 'babel-compiler@7.11.3'                      │ 'babel-runtime@1.5.2'                          │ 'base64@1.0.13'                               │ 'binary-heap@1.0.12'                  │
│ 5       │ 'boilerplate-generator@2.0.0'                │ 'bozhao:link-accounts@3.0.1'                   │ 'caching-compiler@2.0.1'                      │ 'callback-hook@1.6.0'                 │
│ 6       │ 'check@1.4.4'                                │ 'core-runtime@1.0.0'                           │ 'ddp@1.4.2'                                   │ 'ddp-client@3.1.0'                    │
│ 7       │ 'ddp-common@1.4.4'                           │ 'ddp-rate-limiter@1.2.2'                       │ 'ddp-server@3.1.0'                            │ 'dev-error-overlay@0.1.3'             │
│ 8       │ 'diff-sequence@1.1.3'                        │ 'dynamic-import@0.7.4'                         │ 'ecmascript@0.16.10'                          │ 'ecmascript-runtime@0.8.3'            │
│ 9       │ 'ecmascript-runtime-client@0.12.3'           │ 'ecmascript-runtime-server@0.11.1'             │ 'ejson@1.1.4'                                 │ 'email@3.1.2'                         │
│ 10      │ 'es5-shim@4.8.1'                             │ 'facebook-oauth@1.11.6'                        │ 'facts-base@1.0.2'                            │ 'fetch@0.1.6'                         │
│ 11      │ 'force-ssl@1.1.1'                            │ 'force-ssl-common@1.1.1'                       │ 'freedombase:flashnews@1.0.1'                 │ 'freedombase:forums@0.0.4'            │
│ 12      │ 'freedombase:legal-management@2.0.2'         │ 'freedombase:payments-checkout@0.0.1'          │ 'freedombase:payments-core@0.0.1'             │ 'freedombase:payments-platform@0.0.1' │
│ 13      │ 'freedombase:payments-provider-stripe@0.0.1' │ 'freedombase:payments-subscriptions@0.0.1'     │ 'geojson-utils@1.0.12'                        │ 'google-oauth@1.4.5'                  │
│ 14      │ 'hot-code-push@1.0.5'                        │ 'hot-module-replacement@0.5.4'                 │ 'id-map@1.2.0'                                │ 'inter-process-messaging@0.1.2'       │
│ 15      │ 'jam:offline@0.3.2'                          │ 'jam:pub-sub@0.3.2'                            │ 'launch-screen@2.0.1'                         │ 'localstorage@1.2.1'                  │
│ 16      │ 'logging@1.3.6'                              │ 'lu-intl@2.15.4'                               │ 'matb33:collection-hooks@2.0.0'               │ 'mdg:seo@3.5.2'                       │
│ 17      │ 'meteor@2.1.0'                               │ 'meteor-base@1.5.2'                            │ 'meteor-developer-oauth@1.3.3'                │ 'meteortesting:browser-tests@1.7.0'   │
│ 18      │ 'meteortesting:mocha@3.2.0'                  │ 'meteortesting:mocha-core@8.2.0'               │ 'minifier-js@3.0.1'                           │ 'minimongo@2.0.2'                     │
│ 19      │ 'mobile-experience@1.1.2'                    │ 'mobile-status-bar@1.1.1'                      │ 'modern-browsers@0.2.1'                       │ 'modules@0.20.3'                      │
│ 20      │ 'modules-runtime@0.13.2'                     │ 'modules-runtime-hot@0.14.3'                   │ 'mongo@2.1.1'                                 │ 'mongo-decimal@0.2.0'                 │
│ 21      │ 'mongo-dev-server@1.1.1'                     │ 'mongo-id@1.0.9'                               │ 'montiapm:agent@3.0.0-beta.14'                │ 'montiapm:meteorx@2.3.1'              │
│ 22      │ 'msavin:sjobs@5.0.0'                         │ 'natestrauser:publish-performant-counts@0.2.0' │ 'npm-mongo@6.10.2'                            │ 'oauth@3.0.2'                         │
│ 23      │ 'oauth-encryption@1.3.3'                     │ 'oauth1@1.5.2'                                 │ 'oauth2@1.3.3'                                │ 'ordered-dict@1.2.0'                  │
│ 24      │ 'ostrio:spiderable-middleware@2.2.0'         │ 'percolate:migrations@2.0.0'                   │ 'promise@1.0.0'                               │ 'raix:eventemitter@2.0.0'             │
│ 25      │ 'random@1.2.2'                               │ 'rate-limit@1.1.2'                             │ 'react-fast-refresh@0.2.9'                    │ 'react-meteor-accounts@1.0.3'         │
│ 26      │ 'react-meteor-data@3.0.3'                    │ 'react-meteor-state@1.0.0-beta.2'              │ 'reactive-dict@1.3.2'                         │ 'reactive-var@1.0.13'                 │
│ 27      │ 'reload@1.3.2'                               │ 'retry@1.1.1'                                  │ 'reywood:publish-composite@1.9.0'             │ 'roles@1.0.1'                         │
│ 28      │ 'routepolicy@1.1.2'                          │ 'server-render@0.4.2'                          │ 'service-configuration@1.3.5'                 │ 'session@1.2.2'                       │
│ 29      │ 'sha@1.0.10'                                 │ 'shell-server@0.6.1'                           │ 'socialize:base-model@2.0.0'                  │ 'socialize:commentable@2.0.0'         │
│ 30      │ 'socialize:feed@2.0.0'                       │ 'socialize:friendships@2.0.0'                  │ 'socialize:likeable@2.0.0'                    │ 'socialize:linkable-model@2.0.0'      │
│ 31      │ 'socialize:messaging@2.0.0'                  │ 'socialize:postable@2.0.0'                     │ 'socialize:requestable@2.0.0'                 │ 'socialize:server-presence@1.1.0'     │
│ 32      │ 'socialize:server-time@1.0.4'                │ 'socialize:user-blocking@2.0.0'                │ 'socialize:user-model@2.0.0'                  │ 'socialize:user-presence@2.0.0'       │
│ 33      │ 'socialize:user-profile@2.0.0'               │ 'socialize:voteable@2.0.0'                     │ 'socket-stream-client@0.6.0'                  │ 'standard-minifier-js@3.0.0'          │
│ 34      │ 'static-html@1.4.0'                          │ 'static-html-tools@1.0.0'                      │ 'storyteller:accounts-betapass@1.0.0-alpha.1' │ 'storyteller:accounts-discord@1.0.1'  │
│ 35      │ 'storyteller:accounts-line@1.3.2'            │ 'storyteller:accounts-seznam@1.0.0'            │ 'storyteller:betapass-oauth@1.0.0-alpha.1'    │ 'storyteller:cdn@2.1.4'               │
│ 36      │ 'storyteller:discord-oauth@1.0.1'            │ 'storyteller:fictionaltime@0.5.0'              │ 'storyteller:line-oauth@1.4.1'                │ 'storyteller:seznam-oauth@1.0.0'      │
│ 37      │ 'storyteller:ssl@0.3.1'                      │ 'swydo:graphql@2.0.0'                          │ 'tracker@1.3.4'                               │ 'twitter-oauth@1.3.4'                 │
│ 38      │ 'typescript@5.6.3'                           │ 'underscore@1.6.4'                             │ 'url@1.3.5'                                   │ 'webapp@2.0.5'                        │
│ 39      │ 'webapp-hashing@1.1.2'                       │ 'zodern:meteor-package-versions@0.2.2'         │ 'zodern:types@1.0.13'                         │                                       │
└─────────┴──────────────────────────────────────────────┴────────────────────────────────────────────────┴───────────────────────────────────────────────┴───────────────────────────────────────┘
===============================
===============================
 Meteor version - METEOR@3.2
===============================
 Meteor options - --settings settings.local.json --port 4200 --exclude-archs web.browser.legacy,web.cordova
===============================
===============================
Metrics - Cold start
===============================
 - Meteor(resolveConstraints): 3510 ms       |
 - Meteor(prepareProjectForBuild): 12583 ms
 - Meteor(Build App): 112697 ms
 - Meteor(Server startup): 2988 ms
 * Total(Meteor): 131778 ms
===============================
Metrics - Cache start
===============================
 - Meteor(resolveConstraints): 625 ms
 - Meteor(prepareProjectForBuild): 3066 ms
 - Meteor(Build App): 22002 ms
 - Meteor(Server startup): 2731 ms
 * Total(Meteor): 28424 ms
===============================
Metrics - Rebuild client
===============================
 - Meteor(resolveConstraints): 603 ms        -
 - Meteor(prepareProjectForBuild): 1439 ms
 - Meteor(Build App): 26396 ms
 - Meteor(Server startup): 2615 ms
 - Meteor(prepareProjectForBuild #1): 147 ms
 - Meteor(Rebuild App #1): 6674 ms
 - Meteor(prepareProjectForBuild #2): 124 ms
 - Meteor(Rebuild App #2): 5373 ms
 * Total(Meteor): 43371 ms
===============================
Metrics - Rebuild server
===============================
 - Meteor(resolveConstraints): 613 ms
 - Meteor(prepareProjectForBuild): 1340 ms
 - Meteor(Build App): 27491 ms
 - Meteor(Server startup): 2593 ms
 - Meteor(prepareProjectForBuild #1): 130 ms
 - Meteor(Rebuild App #1): 8992 ms
 - Meteor(Server startup #1): 2657 ms
 - Meteor(prepareProjectForBuild #2): 119 ms
 - Meteor(Rebuild App #2): 7011 ms
 - Meteor(Server startup #2): 2655 ms
 * Total(Meteor): 53601 ms
===============================
 Full log details at /home/storyteller/Web/Literary-Universe/app/logs/1743520020900-app-bundle.log
===============================
                                             /
1 Like

@victor, @dokithonon: Could you update your messages above to share the NPM and Atmosphere packages lists from the profile log?

Feel free to send them privately if you prefer. I got this idea from @storyteller’s performance profile, which includes a project heavily reliant on Babel with multiple plugins. That’s a great reference to see how those plugins perform as we implement SWC support. Since SWC replaces Babel, any plugins without equivalents won’t benefit from the switch. A list of dependencies would help us test them in isolation and observe how they perform.

Hello, just sent by private message

1 Like

In my case with the exception of react-compiler and to lesser degree the styled-components babel plugins, the rest I can do without. For Storybook there is either Webpack or Vite, so moving to either of them (preferably Vite) would make my setup easier.

1 Like

Sent profile on Slack DM

Interestingly, when running meteor profile instead of meteor run, the plugin cache for refapp:meteor-typescript does not seem enabled. Is that by design? If so, is there a way to re-enable it to get a profile for when caches ARE available?

Just a suggestion: if you have an app without mainModule set, Meteor generates a single file with all of the eager imports anyway – it’ll be visible in your browser’s devtools. What we did a couple of years back was copy this file verbatim (of course we replaced the reified requires into imports) into client.ts and made it the mainModule. Then you can do the same on the server – it should be easy to find with --inspect-brk.

Maybe there could be a meteor generate-main-module command to do that automatically?

2 Likes