المفاضلات من CSS-in-JS

الصورة بواسطة ارتيم بالي

لقد كتبت مؤخرًا نظرة عامة على مستوى أعلى من CSS-in-JS ، أتحدث غالبًا عن المشكلات التي يحاول هذا النهج حلها. نادراً ما يستثمر مؤلفو المكتبة الوقت في وصف المفاضلات الخاصة بحلهم. أحيانًا يكون السبب في ذلك هو أنهم متحيزون جدًا ، وأحيانًا لا يعرفون كيف يطبق المستخدمون الأداة. هذه محاولة لوصف المقايضات التي رأيتها حتى الآن. أعتقد أنه من المهم أن أذكر أنني مؤلف JSS ، لذلك يجب أن أكون منحازة.

تأثير اجتماعي

هناك طبقة من الأشخاص الذين يعملون على منصة الويب ولا يعرفون أي JavaScript. هؤلاء الناس يحصلون على المال مقابل كتابة HTML و CSS. أحدثت CSS-in-JS تأثيرًا كبيرًا على سير عمل المطورين. لا يمكن أن يحدث تغيير حقيقي في التغيير دون ترك بعض الناس وراءهم. لا أعرف ما إذا كان يجب أن يكون CSS-in-JS هو الطريقة الوحيدة ، لكن الاعتماد الشامل يمثل علامة واضحة على مشاكل استخدام CSS في التطبيقات الحديثة.

جزء كبير من المشكلة هو عدم قدرتنا على التواصل بدقة مع حالات الاستخدام حيث يضيء CSS-in-JS وكيفية استخدامه بشكل صحيح لمهمة ما. نجح العديد من عشاق CSS-in-JS في الترويج للتكنولوجيا ، لكن لم يتحدث كثير من النقاد عن المقايضات بطريقة بناءة ، دون أن يتأرجحوا في الأدوات. نتيجةً لذلك ، تركنا العديد من المقايضات مخفية ولم نبذل جهدًا قويًا لتقديم التفسير والحلول.

تعد CSS-in-JS محاولة لتسهيل التعامل مع حالات الاستخدام المعقدة ، لذلك لا تدفعها إلى حيث لا تكون هناك حاجة إليها!

تكلفة وقت التشغيل

عندما يتم إنشاء CSS من جافا سكريبت في وقت التشغيل ، في المتصفح ، هناك حمولة متأصلة. وقت التشغيل يختلف من مكتبة إلى مكتبة. هذا معيار عام جيد ، ولكن تأكد من إجراء الاختبارات الخاصة بك. تظهر الاختلافات الرئيسية في وقت التشغيل وفقًا للحاجة إلى الحصول على تحليل CSS كامل لسلاسل القوالب ومقدار التحسينات وتفاصيل تنفيذ الأساليب الديناميكية وخوارزمية التجزئة وتكلفة تكامل الإطار. *

إلى جانب وقت التشغيل المحتمل المحتمل ، تحتاج إلى التفكير في 4 استراتيجيات تجميع مختلفة ، لأن بعض مكتبات CSS-in-JS تدعم استراتيجيات متعددة والأمر متروك للمستخدم لتطبيقها. *

الإستراتيجية 1: توليد وقت التشغيل فقط

يعد Runtime CSS إنشاءًا يقوم بإنشاء سلسلة CSS في JavaScript ، ثم يقوم بحقن هذه السلسلة باستخدام علامة نمط في المستند. هذه التقنية تنتج ورقة أنماط ، وليس أنماط مضمنة.

إن المفاضلة بين توليد وقت التشغيل هي عدم القدرة على توفير محتوى مصمم في المرحلة المبكرة ، حيث يبدأ تحميل المستند. يناسب هذا النهج عادةً التطبيقات التي لا تحتوي على محتوى يمكن أن تكون مفيدة على الفور. عادةً ما تتطلب مثل هذه التطبيقات تفاعلات المستخدم قبل أن تصبح مفيدة حقًا للمستخدم. غالبًا ما تعمل مثل هذه التطبيقات مع محتوى ديناميكي للغاية بحيث يصبح قديمًا بمجرد تحميله ، لذلك تحتاج إلى إنشاء خط أنابيب للتحديث مبكرًا ، على سبيل المثال ، Twitter. بالإضافة إلى ذلك ، عند تسجيل دخول المستخدم ، ليست هناك حاجة لتوفير HTML لـ SEO.

إذا تطلب التفاعل جافا سكريبت ، فيجب تحميل الحزمة قبل أن يكون التطبيق جاهزًا. على سبيل المثال ، يمكنك إظهار محتويات قناة افتراضية عند تحميل Slack في المستند ، ولكن من المحتمل أن المستخدم سيرغب في تغيير القناة مباشرة بعد ذلك. لذلك إذا قمت بتحميل المحتويات الأولية فقط لرميها على الفور.

يمكن تحسين الأداء المتصور لمثل هذه التطبيقات من خلال العناصر النائبة والحيل الأخرى للسماح للتطبيق بالشعور بالحظة أكثر مما هو عليه بالفعل. عادة ما تكون هذه التطبيقات ثقيلة البيانات على أي حال ، لذلك لن تكون مفيدة في أسرع وقت ممكن مثل مقال.

استراتيجية 2: جيل وقت التشغيل مع CSS الحرجة

CSS الحرجة هي الحد الأدنى من CSS المطلوب لنمط الصفحة في حالتها الأولية. يتم تقديمه باستخدام علامة نمط في رأس المستند. تستخدم هذه التقنية على نطاق واسع مع وبدون CSS-in-JS. في كلتا الحالتين ، من المحتمل أن تضاعف تحميل قواعد CSS ، مرة واحدة كجزء من CSS الحرجة ومرة ​​واحدة كجزء من حزمة JavaScript أو CSS. يمكن أن يكون حجم CSS الحرج كبيرًا جدًا وفقًا لمقدار المحتوى. عادة ، لن يتم تخزين المستند مؤقتًا.

بدون CSS الحرج ، سيتعين على تطبيق CSS-in-JS ثابت المحتوى ذي المحتوى الثابت الثقيل مع وقت تشغيل أن يعرض العناصر النائبة بدلاً من المحتوى. يعد هذا أمرًا سيئًا لأنه كان من الممكن أن يكون مفيدًا للمستخدم في وقت مبكر جدًا ، مما يؤدي إلى تحسين إمكانية الوصول على الأجهزة المنخفضة النهاية واتصالات النطاق الترددي المنخفض.

مع CSS الحرجة ، يمكن إجراء إنشاء CSS لوقت التشغيل في مرحلة لاحقة ، دون حظر واجهة المستخدم في المرحلة الأولية. كن حذرًا من ذلك ، على أجهزة الجوال المنخفضة ، والتي يبلغ عمرها أكثر من 5 سنوات تقريبًا ، يمكن أن يكون لتوليد CSS من JavaScript تأثير سلبي على الأداء. يعتمد هذا بشدة على كمية CSS التي يتم إنشاؤها والمكتبة المستخدمة ، لذلك لا يمكن تعميمها.

المفاضلة من هذه الاستراتيجية هي تكلفة استخراج CSS الحرجة وتكلفة إنشاء CSS وقت التشغيل.

الاستراتيجية 3: استخراج وقت البناء فقط

هذه الاستراتيجية هي الاستراتيجية الافتراضية على شبكة الإنترنت بدون CSS-in-JS. تتيح لك بعض مكتبات CSS-in-JS استخراج CSS ثابت في وقت البناء. * في هذه الحالة ، لا يوجد أي وقت تشغيل متضمن ، يتم تقديم CSS على الصفحة باستخدام علامة ارتباط. يتم دفع تكلفة إنشاء CSS مرة واحدة قبل الموعد المحدد.

هناك 2 مفاضلات رئيسية هنا:

  1. لا يمكنك استخدام بعض واجهات برمجة التطبيقات الديناميكية التي يوفرها CSS-in-JS في وقت التشغيل ، لأنه ليس لديك إمكانية الوصول إلى الحالة. غالبًا ما زلت لا تستطيع استخدام خصائص CSS المخصصة ، لأنها غير مدعومة في كل متصفح ولا يمكن تعددها في وقت الإنشاء بطبيعتها. في هذه الحالة ، سيتعين عليك تنفيذ حلول بديلة للموضوعات الديناميكية والتصميم القائم على الحالة. *
  2. بدون CSS الحرج ومع ذاكرة التخزين المؤقت الفارغة ، سيتم حظر الطلاء الأول ، حتى يتم تحميل حزمة CSS الخاصة بك. يمنع عنصر الارتباط في رأس المستند عرض HTML.
  3. خصوصية غير حتمية مع تقسيم الحزمة القائمة على الصفحة في تطبيقات صفحة واحدة. *

