Skip to content

Assets compilation bottlenecks

Javi Martín edited this page Mar 25, 2024 · 4 revisions

While investigating why compiling assets is taking so long, here are my findings when running RAILS_ENV=production fnm exec bundle exec rails assets:precompile on my machine using Consul Democracy 2.1.1. Before each run, I deleted already compiled assets with rm -r tmp/cache/ public/assets.

  • Regular compilation: 58.623 seconds
  • Excluding application.js: 49.292 seconds
  • Excluding application.scss: 32.825 seconds
  • Excluding both application.js and application.scss: 24.917 seconds
  • Excluding everything in the app/assets/config/manifest.js file: 14.919 seconds
  • Excluding everything and removing graphiql-rails: 12.421 seconds
  • Excluding everything and removing graphiql-rails and CKEditor: 4.464 seconds
  • Excluding everything and removing graphiql-rails CKEditor and font-awesome: 4.296 seconds

So we've got (approximately) the following bottlenecks:

  • application.scss takes about 44% of the compilation time
  • application.js takes about 16% of the compilation time
  • CKEditor assets take about 14% of the compilation time

Every other asset in the manifest takes about 2%-5% of the compilation time, while loading the application itself takes about 7% of the compilation time.

Splitting application.scss in two files (one for our CSS and one for vendored CSS) we get:

  • About 85% of the time needed to compile application.scss is caused by our own CSS
  • About 15% of the time needed to compile application.scss is caused by vendored CSS

So it looks like we've got a few ways of reducing compilation time:

  1. Use sassc-embedded instead of sassc (this reduces compilation time in about 40%)
  2. Replace CKEditor or find a way to make its assets compile faster
  3. Write less CSS (we've got almost 15,000 thousand lines of CSS code)
  4. By the year 2027 or so (when browser support is almost universal), we could replace margin-#{$global-left} with margin-inline-start and margin-#{$global-right} with margin-inline-end and remove the need for an additional application-rtl stylesheet