As a result of some discussion and work inspired by this thread I’ve recently made some serious improvements in our build times for a very large app. I thought it would be helpful to share it in a new post without all the noise of the debugging post.
I should note that these changes may not be palatable by most people. It reflects that practices of the team that I’m on and we’ve determined the tradeoffs are worth it. Some of the practices that effect this are:
- We never use the
/tests
endpoint. Dev builds go throughember server
, tests go throughember test
- We do not use mirage in development, only in tests
- We nearly exclusively develop new features in chrome first and then do browser QA on a production build on our QA server
- We’ve determined that sourcemaps in dev aren’t worth the tradeoffs in subtle bugs and build time costs
Here is where we found some of the biggest wins. Some of these may be obvious to you, but it wasn’t immediately for us:
- Disable build time linting, except for the test environment
- Disable build time test generation, except for test environment
- Disable all polyfill importing and generation, except for production
- Disable all scss sourcemapping, It’s always better to see the generated CSS
- Disable all js sourcemapping, except for production
- This is default now, but make sure your babel targets only include ie 11 on production builds
How much does this help our development builds?
- Rebuilds are down from 6s to 3s on average
- Initial build down from 120s to 80s
- Warm build down from 40ish to 19s
- Though we haven’t measured it, our browser rendering time is faster because there is less code to download and parse
Here are the changes in actual code:
// ember-
const environment = process.env.EMBER_ENV;
const IS_PROD = environment === 'production';
const IS_TEST = environment === 'test';
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
hinting: IS_TEST, // Disable linting for all builds but test
tests: IS_TEST, // Don't even generate test files unless a test build
"ember-cli-babel": {
includePolyfill: IS_PROD // Only include babel polyfill in prod
},
autoprefixer: {
sourcemap: false // Was never helpful
},
sourcemaps: {
enabled: IS_PROD // CMD ALT F in chrome is *almost* as fast as CMD P
},
...
// Only import other polyfills in production
if (IS_PROD) {
app.import('vendor/file-reader-polyfill.js');
...
}
...
// config/environment.js
if (environment === 'development') {
ENV.yappConfigKey = 'dev';
ENV['ember-cli-mirage'] = {
enabled: false,
excludeFilesFromBuild: true // Don't include lodash and everything else mirage needs
};
}
What else have people done to make improvements?