استراتيجية 4: استخراج وقت البناء مع CSS الحرجة

هذه الاستراتيجية ليست فريدة أيضًا من CSS-in-JS. يوفر الاستخراج الكامل الثابت مع CSS الحرج أفضل أداء عند العمل مع تطبيق أكثر استاتيكية. هذا النهج لا يزال لديه المفاضلات المذكورة أعلاه من CSS ثابت ، إلا أنه يمكن نقل علامة رابط الحظر إلى أسفل المستند.

هناك 4 استراتيجيات تقديم CSS رئيسية. اثنان منهم فقط خاصان بـ CSS-in-JS ولا ينطبق أي منهما على جميع المكتبات.

إمكانية الوصول

يمكن أن يقلل CSS-in-JS من إمكانية الوصول عند استخدامه بطريقة خاطئة. سيحدث هذا عندما يتم تنفيذ موقع محتوى ثابت إلى حد كبير دون استخراج CSS حرج بحيث لا يمكن رسم HTML قبل أن يتم تحميل حزمة JavaScript وتقييمها. يمكن أن يحدث هذا أيضًا عند تقديم ملف CSS ضخم باستخدام علامة ارتباط الحظر في رأس المستند ، وهي المشكلة الحالية الأكثر شيوعًا في التضمين التقليدي وليست خاصة بـ CSS-in-JS.

يحتاج المطورون إلى تحمل مسؤولية إمكانية الوصول. لا تزال هناك فكرة مضللة قوية مفادها أن الاتصال بالإنترنت غير المستقر يمثل مشكلة في البلدان الضعيفة اقتصاديًا. نميل إلى نسيان أن لدينا مشاكل في الاتصال كل يوم عندما ندخل نظام السكك الحديدية تحت الأرض أو مبنى كبير. يعتبر اتصال الهاتف المحمول الثابت بدون كبل خرافة. ليس من السهل أن يكون لديك اتصال WiFi ثابت ، على سبيل المثال ، يمكن لشبكة WI-FI بسرعة 2.4 جيجاهرتز أن تحصل على تداخل من فرن الميكروويف!

تكلفة CSS الحرجة مع التقديم من جانب الخادم

للحصول على استخراج CSS الحرج لـ CSS-in-JS ، نحتاج إلى SSR. SSR هي عملية إنشاء HTML النهائي لحالة معينة من التطبيق على الخادم. في الواقع ، يمكن أن تكون عملية معقدة ومكلفة للغاية. يتطلب قدرا معينا من دورات وحدة المعالجة المركزية على الخادم لكل طلب HTTP.

تعمل CSS-in-JS عادة على زيادة حقيقة كونها مدمجة في خط أنابيب تقديم HTML. يضيف CSS الحرج حملًا إضافيًا لعرض HTML على الخادم لأن هذا CSS يحتاج أيضًا إلى تجميعه في سلسلة CSS نهائية. في بعض السيناريوهات ، من الصعب أو حتى من المستحيل تخزينها على الخادم.

تقديم الصندوق الأسود

يجب أن تكون على دراية بكيفية قيام مكتبة CSS-in-JS التي تستخدمها بعرض CSS الخاص بك. على سبيل المثال ، غالبًا ما يكون الأشخاص غير مدركين لكيفية تطبيق مكونات التصميم والعاطفة أنماط ديناميكية. الأنماط الديناميكية هي بناء جملة يسمح باستخدام وظائف JavaScript داخل تعريف الأنماط الخاصة بك. هذه الوظائف تقبل الدعائم وإرجاع كتلة CSS.

من أجل الحفاظ على خصوصية الطلب المصدر ، تقوم كل من المكتبات المذكورة أعلاه بإنشاء قاعدة CSS جديدة إذا كانت تحتوي على إعلان ديناميكي وتحديثات المكون مع الدعائم الجديدة. لإظهار ما أقصده ، قمت بإنشاء صندوق الحماية هذا. في JSS ، قررنا اتخاذ مقايضة مختلفة ، مما يسمح لنا بتحديث الخصائص الديناميكية دون إنشاء قواعد CSS جديدة. *

