يمكن أن يؤدي تنزيل ملف WebFont "كامل" يتضمّن جميع الصيغ الأسلوبية، التي قد لا تحتاج إليها، بالإضافة إلى جميع الأحرف الرسومية التي قد لا يتم استخدامها، إلى تنزيل عدة ميغابايت بسهولة. في هذا المنشور، ستتعرّف على كيفية تحسين تحميل WebFonts لكي لا ينزّل الزوّار سوى ما سيستخدمونه.
لحلّ مشكلة الملفات الكبيرة التي تحتوي على جميع الصيغ،
تم تصميم قاعدة CSS @font-face
خصيصًا
للسماح لك بتقسيم مجموعة الخطوط إلى مجموعة من الموارد. على سبيل المثال،
مجموعات فرعية من الرموز اليونيكود ونُسخ مختلفة من الأنماط
استنادًا إلى هذه البيانات، يحدِّد المتصفّح المجموعات الفرعية والنُسخ المطلوبة وينزِّل الحد الأدنى من المجموعة المطلوبة لعرض النص، ما يُعدّ أمرًا مفيدًا جدًا. ومع ذلك، إذا لم تكن حذرًا، يمكن أن يؤدي ذلك أيضًا إلى حدوث عرقلة في الأداء في مسار العرض المهم وتأخير عرض النص.
السلوك التلقائي
إنّ تحميل الخطوط بشكلٍ بطيء له تأثير خفيّ مهمّ قد يؤدّي إلى تأخير عرض النص. على المتصفّح إنشاء شجرة العرض، التي تعتمد على شجرَتَي DOM وCSSOM، قبل أن يعرف موارد الخطوط التي يحتاجها لعرض النص. ونتيجةً لذلك، يتأخّر طلب الخطوط بعد مرور وقت طويل على طلب الموارد المهمة الأخرى، وقد يتم حظر المتصفّح من عرض النص إلى أن يتم جلب المورد.
- يطلب المتصفّح مستند HTML.
- يبدأ المتصفّح في تحليل استجابة HTML وإنشاء نموذج DOM.
- يرصد المتصفّح ملفات CSS وJS والموارد الأخرى ويرسل الطلبات.
- ينشئ المتصفّح CSSOM بعد استلام كل محتوى CSS ويدمجه مع
شجرة DOM لإنشاء شجرة العرض.
- يتم إرسال طلبات الخطوط بعد أن تشير شجرة العرض إلى أنواع الخطوط المطلوبة لعرض النص المحدّد على الصفحة.
- يُجري المتصفّح عملية التنسيق ويعرض المحتوى على الشاشة.
- إذا لم يكن الخط متاحًا بعد، قد لا يعرض المتصفّح أيّ بكسل من النص.
- بعد توفّر الخط، يرسم المتصفّح وحدات بكسل النص.
إنّ "المنافسة" بين أول عملية رسم لمحتوى الصفحة، التي يمكن إجراؤها بعد وقت قصير من إنشاء شجرة العرض، وطلب مورد الخط هو ما يتسبب في "مشكلة النص الفارغ"، حيث قد يعرض المتصفّح تنسيق الصفحة ولكن يحذف أي نص.
من خلال التحميل المُسبَق لـ WebFonts واستخدام font-display
للتحكّم في سلوك المتصفّحات مع الخطوط غير المتوفّرة،
يمكنك منع ظهور صفحات فارغة وتغيُّرات في التصميم بسبب تحميل الخطوط.
تحميل موارد WebFont مُسبقًا
إذا كان من المرجّح أن تحتاج صفحتك إلى WebFont معيّن مستضاف على عنوان URL معروف مسبقًا،
يمكنك الاستفادة من ميزة منح الأولوية للموارد.
سيؤدي استخدام <link rel="preload">
إلى بدء طلب الحصول على WebFont في وقت مبكر من مسار المعالجة المُهمّ،
بدون الحاجة إلى الانتظار إلى أن يتم إنشاء CSSOM.
تخصيص وقت تأخير عرض النص
على الرغم من أنّ التحميل المُسبَق يزيد من احتمال توفّر WebFont عند عرض محتوى الصفحة، فإنه
لا يقدّم أيّ ضمانات.
لا يزال عليك مراعاة سلوك المتصفّحات عند عرض نص يستخدم font-family
غير متوفّر بعد.
في المقالة تجنُّب استخدام نص غير مرئي أثناء تحميل الخطوط، يمكنك ملاحظة أنّ سلوك المتصفّح التلقائي غير متّسق.
ومع ذلك، يمكنك إخبار المتصفّحات الحديثة بالطريقة التي تريدها أن تتصرّف بها باستخدام علامة
font-display
.
على غرار سلوكيات وقت الاستراحة الحالية للخطوط التي تنفذها بعض المتصفّحات، قسّمfont-display
مدة تنزيل الخط إلى ثلاث فترات رئيسية:
- الفترة الأولى هي فترة كتلة الخط. خلال هذه الفترة، إذا لم يتم تحميل خط الكتابة، يجب أن يتم عرض أي عنصر يحاول استخدامه باستخدام خط كتابة احتياطي غير مرئي. إذا تم تحميل خط الكتابة بنجاح خلال فترة الحظر، يتم استخدام خط الكتابة بشكلٍ طبيعي.
- تحدث فترة تبديل الخط مباشرةً بعد فترة حظر الخط. خلال هذه الفترة، إذا لم يتم تحميل خط الكتابة، يجب أن يتم عرض أي عنصر يحاول استخدامه باستخدام خط كتابة احتياطي. إذا تم تحميل خط الكتابة بنجاح خلال فترة الاستبدال، يتم استخدام خط الكتابة بشكلٍ طبيعي.
- تحدث فترة تعذُّر استخدام الخط مباشرةً بعد فترة تبديل الخط. إذا لم يتم تحميل خط الكتابة بعد بدء هذه الفترة، يتم وضع علامة عليه على أنّه تحميل تعذّر، ما يؤدي إلى استخدام الخط البديل العادي. في الحالات الأخرى، يتم استخدام خط الكتابة بشكلٍ طبيعي.
من خلال فهم هذه الفترات، يمكنك استخدام font-display
لتحديد كيفية عرض
الخط بناءً على ما إذا تم تنزيله أو وقت تنزيله.
للعمل مع سمة font-display
، أضِفها إلى قواعد @font-face
:
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 400;
font-display: auto; /* or block, swap, fallback, optional */
src: local('Awesome Font'),
url('/fonts/awesome-l.woff2') format('woff2'), /* will be preloaded */
url('/fonts/awesome-l.woff') format('woff'),
url('/fonts/awesome-l.ttf') format('truetype'),
url('/fonts/awesome-l.eot') format('embedded-opentype');
unicode-range: U+000-5FF; /* Latin glyphs */
}
يتيح المتغيّر font-display
حاليًا النطاق التالي من القيم:
auto
block
swap
fallback
optional
لمزيد من المعلومات عن التحميل المُسبَق للخطوط والسمة font-display
، اطّلِع على المشاركات التالية:
- تجنُّب استخدام نص غير مرئي أثناء تحميل الخط
- التحكّم في أداء الخط باستخدام font-display
- منع تغيير التنسيق وميض النص غير المرئي (FOIT) من خلال التحميل المُسبَق للخطوط الاختيارية
Font Loading API
عند استخدام <link rel="preload">
وCSS font-display
معًا، يمكنك التحكّم بشكل كبير في تحميل الخطوط وعرضها،
بدون إضافة الكثير من النفقات العامة.
ولكن إذا كنت بحاجة إلى تخصيصات إضافية،
وكنت على استعداد لتحمل النفقات العامة الناتجة عن تشغيل JavaScript، يتوفّر خيار آخر.
توفّر Font Loading API واجهة برمجة نصية لتحديد وتعديل خطوط CSS، وتتبُّع مستوى تقدّم تنزيلها، وإلغاء سلوك التحميل المُتأخّر التلقائي. على سبيل المثال، إذا كنت متأكدًا من أنّه يجب استخدام نوع خط معيّن، يمكنك تحديده وإخبار المتصفّح ببدء جلب فوري لمصدر الخط:
var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});
// don't wait for the render tree, initiate an immediate fetch!
font.load().then(function() {
// apply the font (which may re-render text and cause a page reflow)
// after the font has finished downloading
document.fonts.add(font);
document.body.style.fontFamily = "Awesome Font, serif";
// OR... by default the content is hidden,
// and it's rendered after the font is available
var content = document.getElementById("content");
content.style.visibility = "visible";
// OR... apply your own render strategy here...
});
بالإضافة إلى ذلك، بما أنّه يمكنك التحقّق من حالة الخط
(من خلال طريقة check()
)
وتتبّع مستوى تقدّم تنزيله،
يمكنك أيضًا تحديد استراتيجية مخصّصة لعرض النص على صفحاتك:
- يمكنك تعليق جميع عمليات عرض النص إلى أن يصبح الخط متاحًا.
- يمكنك تطبيق مهلة مخصّصة لكل خط.
- يمكنك استخدام الخط الاحتياطي لإزالة حظر العرض وإدخال نمط جديد يستخدم الخط المطلوب بعد توفّره.
والأفضل من ذلك، يمكنك أيضًا الجمع بين الاستراتيجيات أعلاه للمحتوى المختلف على الصفحة. على سبيل المثال، يمكنك تأخير عرض النص في بعض الأقسام إلى أن يصبح الخط متاحًا، واستخدام خط احتياطي، ثم إعادة العرض بعد انتهاء تنزيل الخط.
يجب الاحتفاظ بذاكرة التخزين المؤقت بشكل صحيح.
تكون ملفات خطوط الويب عادةً ملفات ثابتة لا يتم تعديلها بشكل متكرّر. ونتيجةً لذلك، تكون هذه الموارد مناسبة بشكل مثالي لوقت انتهاء صلاحية طويل الحد الأقصى للعمر. احرص على تحديد كل من عنوان ETag الشَرطي، وسياسة Cache-Control المثلى لجميع موارد الخطوط.
إذا كان تطبيق الويب يستخدم عامل خدمة، يكون عرض موارد الخطوط باستخدام استراتيجية التخزين المؤقت أولاً مناسبًا لمعظم حالات الاستخدام.
يجب عدم تخزين الخطوط باستخدام localStorage
أو IndexedDB،
لأنّ لكلّ منهما مجموعة من مشاكل الأداء.
توفّر ذاكرة التخزين المؤقت لبروتوكول HTTP في المتصفّح أفضل آلية وأكثرها فعالية لإرسال موارد الخطوط إلى المتصفّح.
قائمة التحقّق من تحميل خطوط الويب
- تخصيص تحميل الخطوط وعرضها باستخدام
<link rel="preload">
أوfont-display
أو Font Loading API: قد يؤدي سلوك التحميل الكسول التلقائي إلى تأخير عرض النص. تتيح لك ميزات منصّة الويب هذه إلغاء هذا السلوك لخطوط معيّنة، وتحديد استراتيجيات عرض ومهلة مخصّصة للمحتوى المختلف على الصفحة. - تحديد سياسات إعادة التحقّق والتخزين المؤقت الأمثل: الخطوط هي موارد ثابتة يتم تعديلها بمعدل منخفض. تأكَّد من أنّ خوادمك توفّر طابعًا زمنيًا لعمر أقصى طويل وعلامة هَمّية لإعادة إثبات الصلاحية للسماح بإعادة استخدام الخطوط بكفاءة بين الصفحات المختلفة. في حال استخدام worker، تكون استراتيجية "الخزينة أولاً" مناسبة.
الاختبار الآلي لسلوك تحميل WebFont باستخدام Lighthouse
يمكن أن يساعدك Lighthouse في تنفيذ عملية التأكّد من اتّباع أفضل الممارسات لتحسين خطوط الويب بشكل آلي.
يمكن أن تساعدك عمليات التدقيق التالية في التأكّد من أنّ صفحاتك تستمر في اتّباع أفضل الممارسات لتحسين خطوط الويب بمرور الوقت: