Performance & BEM Convention
BEM Naming Convention
Basic Structure
.block {
}
.block__element {
}
.block--modifier {
}
BEM Principles
- Block: Standalone component
.card {
}
.navbar {
}
.button {
}
- Element: Parts of a block (double underscore)
.card__title {
}
.card__image {
}
.navbar__menu {
}
.button__icon {
}
- 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 {
}
Navigation
.nav {
}
.nav__item {
}
.nav__link {
}
.nav__link--active {
}
.nav--vertical {
}
Modal
.modal {
}
.modal__overlay {
}
.modal__content {
}
.modal__header {
}
.modal__close {
}
.modal--large {
}
Performance Testing Tips
-
Browser Dev Tools
- Use Paint Flashing to identify repaints
- Check Layout Shifts in Performance panel
- Monitor FPS during animations
-
CSS Stats
- Monitor selector complexity
- Track declaration count
- Identify redundant rules
-
Rendering Performance
/* Use content-visibility for long pages */
.content-block {
content-visibility: auto;
contain-intrinsic-size: 0 500px;
} -
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`;
});