אופטימיזציית CSS: CSS קריטי והסרת סגנונות לא בשימוש
טעינת עמוד איטית נגרמת לעיתים קרובות על ידי CSS מוגזם. CSS שחוסם רינדור מעכב את הציור הראשון של התוכן (FCP) ומגדיל את זמן הציור של התוכן הגדול ביותר (LCP). Bootstrap מחוץ לקופסה שוקל 140 KB, אך לאחר הסרת מחלקות לא בשימוש, הוא נשאר על 5–15 KB (הפחתה של 96%). Tailwind במצב פיתוח הוא 3.5 MB; לאחר purge — 5–50 KB. אנו מגדירים CSS קריטי ו-purge עבור כל מחסנית: מ-Laravel ועד Next.js, ומשיגים FCP < 1 שנייה. הניסיון שלנו: 7+ שנים באופטימיזציית ביצועים, מעל 50 פרויקטים. התוצאה — מעבר Core Web Vitals ללא פשרות. תוך 2–3 ימים, אנו מיישמים CSS קריטי ו-purge turnkey.
כיצד CSS קריטי משפיע על מדדי Core Web Vitals?
LCP (Largest Contentful Paint) — זמן הרינדור של האלמנט הגדול ביותר על המסך. אם CSS נטען באופן סינכרוני (חוסם רינדור), הדפדפן לא מצייר תוכן עד לטעינת הסגנון המלא. CSS קריטי מוטבע מבטל עיכוב זה: סגנונות לתוכן שמעל לקפל מוכנסים ישירות לתוך <head>, והשאר נטען באופן אסינכרוני.
דוגמה: באתר Bootstrap, רק סגנונות עבור הכותרת, ה-hero והכפתורים נכנסים ל-CSS קריטי — כ-5 KB במקום 140 KB. LCP יורד מ-4 ל-1.5 שניות (שיפור של 62%). FCP יורד מ-2.5 ל-1.2 שניות.
מה זה purge CSS וכיצד להגדיר אותו?
Purge מסיר מחלקות שלא נמצאות בתבניות. ב-Tailwind 3+, purge מובנה דרך קובץ התצורה content:
// tailwind.config.ts
import type { Config } from 'tailwindcss';
export default {
content: [
'./resources/views/**/*.blade.php',
'./resources/js/**/*.{ts,tsx}',
'./resources/js/**/*.json', // если классы генерируются динамически
],
theme: {
extend: {},
},
plugins: [],
} satisfies Config;מחלקות דינמיות (שרשור מחרוזות) — purge לא ימצא אותן:
// Плохо — purge не увидит
const color = 'red';
<div className={`text-${color}-500`} />
// Хорошо — полные имена классов
const colorMap = {
red: 'text-red-500',
blue: 'text-blue-500',
};
<div className={colorMap[color]} />
מה זה safelist ולמה הוא נחוץ?
Safelist הוא רשימה לבנה של מחלקות ש-purge לא צריך להסיר. לפעמים מחלקות מתווספות דרך JavaScript, למשל, מודאלים של Bootstrap: // tailwind.config.ts import type { Config } from 'tailwindcss'; export default { content: [ './resources/views/**/*.blade.php', './resources/js/**/*.{ts,tsx}', './resources/js/**/*.json', // если классы генерируются динамически ], theme: { extend: {} }, plugins: [], } satisfies Config; , // Плохо — purge не увидит const color = 'red'; <div className={`text-${color}-500`} /> // Хорошо — полные имена классов const colorMap = { red: 'text-red-500', blue: 'text-blue-500', }; <div className={colorMap[color]} /> . אם הן לא נמצאות בתבניות HTML, purge יסיר אותן — וישבור את הפונקציונליות. אנו מגדירים safelist בקובץ התצורה של PurgeCSS:
// postcss.config.js
import purgecss from '@fullhuman/postcss-purgecss';
export default {
plugins: [
purgecss({
content: [
'./resources/views/**/*.blade.php',
'./resources/js/**/*.tsx',
'./public/**/*.html',
],
safelist: {
standard: ['modal-open', 'show', 'active', 'fade'],
deep: [/^modal/, /^alert/, /^toast/],
greedy: [/swiper/],
},
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [],
}),
],
};
הגדרת purge CSS שלב אחר שלב
- ביקורת CSS נוכחי. השתמשו ב-Coverage ב-DevTools, ניתוח bundle, זיהוי חסימת רינדור.
- הגדרת purge. הגדירו PurgeCSS או Tailwind JIT, ציינו נתיבים לתבניות.
- יצירת safelist. הוסיפו מחלקות בשימוש דינמי (מודאלים, התראות, אנימציות).
- בדיקות. ודאו ששום דבר לא נשבר, רגרסיה ויזואלית.
- פריסה. שלבו purge בתהליך הבנייה (Vite, Webpack, Laravel Mix) ופרסו לייצור.
בחירת אסטרטגיה: CSS רץ vs CSS סטטי
CSS-in-JS (styled-components, Emotion) יוצר סגנונות בזמן ריצה — עומס JS נוסף. לייצור, CSS סטטי עדיף.
| פרמטר | CSS-in-JS | CSS סטטי (Tailwind, CSS Modules) |
|---|---|---|
| עומס בזמן ריצה | כן | לא |
| גודל bundle | +50–150 kB (runtime) | 0 kB |
| Tree-shaking | מורכב | פשוט |
| תמיכה ב-SSR | דורש הגדרה | מובנה |
CSS סטטי עדיף עבור Core Web Vitals: הוא לא חוסם רינדור (אחרי inline קריטי) וטוען פחות CPU.
עבור Vite, CSS קריטי מוגדר דרך critters:
// vite.config.ts
import { defineConfig } from 'vite';
import { critters } from 'critters';
export default defineConfig({
plugins: [
critters({
preload: 'media',
pruneSource: true,
logLevel: 'silent',
})
]
});
ב-Laravel, CSS קריטי מוכנס ידנית:
<style>{!! file_get_contents(public_path('css/critical.css')) !!}</style>
<link rel="preload" href="{{ mix('css/app.css') }}" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript>
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
</noscript>מיניפיקציה — נעשית על ידי LightningCSS ב-Vite או cssnano. פלט: bundle CSS < 20 KB, כיסוי > 80%.
השוואת מדדים לפני ואחרי אופטימיזציה
| מדד | לפני אופטימיזציה | אחרי |
|---|---|---|
| גודל CSS (Bootstrap) | 140 KB | 5 KB |
| LCP | 4.0 s | 1.5 s |
| FCP | 2.5 s | 1.2 s |
| TTFB | 0.8 s | 0.6 s (ללא שינוי) |
טעויות נפוצות באופטימיזציית CSS
- התעלמות ממחלקות דינמיות — purge מסיר אותן, ושובר את הממשק.
- safelist שגוי — מודאלים, התראות מפסיקים להיות מעוצבים.
- CSS קריטי לא מתעדכן כשהתוכן משתנה.
- שכחה מ-iframes וסקריפטים של צד שלישי — ה-CSS שלהם משפיע גם על המדדים.
- אופטימיזציה יתר: הסרת מחלקות בשימוש במקומות לא ברורים (ארכיונים, עמודים סטטיים).
מה כלול בעבודת אופטימיזציית CSS?
- ביקורת CSS נוכחי: Coverage ב-DevTools, ניתוח bundle, זיהוי חסימת רינדור.
- הגדרת purge: תצורת PurgeCSS או Tailwind JIT, יצירת safelist.
- חילוץ CSS קריטי: אוטומטית דרך critters או ידנית באמצעות
modal-open. - מיניפיקציה ודחיסה: LightningCSS / esbuild, Gzip / Brotli.
- שילוב בתהליך הבנייה: Vite, Webpack, Laravel Mix, Next.js.
- בדיקת מדדים: LCP, FCP, TBT לפני ואחרי.
- תיעוד: תיאור הגדרות, המלצות לתחזוקה.
תוצאה: מעבר Core Web Vitals, גודל bundle CSS מינימלי, פונקציונליות וסגנונות נשמרים.
אנו משתמשים ב-PurgeCSS, Tailwind JIT, critters ו-PostHTML בהתאם למחסנית. הכל מוגדר עבור תהליך הבנייה שלכם.
צרו קשר לביקורת מפורטת של הפרויקט שלכם. קבלו ייעוץ על כלים מתאימים. אנו נעריך את ה-CSS שלכם תוך יום אחד. הזמינו אופטימיזציית CSS והאיצו את האתר שלכם.







