Bootstrap: تحسين الأداء والبناء والنشر
آخر تحديث: 2026-08-26
1. مقدمة الدرس
(1) المتطلبات السابقة
- الوضع الداكن وتبديل السمات في Bootstrap (الدرس 21)
- المفاهيم الأساسية لمقاييس أداء الواجهة الأمامية
- آليات تحميل موارد HTML وCSS
(2) 🎯 ما ستتعلّمه
- تحليل حجم الموارد وأداء التحميل في مشروع Bootstrap
- استخدام PurgeCSS لإزالة CSS غير المستخدم
- تحسين تحميل JavaScript حسب الطلب والتحميل الكسول
- إتقان تحسين الصور وأفضل ممارسات نشر CDN
- إعداد سير عمل بناء ونشر إنتاجي كامل
(3) المشكلة
أكملت Alice موقع أعمالها بـ Bootstrap، لكن تحميل الصفحة يستغرق 3 ثوانٍ — قد يغادر المستخدمون قبل اكتمال التحميل. درجة Lighthouse منخفضة أيضًا.
(4) الحل
بناء الصفحة هو مجرد الخطوة الأولى؛ جعلها سريعة التحميل وتوفر تجربة رائعة هو الهدف النهائي. يجمع هذا الدرس أفضل ممارسات تحسين الأداء والبناء والنشر في مشاريع Bootstrap: ضغط CSS، تحميل JS حسب الطلب، تحسين الصور، تسخين CDN — تقليل زمن التحميل إلى 0.8 ثانية عبر التحسين.
لفهم الفكرة: تحسين الأداء = "تخسيس" موقعك — إزالة الكود غير الضروري، ضغط الموارد، السماح للمتصفح بالتخزين المؤقت، لتحميل الصفحة في أقل من ثانية.
(5) الفوائد
تم تحسين موقع Alice من 3 ثوانٍ إلى 0.8 ثانية، مما حسّن درجة Lighthouse بشكل كبير، وعزّز تجربة المستخدم بشكل كبير، وبالتالي زيادة معدل تحويل الموقع.
2. تحليل حجم Bootstrap
| المورد | غير مضغوط | مضغوط بـ Gzip | ملاحظات |
|---|---|---|---|
bootstrap.min.css |
~250KB | ~28KB | الإطار الكامل |
bootstrap.bundle.min.js |
~205KB | ~22KB | يشمل Popper |
bootstrap.min.js |
~170KB | ~19KB | لا يشمل Popper |
| Bootstrap Icons CSS | ~220KB | ~25KB | 2000+ أيقونة |
الاستنتاج الرئيسي: حجم CSS + JS الكامل لـ Bootstrap المضغوط حوالي 50KB، وهو صغير للشبكات الحديثة. التأثيرات الحقيقية على الأداء تأتي من الصور والخطوط والسكربتات الخارجية.
▶ مثال: قبل التحسين وبعده
graph LR
subgraph "Before optimization (3s)"
A1[HTML] --> B1[Full Bootstrap CSS]
B1 --> C1[Full Bootstrap JS]
C1 --> D1[Unoptimized images]
D1 --> E1[Google Fonts CSS]
E1 --> F1[3s load time]
end
subgraph "After optimization (0.8s)"
A2[HTML] --> B2[Purged CSS ~30KB]
B2 --> C2[Lazy loaded images]
C2 --> D2[Deferred JS]
D2 --> E2[CDN cache warm]
E2 --> F2[0.8s load time]
end
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
3. تحسين CSS
(1) التجميع حسب الطلب (Sass)
// استيراد الوحدات المستخدمة فقط
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
@import "bootstrap/scss/grid";
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/card";
@import "bootstrap/scss/navbar";
@import "bootstrap/scss/forms";
@import "bootstrap/scss/utilities";
@import "bootstrap/scss/utilities/api";
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
(2) PurgeCSS لإزالة التكرار
يُحلل PurgeCSS الفئات المستخدمة فعليًا في HTML/JS ويحذف CSS غير المستخدم:
npm install -D purgecss
// purgecss.config.js
module.exports = {
content: ['./**/*.html', './**/*.js'],
css: ['./dist/style.css'],
safelist: ['show', 'active', 'fade', 'collapse', 'modal-open']
}
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
npx purgecss --config purgecss.config.js --output dist/style.min.css
(3) استخدام النسخة المصغّرة عبر CDN
<!-- استخدم دائمًا .min.css / .min.js في الإنتاج -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
4. تحسين JavaScript
(1) استيراد المكونات حسب الطلب
// استيراد مكونات JS المطلوبة فقط
import Alert from 'bootstrap/js/dist/alert'
import Button from 'bootstrap/js/dist/button'
import Carousel from 'bootstrap/js/dist/carousel'
import Collapse from 'bootstrap/js/dist/collapse'
import Dropdown from 'bootstrap/js/dist/dropdown'
import Modal from 'bootstrap/js/dist/modal'
import Offcanvas from 'bootstrap/js/dist/offcanvas'
// تهيئة جميع tooltips
document.querySelectorAll('[data-bs-toggle="tooltip"]')
.forEach(el => new bootstrap.Tooltip(el))
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
(2) تأجيل JS غير الحرج
<!-- تأجيل JS غير الحرج -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" defer></script>
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
(3) استيراد الأيقونات حسب الطلب
<!-- إذا كنت تستخدم أيقونات قليلة، استخدم SVG مضمّن بدلاً من خط الأيقونات -->
<svg class="bi" width="16" height="16" fill="currentColor">
<use href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/bootstrap-icons.svg#house"/>
</svg>
<!-- أو نزّل SVG المطلوبة محليًا لتجنب طلبات CDN -->
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
5. تحسين الصور
<!-- استخدم دائمًا width + height لمنع إزاحة التخطيط -->
<img src="photo.webp" width="800" height="450" class="img-fluid" alt="Photo"
loading="lazy">
<!-- استخدم الصيغ الحديثة -->
<picture>
<source srcset="photo.avif" type="image/avif">
<source srcset="photo.webp" type="image/webp">
<img src="photo.jpg" class="img-fluid" alt="Photo">
</picture>
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
6. البناء والنشر
(1) عملية بناء الإنتاج
// package.json
{
"scripts": {
"dev": "sass scss/custom.scss:dist/style.css --watch",
"build:css": "sass scss/custom.scss:dist/style.css --style compressed",
"build:purge": "purgecss --config purgecss.config.js --output dist/style.min.css",
"build": "npm run build:css && npm run build:purge",
"serve": "npx live-server --port=3000"
}
}
npm run build # تجميع + تنقية
npm run serve # خادم تطوير محلي
(2) قائمة مراجعة النشر
| العنصر | نقاط التحقق | الأدوات |
|---|---|---|
| CSS | مضغوط، منقّى، CSS حرج مضمّن | PurgeCSS، Critical |
| JS | مضغوط، تحميل حسب الطلب، defer | terser، webpack |
| الصور | مضغوطة، webp/avif، تحميل كسول | sharp، squoosh |
| الخطوط | محمّلة مسبقًا، font-display: swap | @font-face |
| التخزين المؤقت | تخزين CDN، ETag، Cache-Control | Cloudflare، Nginx |
| التحليل | درجة Lighthouse ≥ 90 | Lighthouse |
(3) أهداف Lighthouse
| المقياس | الهدف |
|---|---|
| First Contentful Paint | < 1.5s |
| Largest Contentful Paint | < 2.5s |
| Total Blocking Time | < 200ms |
| Cumulative Layout Shift | < 0.1 |
| Speed Index | < 3.0s |
7. مراجعة اختيار Bootstrap مقابل Tailwind
| البُعد | Bootstrap | Tailwind CSS |
|---|---|---|
| منحنى التعلّم | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| سرعة التطوير | سريع (مكونات جاهزة) | متوسط (يجب جمع الفئات المساعدة) |
| حجم الملف | 28KB gzip (كامل) | تجميع حسب الطلب، عادةً < 10KB |
| قابلية التخصيص | متوسطة (متغيرات Sass) | عالية (نظام تصميم) |
| نظام المكونات | 70+ مدمج | لا يوجد (يحتاج Headless UI) |
| تكلفة الترقية | منخفضة (فئات دلالية) | متوسطة (تغيير الفئات) |
| المشاريع المناسبة | لوحات التحكم، MVPs، مواقع الشركات الصغيرة | أنظمة التصميم، تخصيص العلامات التجارية |
8. أمثلة عملية للتحسين
▶ مثال: إعداد تحسين PurgeCSS
// purgecss.config.js — إعداد إنتاج كامل
module.exports = {
content: [
'./src/**/*.html',
'./src/**/*.js',
'./src/**/*.php',
],
css: [
'./dist/style.css',
'./node_modules/bootstrap-icons/font/bootstrap-icons.css',
],
safelist: {
standard: [
// فئات Bootstrap الديناميكية
/^bs-/, // جميع متغيرات CSS في Bootstrap
/^data-bs-/, // جميع سمات data
'active', 'show', 'fade', 'collapsing',
'modal-open', 'modal-backdrop',
'carousel-item-start', 'carousel-item-end',
'tooltip', 'popover', 'toast',
/^btn-/, // فئات تنويعات الأزرار
/^bg-/, // فئات الخلفية
/^text-/, // فئات لون النص
/^border-/, // فئات الحدود
/^alert-/, // تنويعات التنبيه
/^badge-/, // تنويعات الشارات
],
deep: [
/^theme$/,
],
greedy: [
/dark/,
],
},
blocklist: [
/^bi-/, // اختياري: إزالة أيقونات BI غير المستخدمة
],
variables: true,
};
// التشغيل: npx purgecss --config purgecss.config.js --output dist/style.purged.css
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
// package.json scripts لبناء محسّن
{
"scripts": {
"dev": "sass scss/custom.scss dist/style.css --watch",
"build:css": "sass scss/custom.scss dist/style.css --style compressed",
"build:purge": "purgecss --config purgecss.config.js --output dist/style.purged.css",
"build:copy": "cp dist/style.purged.css dist/style.min.css",
"build": "npm run build:css && npm run build:purge && npm run build:copy",
"build:all": "npm run build && npx terser dist/script.js -o dist/script.min.js",
"serve": "npx live-server --port=3000 --no-browser"
}
}
▶ مثال: قائمة مراجعة تحسين Lighthouse
<!DOCTYPE html>
<html lang="ar">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- SEO Meta -->
<title>Optimized Bootstrap Page</title>
<meta name="description" content="Lighthouse score 95+ page built with Bootstrap.">
<!-- Preconnect to CDN -->
<link rel="preconnect" href="https://cdn.jsdelivr.net">
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
<!-- Critical CSS inline (load first) -->
<style>
/* Minimal critical CSS for above-the-fold content */
.hero { background: #0d6efd; color: #fff; padding: 4rem 0; }
.container { max-width: 1140px; margin: 0 auto; padding: 0 1rem; }
@media (max-width: 768px) { .hero { padding: 2rem 0; } }
</style>
<!-- Non-critical CSS (deferred) -->
<link rel="preload" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"></noscript>
<!-- Preload hero image -->
<link rel="preload" href="hero.webp" as="image" fetchpriority="high">
</head>
<body>
<div class="hero">
<div class="container">
<h1 class="display-4 fw-bold">Optimized Bootstrap</h1>
<p class="lead mb-4">Lighthouse score: Performance 98, Accessibility 100, Best Practices 95</p>
<a href="#" class="btn btn-light btn-lg px-4">Get Started</a>
</div>
</div>
<div class="container py-5">
<div class="row g-4">
<!-- Cards with lazy loaded images -->
<div class="col-md-4">
<div class="card p-4 h-100">
<img src="placeholder.svg" data-src="card1.webp" class="card-img-top lazy" alt="Card 1" width="400" height="250" loading="lazy">
<h5 class="card-title mt-2">Optimized Card</h5>
<p class="card-text text-body-secondary">Lazy-loaded WebP image, proper aspect ratio.</p>
</div>
</div>
<div class="col-md-4">
<div class="card p-4 h-100">
<img src="placeholder.svg" data-src="card2.webp" class="card-img-top lazy" alt="Card 2" width="400" height="250" loading="lazy">
<h5 class="card-title mt-2">Fast Loading</h5>
<p class="card-text text-body-secondary">Font display swap enabled.</p>
</div>
</div>
<div class="col-md-4">
<div class="card p-4 h-100">
<img src="placeholder.svg" data-src="card3.webp" class="card-img-top lazy" alt="Card 3" width="400" height="250" loading="lazy">
<h5 class="card-title mt-2">Accessible</h5>
<p class="card-text text-body-secondary">100 Accessibility score guaranteed.</p>
</div>
</div>
</div>
</div>
<!-- Deferred Bootstrap JS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" defer></script>
<!-- Lazy load images -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const lazyImages = document.querySelectorAll('.lazy');
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
observer.unobserve(img);
}
});
});
lazyImages.forEach(function(img) { observer.observe(img); });
}
});
</script>
</body>
</html>
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
▶ مثال: تحميل CDN متعدد المصادر مع احتياطي
<!DOCTYPE html>
<html lang="ar">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CDN with Fallback</title>
<!-- CDN الأساسي: jsDelivr -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
id="bootstrap-css"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous">
<!-- احتياطي: إذا فشل CDN الأساسي، تحميل من unpkg -->
<script>
window.onload = function() {
var css = document.getElementById('bootstrap-css');
if (css && !css.sheet) {
var fallback = document.createElement('link');
fallback.rel = 'stylesheet';
fallback.href = 'https://unpkg.com/bootstrap@5.3.3/dist/css/bootstrap.min.css';
document.head.appendChild(fallback);
}
};
</script>
</head>
<body>
<div class="container py-5">
<h1>CDN Multi-Source Fallback</h1>
<div class="alert alert-success">
<i class="bi bi-check-circle-fill me-2"></i> Bootstrap loaded successfully!
</div>
<p class="text-body-secondary">If jsDelivr is down, automatically falls back to unpkg.</p>
<div class="card p-4 shadow-sm">
<h5>CDN Source Chain</h5>
<ol class="mb-0">
<li class="mb-1"><strong>Primary:</strong> cdn.jsdelivr.net</li>
<li class="mb-1"><strong>Fallback 1:</strong> unpkg.com</li>
<li><strong>Fallback 2:</strong> cdnjs.cloudflare.com</li>
</ol>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"
defer></script>
<script>
// احتياطي JS — يعمل بعد السكربتات المؤجلة
document.addEventListener('DOMContentLoaded', function() {
if (typeof bootstrap === 'undefined') {
var script = document.createElement('script');
script.src = 'https://unpkg.com/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js';
document.body.appendChild(script);
}
});
</script>
</body>
</html>
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
▶ مثال: سكربت بناء كامل
// package.json — خط بناء إنتاجي كامل
{
"name": "bootstrap-production-build",
"version": "1.0.0",
"scripts": {
"clean": "rimraf dist",
"sass:compile": "sass scss/custom.scss:dist/css/style.css --style compressed",
"sass:watch": "sass scss/custom.scss:dist/css/style.css --watch",
"prefix": "postcss dist/css/style.css --use autoprefixer -o dist/css/style.prefixed.css",
"purge": "purgecss --config purgecss.config.js --output dist/css/style.min.css",
"js:bundle": "esbuild src/js/main.js --bundle --minify --outfile=dist/js/main.min.js",
"img:min": "imagemin src/images/* --out-dir=dist/images",
"copy:html": "cp src/*.html dist/",
"build:dev": "npm run clean && npm run sass:compile && npm run copy:html",
"build:prod": "npm run build:dev && npm run prefix && npm run purge && npm run js:bundle && npm run img:min",
"serve": "lite-server --baseDir='dist'",
"deploy": "npm run build:prod && gh-pages -d dist"
},
"devDependencies": {
"autoprefixer": "^10.4.17",
"esbuild": "^0.20.0",
"imagemin-cli": "^7.0.0",
"lite-server": "^2.6.1",
"postcss": "^8.4.33",
"postcss-cli": "^11.0.0",
"purgecss": "^6.0.0",
"rimraf": "^5.0.5",
"sass": "^1.70.0"
},
"dependencies": {
"bootstrap": "^5.3.3",
"bootstrap-icons": "^1.11.3"
}
}
# أوامر البناء الكاملة
# التطوير
npm run build:dev # تجميع SCSS + نسخ HTML
# الإنتاج
npm run build:prod # تجميع → Autoprefix → Purge → تصغير JS → تحسين الصور
# معاينة محلية
npm run serve # خدمة dist/ مع إعادة تحميل تلقائية
# النشر إلى GitHub Pages
npm run deploy # بناء + نشر
# خطوات فردية
npx sass scss/custom.scss dist/css/style.css --style compressed
npx postcss dist/css/style.css --use autoprefixer -o dist/css/style.prefixed.css
npx purgecss --css dist/css/style.prefixed.css --content dist/**/*.html --output dist/css/
npx esbuild src/js/main.js --bundle --minify --outfile=dist/js/main.min.js
(1) مصفوفة أولوية التحسين
graph TD
A[Performance Optimization Priority] --> B[🛡️ P0: Critical]
A --> C[🔥 P1: High]
A --> D[⚡ P2: Medium]
A --> E[📋 P3: Low]
B --> B1[Enable Gzip/Brotli compression]
B --> B2[Optimize image format WebP/AVIF]
B --> B3[Remove unused CSS]
B --> B4[Enable CDN cache]
C --> C1[Defer non-critical JS]
C --> C2[Inline critical CSS]
C --> C3[Preconnect to third-party domains]
D --> D1[Font display:swap]
D --> D2[Image lazy loading]
D --> D3[Resource Preload/Prefetch]
E --> E1[Service Worker cache]
E --> E2[HTTP/2 Server Push]
E --> E3[Skeleton screen loading]
النتيجة: مكونات بأسلوب Bootstrap 5.3 (مثل الأزرار والبطاقات وCarousel وCollapse إلخ)، باستخدام سمة Bootstrap الافتراضية (الفاتحة) وشبكة متجاوبة.
(2) جدول مصفوفة أولوية التحسين
| الأولوية | عنصر التحسين | الفائدة المقدّرة | صعوبة التنفيذ | مقياس Lighthouse |
|---|---|---|---|---|
| P0 (حرج) | تفعيل Gzip/Brotli | تقليل الحجم 70-80% | منخفض (إعداد خادم) | FCP، LCP |
| P0 (حرج) | صيغة صور WebP/AVIF | تقليل حجم الصور 30-50% | متوسط (سكربت بناء) | LCP |
| P0 (حرج) | PurgeCSS إزالة الأنماط غير المستخدمة | تقليل CSS 60-80% | منخفض (ملف إعداد) | FCP |
| P1 (عالي) | إدراج CSS حرج | تقليل حظر عرض الشاشة الأولى | متوسط (يحتاج أداة) | FCP |
| P1 (عالي) | تأجيل تحميل JS | تقليل حظر JS | منخفض (إضافة سمة) | TBT |
| P1 (عالي) | تسخين CDN | تسريع الزيارة الأولى | متوسط (إجراء يدوي) | LCP |
| P2 (متوسط) | Font display:swap | إلغاء FOIT | منخفض (خاصية CSS) | CLS |
| P2 (متوسط) | تحميل كسول للصور | تقليل التحميل الأولي | منخفض (إضافة سمة) | LCP |
| P3 (منخفض) | تخزين Service Worker | زيارة ثانية فائقة السرعة | عالية (كتابة SW) | مقاييس إعادة الاستخدام |
(3) جدول مقارنة منصات النشر
| المنصة | الحصة المجانية | نطاق مخصص | HTTPS | طريقة النشر | CI/CD | السيناريو المناسب |
|---|---|---|---|---|---|---|
| GitHub Pages | غير محدود (مستودعات عامة) | ✅ | ✅ | git push |
GitHub Actions | مشاريع شخصية/مفتوحة المصدر |
| Netlify | 100GB/شهر | ✅ | ✅ | ربط Git / CLI | تلقائي | مواقع ثابتة، Jamstack |
| Vercel | 100GB/شهر | ✅ | ✅ | ربط Git / CLI | تلقائي | Next.js، مشاريع الواجهة الأمامية |
| Cloudflare Pages | غير محدود | ✅ | ✅ | ربط Git / CLI | تلقائي | أولوية CDN عالمي |
| AWS S3 + CloudFront | حسب الاستخدام | ✅ | ✅ | CLI / SDK | قابل للإعداد | إنتاج مؤسسي |
| Aliyun OSS + CDN | حسب الاستخدام | ✅ | ✅ | CLI / SDK | قابل للإعداد | مستخدمو منطقة الصين |
❓ أسئلة شائعة
btn-${color} المجمّعة بـ JS) يجب إضافتها إلى safelist. يُنصح بإدراج جميع أسماء الفئات التي قد تظهر ديناميكيًا في safelist في إعداد PurgeCSS.📖 ملخص
- تحسين CSS: تجميع Sass حسب الطلب + إزالة تكرار PurgeCSS، استخدم نسخة
.minعبر CDN - تحسين JS: استيراد مكونات حسب الطلب +
deferللتحميل الكسول - تحسين الصور:
loading="lazy"+ صيغة WebP/AVIF + عرض وارتفاع ثابتين - عملية البناء: تجميع
sass> تنقيةpurgecss> نشر - أهداف Lighthouse: FCP < 1.5s، LCP < 2.5s، CLS < 0.1
📝 تمارين
- ⭐ شغّل تدقيق Lighthouse على مشروع Bootstrap موجود، سجّل مقاييس FCP وLCP وCLS، ثم حسّنها عنصرًا بعنصر حتى تحقق جميع الأهداف.
- ⭐⭐ إعداد PurgeCSS: شغّل PurgeCSS على ملف HTML يستخدم Bootstrap، وقارن فرق الحجم بين CSS المنقّى وغير المنقّى.
- ⭐⭐⭐ أنشئ سكربت
package.jsonكامل يحتوي على ثلاثة أوامر: dev (مراقبة)، build (sass + purge)، serve.
الدرس السابق: الوضع الداكن