Performance & Output
Optimize Sass compilation and CSS output size — choose the right output style, manage source maps, and avoid common bloat patterns.
Compilation Performance
Sass compilation speed depends on file count, @extend complexity, and import depth. The module system (@use) compiles faster than @import because it avoids duplicate parsing.
Use --watch in development for incremental compilation. In CI, compile once with --style=compressed. Dart Sass (the canonical implementation) is fast enough for most projects without caching.
- Dart Sass is the only supported implementation since 2020
- Avoid @import — it re-processes files and slows compilation
- Split large projects into entry points for parallel compilation
# Development sass --watch src/scss:dist/css --source-map # CI production build sass src/scss/main.scss dist/css/main.min.css \ --style=compressed --no-source-map
Output Styles
Sass offers four output styles. expanded (default) is readable with full indentation. compressed removes all whitespace and comments. nested mirrors Sass nesting structure. compact puts each selector on one line.
Always use compressed for production. The size difference between expanded and compressed is typically 30–50%.
# expanded (development)
.button {
background: #2563eb;
padding: 0.75rem 1.5rem;
}
# compressed (production)
.button{background:#2563eb;padding:.75rem 1.5rem}Source Maps
Source maps link compiled CSS lines back to Sass source in browser DevTools. Enable in development, disable in production to avoid exposing source structure.
Inline source maps embed the map in the CSS file (larger). External source maps create a separate .map file referenced by a comment. External maps are preferred — they do not bloat the CSS download.
# External source map (recommended for dev) sass src:dist --source-map # Inline source map sass src:dist --source-map --embed-sources
Avoiding Output Bloat
Mixins duplicate CSS for every @include — ten includes of a 20-line mixin adds 200 lines. Extends group selectors but can create massive selector lists. Loops generating hundreds of utility classes inflate output.
Audit output with csscss or PurgeCSS. If your compiled CSS exceeds 100KB before gzip, investigate mixin overuse and unnecessary utility generation.
- Prefer CSS custom properties over Sass loops for runtime values
- Limit generated utility classes to your actual design scale
- Use @extend with placeholders instead of mixins for shared silent classes
// Bloated: generates 100 classes
@for $i from 1 through 100 {
.m-#{$i} { margin: #{$i}px; }
}
// Better: use CSS custom properties or a limited scale
$spacing: (1: 0.25rem, 2: 0.5rem, 4: 1rem, 8: 2rem);Production Pipeline
The ideal pipeline: Sass compiles to CSS, PostCSS autoprefixes and optimizes, then the bundler minifies and code-splits. Tools like cssnano handle final compression beyond Sass compressed output.
Measure gzip size, not raw size — gzip compresses repetitive CSS patterns dramatically. A 200KB raw file may gzip to 30KB.
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano')({ preset: 'default' }),
],
};