"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > خطا CSS اللذان يؤثران على الأداء (fps إلى ps)

خطا CSS اللذان يؤثران على الأداء (fps إلى ps)

تم النشر بتاريخ 2024-11-03
تصفح:198

لقد قمت مؤخرًا بإصدار Learn WCs وإذا كنت قد شاهدته، فمن المحتمل أنك لاحظت الرسوم المتحركة في الخلفية، حيث تتحرك الدوائر الملونة قطريًا عبر الشاشة. يبدو مثل هذا:

يعمل بشكل جيد على Chrome وSafari، لكنني لاحظت انخفاضًا حادًا في الأداء على Firefox.

كان الأداء سيئًا للغاية، لدرجة أنني قمت بتعطيل هذه الرسوم المتحركة في Firefox.

كيف تعمل الرسوم المتحركة؟

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

    

عنصر .background-gradient مسؤول عن إنشاء تدرج يمتد على كامل عرض وارتفاع الحاوية الأصلية. مثل ذلك:

The Two Lines of CSS That Tanked Performance (fps to ps)

قناع الخلفية الخارجي مسؤول عن شيئين:

  1. يضبط الموضع على ثابت، ويجعل الحاوية تملأ أبعاد إطار العرض بالكامل.
  2. إنشاء قناع منقط فوق التدرج

وهذا يضمن أن يكون لون النقاط هو لون التدرج الموجود أسفلها مباشرة:

The Two Lines of CSS That Tanked Performance (fps to ps)

إليك ملف CSS لكل ما وصفته أعلاه:

.background-mask {
    --mask-size: 24px;

    /* Position Styles */
    position: fixed;
    width: 100%;
    height: 100%;
    z-index: -1;

    /* Mask Styles */
    mask-image: radial-gradient(black 2px, transparent 2px);
    mask-size: var(--mask-size) var(--mask-size);
    mask-position: 0px 0px;
    animation: mask-move 3s infinite linear;
}

.background-gradient {
    background: var(--red);
    background-image: var(--gradient);
    width: 100%;
    height: 100%;
}

@keyframes mask-move {
    0% {
        mask-position: 0px 0px;
    }

    100% {
        mask-position: var(--mask-size) var(--mask-size);
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-background-mask {
        animation: none;
    }
}

إذا كنت مهتمًا بمعرفة المزيد عن الأقنعة في CSS، فيمكنني أن أوصي بهذا المنشور الشامل لأحمد شديد

ما سبب هذا الانخفاض في الأداء؟

ليست كل خصائص CSS تتحرك بالتساوي. دون الخوض كثيرًا في كيفية عرض المتصفح لـ HTML على الصفحة (على الرغم من أنني قمت بتوضيح ذلك هنا)، هناك عدد قليل من المراحل التي يمر بها. المراحل الثلاث التي نهتم بها هي:

  • التخطيط - عندما يقوم المتصفح بحساب حجم ومواضع العناصر على الصفحة
  • الرسام - يرسم جميع الجوانب المرئية للصفحة، مثل الصور والألوان والظلال وما إلى ذلك
  • مركب - وضع العناصر فوق بعضها البعض بالترتيب الصحيح

يبدو ترتيب خط الأنابيب كما يلي:

التخطيط → الطلاء → مركب

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

تحريك خصائص معينة، مثل الترجمة والتعتيم، كلاهما يتجنب تشغيل التخطيط ويستخدم تسريع الأجهزة.

للأسف، ليس هذا هو الحال عند تحريك موضع القناع. لقد ألقيت نظرة على Chrome ورأيت أن عدد الطلاء لقسم الخلفية يتزايد في كل إطار. وبعد بضع ثوانٍ، تم بالفعل إطلاق الطلاء أكثر من 1000 مرة.

The Two Lines of CSS That Tanked Performance (fps to ps)

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

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

كيف أصلحت هذا؟

بدلاً من تحريك خصائص CSS المحسنة بشكل سيئ مثل موضع القناع، كنت بحاجة إلى الاعتماد على الخصائص الأكثر أداءً، مثل الترجمة.

لم يكن الحل هو نقل الأقنعة بمقدار 24 بكسل، ولكن بدلاً من ذلك نقل عنصر الخلفية بالكامل باستخدام خاصية الترجمة.

من وجهة نظر مجردة، هكذا تبدو الرسوم المتحركة:

هذا هو التغيير في السطرين في CSS:

/* --mask-size = 24px */

@keyframes mask-move {
    0% {
        transform: translate(calc(var(--mask-size) * -1), calc(var(--mask-size) * -1));
    }

    100% {
        transform: translate(0px, 0px);
    }
}

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

The Two Lines of CSS That Tanked Performance (fps to ps)

سيكون المشاهدون ذوو العيون الصقر قد اكتشفوا مشكلة. إذا كنت تتذكر، فإن ارتفاع وعرض الخلفية يملأ إطار العرض. يؤدي تغيير الخلفية إلى اليسار وإلى الأعلى بمقدار 24 بكسل إلى ترك هذه المساحة الفارغة في إطار العرض.

The Two Lines of CSS That Tanked Performance (fps to ps)

حلها بسيط مثل إضافة حجم القناع إلى عرض الحاوية وارتفاعها:

.background-mask {
    --mask-size: 24px;

    width: calc(100%   var(--mask-size));
    height: calc(100%   var(--mask-size));
}

دعونا نلقي نظرة مرة أخرى على فايرفوكس:

قد لا يكون هذا حلاً مثاليًا، لكنه دائمًا ما يكون مُرضيًا بعض الشيء من خلال تنفيذ خدعة CSS الممتعة smoke and Mirrors.

بيان الافراج تم إعادة إنتاج هذه المقالة على: https://dev.to/andrico1234/the-two-lines-of-css-that-tanked-performance-120fps-to-40fps-3lnj?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ Study_golang @163.com حذف
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3