CSS / CSS гүйцэтгэлийн оновчлол

CSS гүйцэтгэлийн оновчлол

CSS зөв бичихгүй бол хуудас удаан ачааллах, гүйлгэхэд "уначих" зэрэг асуудал гарч болно. Хэдэн зарчим мэдэж байхад хуудсаа хурдан, саад тотгоргүй болгох боломжтой.

Reflow ба repaint гэж юу вэ?

Браузер хуудсыг дэлгэцэд харуулахдаа дараах үе шатыг дамждаг:

код
HTML/CSS → DOM/CSSOM → Render Tree → Layout (Reflow) → Paint (Repaint) → Composite

Reflow (layout дахин тооцоолох) — элементийн хэмжээ, байрлал өөрчлөгдөхөд болно. Энэ нь хамгийн үнэтэй үйлдэл:

css
/* Эдгээр property өөрчлөхөд REFLOW үүснэ */
width, height, margin, padding, border, top, left, font-size, display

Repaint (дахин будах) — харагдах байдал өөрчлөгдөхөд болно, layout тооцоолдоггүй тул арай хямд:

css
/* Эдгээр property өөрчлөхөд зөвхөн REPAINT үүснэ */
color, background-color, visibility, box-shadow

Composite (давхарга нэгтгэх) — хамгийн хямд. Зөвхөн эдгээр property GPU-д шилждэг:

css
/* Зөвхөн COMPOSITE — хамгийн хурдан */
transform, opacity

Практик дүгнэлт

Animation хийхдээ transform болон opacity ашиглах нь хамгийн зөв:

css
/* МУУГААР: reflow + repaint үүсгэнэ */
.box-bad {
  animation: move-bad 1s;
}
@keyframes move-bad {
  from {
    left: 0;
  }
  to {
    left: 200px;
  }
}

/* САЙНААР: зөвхөн composite */
.box-good {
  animation: move-good 1s;
}
@keyframes move-good {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(200px);
  }
}

will-change

will-change property нь браузерт "энэ элемент удахгүй өөрчлөгдөнө" гэдгийг урьдчилан мэдэгддэг. Браузер тухайн элементийг тусдаа GPU давхаргад шилжүүлж, гүйцэтгэлийг сайжруулна.

css
.animated-card {
  will-change: transform, opacity;
}

.scrollable-panel {
  will-change: scroll-position;
}

will-change болгоомжтой ашиглах

will-change-г хэт их ашиглах нь санах ойг их эзлэж, эсрэгээр удаашруулдаг:

css
/* БУРУУ — бүх элементэд тавих */
* {
  will-change: transform; /* санах ой дуусна */
}

/* ЗӨВ — зөвхөн animation болох элементэд */
.card:hover {
  will-change: transform;
}

JavaScript-ээр hover-д нэмж, дууссаны дараа арилгах нь хамгийн оновчтой арга:

css
.card {
  transition: transform 0.3s;
}

/* hover хийхэд will-change нэмж, дууссаны дараа арилгана */

contain

contain property нь элементийн дотоод өөрчлөлт гаднаасаа тусгаарлагдсан гэдгийг браузерт мэдэгддэг. Браузер тухайн элементийг дахин тооцоолохдоо бусад хэсэгт нөлөөлөхгүй гэдгийг мэдэж, ажлыг багасгадаг.

css
/* Утгууд */
contain: layout; /* layout тусгаарлах */
contain: paint; /* paint тусгаарлах */
contain: size; /* хэмжээ тусгаарлах */
contain: style; /* style тусгаарлах */
contain: strict; /* бүгдийг тусгаарлах (size + layout + paint + style) */
contain: content; /* layout + paint + style */
css
/* Жишээ: олон карт бүхий жагсаалт */
.feed-item {
  contain: content;
  /* Нэг карт өөрчлөгдөхөд бусад картуудыг дахин тооцоолохгүй */
}

/* Widgets, sidebar-д хэрэглэх */
.widget {
  contain: layout paint;
}

CSS-ийн critical path

Critical CSS гэдэг нь хуудас анх ачааллах үед дэлгэцэнд харагдах хэсгийн CSS юм. Энэ CSS-ийг <head>-д шууд оруулах нь ачаалах хугацааг богиносгодог.

html
<!-- Critical CSS — шууд head-д -->
<style>
  /* Дэлгэцийн анхны хэсгийн style */
  body {
    margin: 0;
    background: #0b1120;
    color: #f1f5f9;
  }
  .navbar {
    height: 60px;
    background: #0f172a;
  }
  .hero {
    padding: 80px 20px;
    text-align: center;
  }
</style>

<!-- Бусад CSS — async ачааллах -->
<link
  rel="preload"
  href="style.css"
  as="style"
  onload="this.onload=null;this.rel='stylesheet'"
/>
<noscript><link rel="stylesheet" href="style.css" /></noscript>

CSS ачааллах дарааллыг оновчтой болгох

html
<head>
  <!-- 1. Хамгийн чухал font-ийг урьдчилан ачааллах -->
  <link rel="preconnect" href="https://fonts.googleapis.com" />

  <!-- 2. Critical CSS шууд -->
  <style>
    /* ... */
  </style>

  <!-- 3. Бусад CSS дараа -->
  <link
    rel="stylesheet"
    href="non-critical.css"
    media="print"
    onload="this.media='all'"
  />
</head>

Unused CSS арилгах

Ихэнх сайт ашиглагдаагүй CSS-ийн 70–90% нь ачааллагддаг. Энэ нь хуудасны хэмжээ нэмэгдүүлж, ачааллах хугацааг уртасгадаг.

@layer ашиглах

css
/* @layer ашиглан CSS-ийг давхаргалж, дарааллыг тодорхойлох */
@layer base, components, utilities;

@layer base {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }
  body {
    margin: 0;
  }
}

@layer components {
  .btn {
    padding: 8px 16px;
    border-radius: 6px;
  }
}

@layer utilities {
  .text-center {
    text-align: center;
  }
}

CSS хэмжээ багасгах зарчмууд

css
/* 1. Shorthand ашиглах */
/* УРТ */
margin-top: 16px;
margin-right: 16px;
margin-bottom: 16px;
margin-left: 16px;

/* БОГИНО */
margin: 16px;

/* 2. Custom property ашиглан давтагдлыг багасгах */
:root {
  --space-md: 16px;
  --radius: 8px;
}

.card {
  padding: var(--space-md);
  border-radius: var(--radius);
}

/* 3. Нэг удаа тодорхойлж, дахин ашиглах */
.flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

Гүйцэтгэлийн шалгах жагсаалт

css
/* ✅ ЗӨВ */
.animated {
  transform: translateY(-4px);
} /* GPU-д */
.animated {
  opacity: 0;
} /* GPU-д */
.list-item {
  contain: content;
} /* тусгаарласан */

/* ❌ БУРУУ */
.animated {
  top: -4px;
} /* reflow */
.animated {
  left: 200px;
} /* reflow */
* {
  will-change: transform;
} /* санах ой дуусна */

Дараагийн хичээлд:

Print stylesheet — хуудсаа хэвлэхэд ямар харагдах талаар судална.