Skip to main content

Performance & BEM Convention

BEM Naming Convention

Basic Structure

.block {}
.block__element {}
.block--modifier {}

BEM Principles

  1. Block: Standalone component
.card {}
.navbar {}
.button {}
  1. Element: Parts of a block (double underscore)
.card__title {}
.card__image {}
.navbar__menu {}
.button__icon {}
  1. Modifier: Variations of block/element (double dash)
.card--featured {}
.button--large {}
.button--primary {}
.navbar__menu--collapsed {}

Real-world BEM Example

/* Block component */
.card {
background: #fff;
padding: 20px;
}

/* Elements that depend upon block */
.card__title {
font-size: 2em;
font-weight: bold;
}

.card__content {
font-size: 1.1em;
}

/* Modifier that changes the style of the block */
.card--featured {
background: #f7f7f7;
border: 2px solid gold;
}

Performance Optimizations

1. Selector Performance

Avoid Deep Nesting

/* Bad - Deep nesting */
.header .nav .nav-item .link a { }

/* Good - Flat structure */
.header__nav-link { }

Minimize Selector Complexity

/* Bad - Complex selector */
div.container > div.content article.post > h2.title span { }

/* Good - Direct and simple */
.post__title-text { }

2. CSS Property Performance

Use Transform Instead of Position

/* Bad - Triggers layout */
.modal {
position: absolute;
top: 50%;
left: 50%;
}

/* Good - Uses GPU acceleration */
.modal {
position: absolute;
transform: translate(-50%, -50%);
}

Optimize Animations

/* Good - GPU-accelerated properties */
.element {
transform: translateX(100px);
opacity: 0.5;
will-change: transform, opacity;
}

/* Avoid animating */
.element--avoid {
width: 100px; /* Triggers layout */
height: 100px; /* Triggers layout */
top: 50px; /* Triggers layout */
}

3. Media Optimization

Progressive Loading

/* Load critical styles first */
.header {
/* Critical styles */
}

/* Then load larger background images */
@media (min-width: 768px) {
.header {
background-image: url('large-bg.jpg');
}
}

4. File Organization

Component-Based Structure

/* components/_card.css */
.card { }
.card__title { }
.card__content { }
.card--featured { }

/* components/_button.css */
.button { }
.button__icon { }
.button--primary { }

5. Performance Best Practices

CSS Loading

<!-- Critical CSS inline -->
<style>
/* Critical path CSS here */
</style>

<!-- Non-critical CSS deferred -->
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">

Reduce Redundancy

/* Bad - Repetitive */
.button--primary {
display: inline-block;
padding: 10px 20px;
border-radius: 4px;
background: blue;
}

.button--secondary {
display: inline-block;
padding: 10px 20px;
border-radius: 4px;
background: gray;
}

/* Good - Using common base class */
.button {
display: inline-block;
padding: 10px 20px;
border-radius: 4px;
}

.button--primary {
background: blue;
}

.button--secondary {
background: gray;
}

Common BEM Patterns

Form Components

.form { }
.form__group { }
.form__input { }
.form__input--error { }
.form__label { }
.form__submit { }
.nav { }
.nav__item { }
.nav__link { }
.nav__link--active { }
.nav--vertical { }
.modal { }
.modal__overlay { }
.modal__content { }
.modal__header { }
.modal__close { }
.modal--large { }

Performance Testing Tips

  1. Browser Dev Tools

    • Use Paint Flashing to identify repaints
    • Check Layout Shifts in Performance panel
    • Monitor FPS during animations
  2. CSS Stats

    • Monitor selector complexity
    • Track declaration count
    • Identify redundant rules
  3. Rendering Performance

    /* Use content-visibility for long pages */
    .content-block {
    content-visibility: auto;
    contain-intrinsic-size: 0 500px;
    }
  4. Layout Thrashing Prevention

    // Bad - Causes layout thrashing
    elements.forEach(el => {
    const height = el.offsetHeight;
    el.style.height = `${height + 10}px`;
    });

    // Good - Batch read/write operations
    const heights = elements.map(el => el.offsetHeight);
    elements.forEach((el, i) => {
    el.style.height = `${heights[i] + 10}px`;
    });