منحنى التعلم حاد

بالنسبة للأشخاص المطلعين على CSS ، ولكنهم جدد في JavaScript ، قد يكون حجم العمل الأولي للحصول على السرعة مع CSS-in-JS كبيرًا جدًا.

لست بحاجة إلى أن تكون مطور جافا سكريبت محترفًا لكتابة CSS-in-JS ، حتى النقطة التي ينخرط فيها المنطق المعقد. لا يمكننا تعميم تعقيد التصميم ، لأنه يعتمد حقًا على حالة الاستخدام. في الحالات التي يصبح فيها CSS-in-JS معقدًا ، فمن المحتمل أن يكون التنفيذ باستخدام الفانيليا CSS أكثر تعقيدًا.

بالنسبة لتصميم CSS-in-JS الأساسي ، يحتاج المرء إلى معرفة كيفية الإعلان عن المتغيرات ، وكيفية استخدام سلاسل القوالب ، ومحاور قيم JavaScript. إذا تم استخدام تدوين الكائنات ، فيتعين على المرء أن يعرف كيفية التعامل مع كائنات جافا سكريبت وصيغة بناء الجملة الخاصة بالمكتبة. إذا كان التصميم الديناميكي متورطًا ، فيتعين على المرء أن يعرف كيفية استخدام وظائف وشروط JavaScript.

بشكل عام ، هناك منحنى تعليمي ، لا يمكننا إنكاره. عادة لا يكون منحنى التعلم هذا أكبر من تعلم ساس. في الواقع ، لقد قمت بإنشاء هذا بالطبع egghead لإظهار هذا.

لا قابلية التشغيل البيني

معظم LSSS CSS-in-JS غير قابلة للتشغيل البيني. هذا يعني أنه لا يمكن تقديم الأنماط المكتوبة باستخدام مكتبة واحدة باستخدام مكتبة مختلفة. من الناحية العملية ، يعني ذلك أنه لا يمكنك تبديل التطبيق بالكامل بسهولة من تطبيق إلى آخر. هذا يعني أيضًا أنه لا يمكنك مشاركة واجهة المستخدم الخاصة بك بسهولة على NPM دون إحضار مكتبة CSS-in-JS التي تختارها إلى حزمة المستهلك ما لم يكن لديك استخراج ثابت لوقت البناء ل CSS الخاص بك.

لقد بدأنا العمل على تنسيق ISTF الذي من المفترض أن يعمل على حل هذه المشكلة ، لكن للأسف لم يكن لدينا الوقت الكافي للوصول به إلى حالة جاهزة للإنتاج. *

أعتقد أن مشاركة مكونات إطار واجهة المستخدم غير القابلة لإعادة الاستخدام في المجال العام لا تزال مشكلة يصعب حلها عمومًا.

أخطار أمنية

من الممكن تقديم تسرب أمني باستخدام CSS-in-JS. كما هو الحال مع أي تطبيقات من جانب العميل ، تحتاج إلى تجنب إدخال المستخدم قبل تقديمه ، دائمًا.

هذه المقالة سوف تعطيك المزيد من البصيرة وبعض الأمثلة تشويه.

أسماء الفئات غير القابلة للقراءة

لا يزال بعض الناس يعتقدون أنه من المهم أن نحتفظ بأسماء فصول قابلة للقراءة على الويب. حاليًا ، توفر العديد من مكتبات CSS-in-JS أسماء فئات ذات معنى بناءً على اسم الإعلان أو اسم المكون في وضع التطوير. حتى أن بعضها يتيح لك تخصيص وظيفة منشئ اسم الفئة.

على الرغم من ذلك ، في وضع الإنتاج ، ينشئ معظمهم أسماء أقصر لحمولة أصغر. هذه مفاضلة يجب على مستخدم المكتبة أن يقوم بها وتخصيصها للمكتبة إذا لزم الأمر.

استنتاج

توجد مقايضات ، وربما لم أذكرها جميعًا. لكن معظمهم لا ينطبق على جميع CSS-in-JS. يعتمدون على المكتبة التي تستخدمها وكيفية استخدامها.

* سوف يستغرق مقال مخصص لشرح هذه الجملة. اسمحوا لي أن أعرف على Twitter (@ oleg008) حول أي واحدة ترغب في قراءة المزيد.