التخزين المؤقت والتصغير
هناك ثلاثة اعتبارات إنتاجية عند أطراف مسار العمل: تجنب إعادة ترجمة المدخلات المتطابقة، وتجنب كلفة بناء المترجم مع كل طلب، وتقليل حجم CSS المُنشأ. وكلها مساعدات على جانب PHP تحيط بالمترجم.
التخزين المؤقت
يشغّل توليد CSS مسار العمل بالكامل في كل استدعاء. أما المحتوى الذي لا يتغير بين الطلبات، فتكتب ذاكرة التخزين المؤقت القائمة على الملفات نتيجته على القرص وتقدّمها في الاستدعاءات اللاحقة.
مرّر cache إلى tw::generate() — true للدليل الافتراضي، أو سلسلة مسار لدليل مخصص:
use TailwindPHP\tw;
// Cache to the default directory: sys_get_temp_dir() . '/tailwindphp'
$css = tw::generate([
'content' => '<div class="flex p-4">Hello</div>',
'cache' => true,
]);
// Cache to a custom directory
$css = tw::generate([
'content' => '<div class="flex p-4">Hello</div>',
'cache' => '/path/to/cache',
]);
// With a time-to-live (seconds)
$css = tw::generate([
'content' => '<div class="flex p-4">Hello</div>',
'cache' => true,
'cacheTtl' => 3600, // expire after 1 hour
]);
يُنشأ دليل ذاكرة التخزين المؤقت تلقائيًا إذا لم يكن موجودًا.
مفتاح ذاكرة التخزين المؤقت
يُشتق المفتاح من المحتوى وإعدادات CSS وعلامة minify — ثم يُحوّل إلى تجزئة تُستخدم في اسم الملف tailwind_<hash>.css. أي تغيير في الترميز أو مدخل CSS أو تفعيل التصغير ينتج مفتاحًا مختلفًا، وبالتالي ملفًا مختلفًا.
إعدادات CSS في المفتاح هي css المضمنة بالإضافة إلى محتويات الملفات المحددة في importPaths. ولا يشمل المفتاح مدخلين: الملفات المستوردة عبر @import متداخل داخل تلك الملفات، وإصدار TailwindPHP. امسح ذاكرة التخزين المؤقت بعد تعديل استيراد متداخل أو ترقية الحزمة، وإلا فستظل المخرجات القديمة تُقدّم.
مدة الصلاحية
cacheTtl مدة بالثواني. عند إصابة ذاكرة التخزين المؤقت، يُقارن وقت تعديل الملف بالوقت الحالي؛ فإذا كان الملف أقدم من cacheTtl، يُعدّ ذلك إخفاقًا وتُعاد الترجمة. إذا لم تحدد cacheTtl، فلن تنتهي صلاحية المدخلات — امسحها صراحةً.
مسح ذاكرة التخزين المؤقت
يحذف tw::clearCache() (أو الدالة clearCache()) ملفات tailwind_*.css من دليل ذاكرة التخزين المؤقت ويعيد عدد الملفات المحذوفة.
use TailwindPHP\tw;
use function TailwindPHP\clearCache;
$deleted = tw::clearCache(); // default directory
$deleted = tw::clearCache('/path/to/cache'); // custom directory
clearCache('/path/to/cache'); // function form
ذاكرة حالة المترجم
لا تفيد ذاكرة مخرجات التخزين المؤقت إلا عند تكرار المحتوى نفسه. عندما يتغير المحتوى في كل استدعاء، تكون الكلفة الأكبر في بناء المترجم نفسه: حل @import "tailwindcss"، وتحليل الموارد المضمنة، وتجميع السمة. تعتمد هذه المرحلة على مدخل CSS فقط، لذا يمكن تخزينها وإعادة استخدامها.
مرّر stateCacheFile إلى tw::compile() (أو new TailwindCompiler($css, $options)):
use TailwindPHP\tw;
$compiler = tw::compile($themeCss, [
'stateCacheFile' => __DIR__ . '/cache/tailwind-state.php',
]);
$css = $compiler->generateExact($html, true);
عند الإنشاء الأول، تُكتب الحالة في ذلك المسار كملف PHP عادي يمكن لـ OPcache مشاركته بين الطلبات؛ وتحملها عمليات الإنشاء اللاحقة بدلًا من إعادة التحليل. وتطابق المخرجات البايتات الناتجة عن مترجم غير مخزّن مؤقتًا.
- يُتحقق من الملف بمقارنته ببصمة المحرك (حجم مصادر وموارد TailwindPHP ووقت تعديلها)، ومفتاح مشتق من مدخل CSS وخياري
baseوimportSearchPaths، وحجم ووقت تعديل كل ملف استورده المدخل. تؤدي أي مخالفة إلى إعادة البناء والكتابة، لذا لا تتطلب ترقية TailwindPHP أو تعديل ملف مستورد أي خطوة يدوية. - المسار تحت مسؤوليتك: استخدم ملفًا لكل مدخل CSS مميز، في دليل يستطيع خادم الويب الكتابة إليه. عمليات الكتابة ذرية (ملف مؤقت بالإضافة إلى
rename()). - تتجاوز المدخلات التي تستخدم
importResolverمخصصًا ذاكرة التخزين المؤقت، لأن سلوك المحلّل لا يمكن تكوين بصمة له. - تتوفر ذاكرة التخزين المؤقت نفسها حول
compile()الأدنى مستوى من النوع array باسم API عبرTailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options).
لا يقبل tw::generate() قيمة stateCacheFile؛ فهو ينشئ مترجمًا جديدًا في كل استدعاء. استخدم نسخة مترجم عندما تكون كلفة الإنشاء مهمة.
التصغير
يقلل التصغير حجم المخرجات للإنتاج. تُصدر العلامة minify مخرجات CSS مصغّرة مباشرة أثناء التسلسل، لذا فهي المسار الأسرع والأدق؛ أما tw::minify() فيشغّل المصغّر القائم على السلاسل (src/_tailwindphp/CssMinifier.php) على سلسلة CSS موجودة:
use TailwindPHP\tw;
// Minify during generation (serializer path, preferred)
$css = tw::generate([
'content' => '<div class="flex p-4">Hello</div>',
'minify' => true,
]);
// Or minify an existing string (string-based post-pass)
$css = tw::generate('<div class="flex p-4">Hello</div>');
$minified = tw::minify($css);
ينتج المساران بنية متكافئة، لكن البايتات ليست متطابقة. يحافظ مسار التسلسل على محددات :not() التابعة التي يدمجها مسار السلاسل، لذا يُفضّل استخدام علامة minify للمخرجات المُنشأة، وترك tw::minify() لـ CSS التي تصل على هيئة سلسلة.
ما الذي يفعله
يطبق كلا المسارين مجموعة التخفيضات نفسها للحجم:
| الخطوة | الأثر |
|---|---|
| إزالة التعليقات | يحذف كتل /* … */ |
| دمج المسافات البيضاء | يدمج تتابعات المسافات البيضاء ويزيلها حول { } ; : , وروابط المحددات |
| اختصار ألوان hex | #ffffff → #fff، #aabbcc → #abc |
| إزالة وحدات الصفر | 0px → 0 (مع الحفاظ على قيم الوقت 0s/0ms) |
| اختصار وزن الخط | font-weight:normal → 400، font-weight:bold → 700 |
| إزالة القواعد الفارغة | يحذف المحددات ذات كتل التصريحات الفارغة |
حسب التصميم، لا يدمج المحددات المكررة أو يجمع خصائص الاختصار — فكلاهما يجعل تصحيح الأخطاء أصعب وقد يؤثر في التتابع.
CLI: --minify مقابل --optimize
تتيح CLI مسار تصغير التسلسل عبر علامتين:
# Optimize and minify (smallest output)
tailwindphp -i ./src/app.css -o ./dist/styles.css --minify # or -m
# Meant to optimize without minifying
tailwindphp -i ./src/app.css -o ./dist/styles.css --optimize
في الإصدار الحالي، يصغّر --optimize أيضًا، لذا تكتب الأوامر كلاهما البايتات نفسها (#9). تُشغّل تحويلات مكافئة لـ lightningcss في كل عملية بناء على أي حال، لذا فالمخرجات العادية (دون علامة) محسّنة ومقروءة بالفعل.
للاطلاع على بقية واجهة API العامة — tw::generate() وtw::compile() وطرق الفحص وتنسيقات الإدخال — راجع مرجع API.