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

Disable gems lookup on startup #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

sailor
Copy link

@sailor sailor commented Jan 6, 2021

On large react applications (~1000 chunks), i get some R10 errors because of the app isn't able to boot within 60 seconds.
Looking at the logs, it seems that the buildpack is trying to inject the configuration during this timeframe and it takes a few hundreds ms per file on average.

This is what a typical trace looks like

2021-01-06T22:53:04.296033+00:00 app[web.1]: Injecting runtime env into /app/build/static/js/358.214d2562.chunk.js (from .profile.d/inject_react_app_env.sh)
2021-01-06T22:53:04.512350+00:00 app[web.1]: Injecting runtime env into /app/build/static/js/359.3562496e.chunk.js (from .profile.d/inject_react_app_env.sh)
2021-01-06T22:53:04.682601+00:00 app[web.1]: Injecting runtime env into /app/build/static/js/36.74870549.chunk.js (from .profile.d/inject_react_app_env.sh)
2021-01-06T22:53:04.800934+00:00 app[web.1]: Injecting runtime env into /app/build/static/js/360.eb858927.chunk.js (from .profile.d/inject_react_app_env.sh)
2021-01-06T22:53:04.895693+00:00 app[web.1]: Injecting runtime env into /app/build/static/js/361.2907631a.chunk.js (from .profile.d/inject_react_app_env.sh)
2021-01-06T22:53:04.919483+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
2021-01-06T22:53:04.936292+00:00 heroku[web.1]: Stopping process with SIGKILL
2021-01-06T22:53:05.003213+00:00 heroku[web.1]: Process exited with status 137
2021-01-06T22:53:05.048418+00:00 heroku[web.1]: State changed from starting to crashed

By looking at the script, it looks like it loads a new ruby VM for each files in the bundle, which can be really slow

  ruby -E utf-8:utf-8 \
   -r /app/.heroku/create-react-app/injectable_env.rb \
   -e "InjectableEnv.replace('$js_bundle_filename')"

By disabling the loading of the gems on startup, i managed to decrease a bit the execution time for ruby-1.9.3 which is the version used by this buildpack:

  ruby -E utf-8:utf-8 \
   -r /app/.heroku/create-react-app/injectable_env.rb \
   -e "InjectableEnv.replace('$js_bundle_filename')" \
   --disable-gems

With the gems autoloading enabled (on a macbook pro with 4 cores and 1000 js files)

time .profile.d/inject_react_app_env.sh
.profile.d/inject_react_app_env.sh  13.07s user 6.86s system 90% cpu 22.003 total

Without:

time .profile.d/inject_react_app_env.sh
.profile.d/inject_react_app_env.sh  9.97s user 7.24s system 83% cpu 20.686 total

Fun fact, ruby 3.0 is way slower than 1.9.3 to start, so this patch is even more important

With gems:

time .profile.d/inject_react_app_env.sh
.profile.d/inject_react_app_env.sh  58.70s user 14.98s system 93% cpu 1:18.48 total

Without:

time .profile.d/inject_react_app_env.sh
.profile.d/inject_react_app_env.sh  12.23s user 8.16s system 84% cpu 24.011 total

My gut feeling is that on a typical dyno where the I/O are a bit slow than on my local machine, it can have a big impact and reduce the amount of time spent on the inject variable stage.

I will also try to reduce the number of files inspected in another PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant