फ़ॉन्ट फ़ॉलबैक के लिए फ़्रेमवर्क टूल

Janicklas Ralph James
Janicklas Ralph James

font-display: swap का इस्तेमाल करके फ़ॉन्ट लोड करने वाली साइटों पर, अक्सर लेआउट शिफ़्ट (CLS) की समस्या आती है. ऐसा तब होता है, जब वेब फ़ॉन्ट लोड होने के बाद, उसे फ़ॉलबैक फ़ॉन्ट से बदल दिया जाता है.

फ़ॉलबैक फ़ॉन्ट के डाइमेंशन को प्राइमरी फ़ॉन्ट से मैच करने के लिए अडजस्ट करके, सीएलएस को रोका जा सकता है. @font-face नियम में size-adjust, ascent-override, descent-override, और line-gap-override जैसी प्रॉपर्टी, फ़ॉलबैक फ़ॉन्ट की मेट्रिक को बदलने में मदद कर सकती हैं. इससे डेवलपर, फ़ॉन्ट के दिखने के तरीके को बेहतर तरीके से कंट्रोल कर सकते हैं. फ़ॉन्ट-फ़ॉलबैक और बदलाव करने की सुविधा वाली प्रॉपर्टी के बारे में ज़्यादा जानने के लिए, यह पोस्ट पढ़ें. इस डेमो में, इस तकनीक को लागू करने का तरीका भी देखा जा सकता है.

इस लेख में, फ़ॉलबैक फ़ॉन्ट सीएसएस जनरेट करने और सीएलएस को कम करने के लिए, Next.js और Nuxt.js फ़्रेमवर्क में फ़ॉन्ट साइज़ में बदलाव करने का तरीका बताया गया है. इसमें यह भी बताया गया है कि Fontaine और Capsize जैसे क्रॉस-कटिंग टूल का इस्तेमाल करके, फ़ॉलबैक फ़ॉन्ट कैसे जनरेट किए जा सकते हैं.

बैकग्राउंड

आम तौर पर, font-display: swap का इस्तेमाल, FOIT (अनदेखे जा सकने वाले टेक्स्ट का फ़्लैश) को रोकने और स्क्रीन पर कॉन्टेंट को तेज़ी से दिखाने के लिए किया जाता है. swap की वैल्यू से ब्राउज़र को पता चलता है कि फ़ॉन्ट का इस्तेमाल करके लिखे गए टेक्स्ट को तुरंत सिस्टम फ़ॉन्ट का इस्तेमाल करके दिखाया जाना चाहिए. साथ ही, सिस्टम फ़ॉन्ट को सिर्फ़ तब बदलना चाहिए, जब कस्टम फ़ॉन्ट तैयार हो.

swap की सबसे बड़ी समस्या, स्क्रीन पर कॉन्टेंट के हिलने-डुलने की है. ऐसा दो फ़ॉन्ट के वर्णों के साइज़ में अंतर की वजह से होता है. इससे सीएलएस का स्कोर खराब हो जाता है. खास तौर पर, ज़्यादा टेक्स्ट वाली वेबसाइटों के लिए.

यहां दी गई इमेज में, समस्या का उदाहरण दिखाया गया है. पहली इमेज में font-display: swap का इस्तेमाल किया गया है. इसमें फ़ॉलबैक फ़ॉन्ट के साइज़ में कोई बदलाव नहीं किया गया है. दूसरे इमेज में दिखाया गया है कि सीएसएस @font-face नियम का इस्तेमाल करके साइज़ में बदलाव करने से, लोड होने में लगने वाला समय कैसे कम होता है.

फ़ॉन्ट साइज़ में बदलाव किए बिना

body {
  font-family: Inter, serif;
}
ऐसा टेक्स्ट जिसका फ़ॉन्ट और साइज़ अचानक बदल जाता है और जिससे अजीब असर पड़ता है.

फ़ॉन्ट साइज़ में बदलाव करने के बाद

body {
  font-family: Inter, fallback-inter, serif;
  }

@font-face {
  font-family: "fallback-inter";
  ascent-override: 90.20%;
  descent-override: 22.48%;
  line-gap-override: 0.00%;
  size-adjust: 107.40%;
  src: local("Arial");
}
ऐसा टेक्स्ट जो किसी दूसरे फ़ॉन्ट में आसानी से ट्रांज़िशन करता है.

फ़ॉन्ट लोड होने के दौरान लेआउट में होने वाले बदलाव को रोकने के लिए, फ़ॉलबैक फ़ॉन्ट का साइज़ अडजस्ट करना एक असरदार रणनीति हो सकती है. हालांकि, फ़ॉलबैक फ़ॉन्ट के बारे में इस पोस्ट में बताया गया है कि लॉजिक को शुरू से लागू करना मुश्किल हो सकता है. अच्छी बात यह है कि ऐप्लिकेशन डेवलप करते समय, इस प्रोसेस को आसान बनाने के लिए कई टूल पहले से उपलब्ध हैं.

Next.js की मदद से, फ़ॉन्ट फ़ॉलबैक को ऑप्टिमाइज़ करने का तरीका

Next.js में, फ़ॉलबैक फ़ॉन्ट ऑप्टिमाइज़ेशन की सुविधा चालू करने का तरीका पहले से मौजूद है. @next/font कॉम्पोनेंट का इस्तेमाल करके फ़ॉन्ट लोड करने पर, यह सुविधा डिफ़ॉल्ट रूप से चालू रहती है.

@next/font कॉम्पोनेंट को Next.js के वर्शन 13 में लॉन्च किया गया था. यह कॉम्पोनेंट, आपके पेजों में Google Fonts या कस्टम फ़ॉन्ट इंपोर्ट करने के लिए एक एपीआई उपलब्ध कराता है. साथ ही, इसमें फ़ॉन्ट फ़ाइलों को अपने-आप होस्ट करने की सुविधा भी पहले से मौजूद होती है.

इस्तेमाल करने पर, फ़ॉलबैक फ़ॉन्ट मेट्रिक अपने-आप कैलकुलेट हो जाती हैं और सीएसएस फ़ाइल में इंजेक्ट हो जाती हैं.

​​उदाहरण के लिए, अगर Roboto फ़ॉन्ट का इस्तेमाल किया जा रहा है, तो आम तौर पर इसे सीएसएस में इस तरह से तय किया जाता है:

@font-face {
  font-family: 'Roboto';
  font-display: swap;
  src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff');
  font-weight: 700;
}

body {
  font-family: Roboto;
}

अगले/फ़ॉन्ट पर माइग्रेट करने के लिए:

  1. 'next/font' से 'Roboto' फ़ंक्शन इंपोर्ट करके, Roboto फ़ॉन्ट के एलान को अपने JavaScript में ले जाएं. फ़ंक्शन की रिटर्न वैल्यू, एक क्लास का नाम होगा. इसका इस्तेमाल, कॉम्पोनेंट टेंप्लेट में किया जा सकता है. इस सुविधा को चालू करने के लिए, कॉन्फ़िगरेशन ऑब्जेक्ट में display: swap जोड़ना न भूलें.

     import { Roboto } from '@next/font/google';
    
    const roboto = Roboto({
      weight: '400',
      subsets: ['latin'],
      display: 'swap' // Using display swap automatically enables the feature
    })
    
  2. अपने कॉम्पोनेंट में, जनरेट की गई क्लास के नाम का इस्तेमाल करें: javascript export default function RootLayout({ children }: { children: React.ReactNode; }) { return ( <html lang="en" className={roboto.className}> <body>{children}</body> </html> ); }

adjustFontFallback कॉन्फ़िगरेशन विकल्प:

@next/font/google के लिए: यह एक बूलियन वैल्यू है, जो यह सेट करती है कि कुल लेआउट शिफ़्ट को कम करने के लिए, अपने-आप फ़ॉलबैक फ़ॉन्ट का इस्तेमाल किया जाना चाहिए या नहीं. यह डिफ़ॉल्ट रूप से 'सही' पर सेट होती है. Next.js, फ़ॉन्ट टाइप (क्रमशः सेरिफ़ बनाम सैंस-सेरिफ़) के आधार पर, आपके फ़ॉलबैक फ़ॉन्ट को Arial या Times New Roman पर अपने-आप सेट करता है.

@next/font/local के लिए: यह एक स्ट्रिंग या बूलियन फ़ॉल्स वैल्यू है. इससे यह तय होता है कि कुल लेआउट शिफ़्ट को कम करने के लिए, अपने-आप फ़ॉलबैक फ़ॉन्ट का इस्तेमाल किया जाना चाहिए या नहीं. इस एट्रिब्यूट की वैल्यू Arial, Times New Roman या false हो सकती हैं. डिफ़ॉल्ट रूप से, यह Arial पर सेट होता है. अगर आपको सेरिफ़ फ़ॉन्ट का इस्तेमाल करना है, तो इस वैल्यू को Times New Roman पर सेट करें.

Google फ़ॉन्ट के लिए एक और विकल्प

अगर next/font कॉम्पोनेंट का इस्तेमाल नहीं किया जा सकता, तो Google Fonts के साथ इस सुविधा का इस्तेमाल करने के लिए, optimizeFonts फ़्लैग का इस्तेमाल करें. Next.js में, optimizeFonts सुविधा पहले से ही डिफ़ॉल्ट रूप से चालू होती है. यह सुविधा, एचटीएमएल रिस्पॉन्स में Google फ़ॉन्ट सीएसएस को इनलाइन करती है. इसके अलावा, next.config.js में experimental.adjustFontFallbacksWithSizeAdjust फ़्लैग सेट करके, फ़ॉन्ट फ़ॉलबैक अडजस्टमेंट की सुविधा चालू की जा सकती है. इस बारे में यहां दिए गए स्निपेट में बताया गया है:

// In next.config.js
module.exports = {
 experimental: {
   adjustFontFallbacksWithSizeAdjust: true,
 },
}

ध्यान दें: हाल ही में लॉन्च किए गए app dir के साथ, इस सुविधा को इस्तेमाल करने की कोई योजना नहीं है. लंबे समय तक, next/font का इस्तेमाल करना सबसे सही रहेगा.

Nuxt की मदद से, फ़ॉन्ट फ़ॉलबैक में बदलाव करने का तरीका

@nuxtjs/fontaine, Nuxt.js फ़्रेमवर्क का एक मॉड्यूल है. यह फ़ॉलबैक फ़ॉन्ट मेट्रिक की वैल्यू अपने-आप कैलकुलेट करता है और फ़ॉलबैक @font-face सीएसएस जनरेट करता है.

अपने मॉड्यूल कॉन्फ़िगरेशन में @nuxtjs/fontaine जोड़कर, मॉड्यूल चालू करें:

import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
  modules: ['@nuxtjs/fontaine'],
})

अगर Google Fonts का इस्तेमाल किया जा रहा है या किसी फ़ॉन्ट के लिए @font-face एलान नहीं किया गया है, तो उन्हें अन्य विकल्पों के तौर पर एलान किया जा सकता है.

ज़्यादातर मामलों में, मॉड्यूल आपकी सीएसएस से @font-face नियमों को पढ़ सकता है और फ़ॉन्ट-फ़ैमिली, फ़ॉलबैक फ़ॉन्ट फ़ैमिली, और डिसप्ले टाइप जैसी जानकारी अपने-आप निकाल सकता है.

अगर फ़ॉन्ट को ऐसी जगह पर तय किया गया है जहां मॉड्यूल उसे ढूंढ नहीं सकता, तो नीचे दिए गए कोड स्निपेट में दिखाए गए तरीके से मेट्रिक की जानकारी दी जा सकती है.

export default defineNuxtConfig({
  modules: ['@nuxtjs/fontaine'],
  fontMetrics: {
  fonts: ['Inter', { family: 'Some Custom Font', src: '/path/to/custom/font.woff2' }],
},
})

यह मॉड्यूल, @font-face एलान को पढ़ने के लिए आपकी सीएसएस को अपने-आप स्कैन करता है और फ़ॉलबैक @font-face नियम जनरेट करता है.

@font-face {
  font-family: 'Roboto';
  font-display: swap;
  src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff');
  font-weight: 700;
}
/* This will be generated. */
@font-face {
  font-family: 'Roboto override';
  src: local('BlinkMacSystemFont'), local('Segoe UI'), local('Roboto'), local('Helvetica Neue'),
    local('Arial'), local('Noto Sans');
  ascent-override: 92.7734375%;
  descent-override: 24.4140625%;
  line-gap-override: 0%;
}

अब अपनी सीएसएस में, फ़ॉलबैक फ़ॉन्ट के तौर पर Roboto override का इस्तेमाल किया जा सकता है. इसका उदाहरण यहां दिया गया है

:root {
  font-family: 'Roboto';
  /* This becomes */
  font-family: 'Roboto', 'Roboto override';
}

सीएसएस को खुद जनरेट करना

स्टैंडअलोन लाइब्रेरी की मदद से, फ़ॉलबैक फ़ॉन्ट साइज़ में बदलाव करने के लिए सीएसएस जनरेट की जा सकती है.

फ़ॉन्टेन लाइब्रेरी का इस्तेमाल करना

अगर Nuxt या Next.js का इस्तेमाल नहीं किया जा रहा है, तो Fontaine का इस्तेमाल किया जा सकता है. @nuxtjs/fontaine को काम करने में मदद करने वाली लाइब्रेरी को फ़ॉन्टेन कहा जाता है. अपने प्रोजेक्ट में इस लाइब्रेरी का इस्तेमाल करके, फ़ॉलबैक फ़ॉन्ट की सीएसएस को अपने-आप इंजेक्ट किया जा सकता है. इसके लिए, Vite या Webpack प्लग इन का इस्तेमाल करें.

मान लें कि आपने सीएसएस फ़ाइल में Roboto फ़ॉन्ट तय किया है:

@font-face {
  font-family: 'Roboto';
  font-display: swap;
  src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff');
  font-weight: 700;
}

फ़ॉन्टाइन, Vite और Webpack ट्रांसफ़ॉर्मर उपलब्ध कराता है, ताकि इन्हें आसानी से बिल्ड चेन में जोड़ा जा सके. नीचे दिए गए JavaScript में दिखाए गए तरीके से प्लग इन को चालू करें.

import { FontaineTransform } from 'fontaine'

const options = {
  fallbacks: ['BlinkMacSystemFont', 'Segoe UI', 'Helvetica Neue', 'Arial', 'Noto Sans'],
  // You may need to resolve assets like `/fonts/Roboto.woff2` to a particular directory
  resolvePath: (id) => 'file:///path/to/public/dir' + id,
  // overrideName: (originalName) => `${name} override`
  // sourcemap: false
}

अगर Vite का इस्तेमाल किया जा रहा है, तो प्लग इन को इस तरह जोड़ें: javascript // Vite export default { plugins: [FontaineTransform.vite(options)] }

अगर Webpack का इस्तेमाल किया जा रहा है, तो इसे इस तरह चालू करें:

// Webpack
export default {
  plugins: [FontaineTransform.webpack(options)]
}

@font-face नियमों में बदलाव करने के लिए, मॉड्यूल आपकी फ़ाइलों को अपने-आप स्कैन करेगा: css @font-face { font-family: 'Roboto'; font-display: swap; src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff'); font-weight: 700; } /* This will be generated. */ @font-face { font-family: 'Roboto override'; src: local('BlinkMacSystemFont'), local('Segoe UI'), local('Roboto'), local('Helvetica Neue'), local('Arial'), local('Noto Sans'); ascent-override: 92.7734375%; descent-override: 24.4140625%; line-gap-override: 0%; }

अब सीएसएस में, Roboto override को फ़ॉलबैक फ़ॉन्ट के तौर पर इस्तेमाल किया जा सकता है. css :root { font-family: 'Roboto'; /* This becomes */ font-family: 'Roboto', 'Roboto override'; }

Capsize लाइब्रेरी का इस्तेमाल करना

अगर Next.js, Nuxt, Webpack या Vite का इस्तेमाल नहीं किया जा रहा है, तो फ़ॉलबैक सीएसएस जनरेट करने के लिए, Capsize लाइब्रेरी का इस्तेमाल किया जा सकता है.

नया createFontStack एपीआई

यह एपीआई, createFontStack नाम के @capsize/core पैकेज का हिस्सा है. यह फ़ॉन्ट मेट्रिक के कलेक्शन को उसी क्रम में स्वीकार करता है जिस क्रम में आपने फ़ॉन्ट स्टैक (font-family प्रॉपर्टी) तय किया है.

Capsize का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, यहां मौजूद दस्तावेज़ देखें.

उदाहरण

इस उदाहरण पर विचार करें: पसंदीदा वेब फ़ॉन्ट Lobster है, जो Helvetica Neue और फिर Arial पर स्विच हो जाता है. सीएसएस में, font-family: Lobster, 'Helvetica Neue', Arial.

  1. कोर पैकेज से createFontStack इंपोर्ट करें:

    import { createFontStack } from '@capsizecss/core';
    
  2. अपनी पसंद के हर फ़ॉन्ट के लिए फ़ॉन्ट मेट्रिक इंपोर्ट करें (ऊपर फ़ॉन्ट मेट्रिक देखें): javascript import lobster from '@capsizecss/metrics/lobster'; import helveticaNeue from '@capsizecss/metrics/helveticaNeue'; import arial from '@capsizecss/metrics/arial';`

  3. मेट्रिक को ऐरे के तौर पर पास करके, अपना फ़ॉन्ट स्टैक बनाएं. इसके लिए, उसी क्रम का इस्तेमाल करें जिसका इस्तेमाल font-family CSS प्रॉपर्टी के लिए किया जाता है. javascript const { fontFamily, fontFaces } = createFontStack([ lobster, helveticaNeue, arial, ]);

इससे यह जानकारी मिलती है:

{
  fontFamily: Lobster, 'Lobster Fallback: Helvetica Neue', 'Lobster Fallback: Arial',
  fontFaces: [
    {
      '@font-face' {
      'font-family': '"Lobster Fallback: Helvetica Neue"';
      src: local('Helvetica Neue');
      'ascent-override': '115.1741%';
      'descent-override': '28.7935%';
      'size-adjust': '86.8251%';
      }
     '@font-face' {
       'font-family': '"Lobster Fallback: Arial"';
       src: local('Arial');
       'ascent-override': 113.5679%;
       'descent-override': 28.392%;
       'size-adjust': 88.053%;
     }
   }
 ]
}

आपको अपनी सीएसएस में fontFamily और fontFaces कोड जोड़ना होगा. नीचे दिए गए कोड में, इसे सीएसएस स्टाइल शीट या <style> ब्लॉक में लागू करने का तरीका बताया गया है.

<style type="text/css">
  .heading {
    font-family: 
  }

  
</style>

इससे यह सीएसएस जनरेट होगी:

.heading {
  font-family: Lobster, 'Lobster Fallback: Helvetica Neue',
    'Lobster Fallback: Arial';
}

@font-face {
  font-family: 'Lobster Fallback: Helvetica Neue';
  src: local('Helvetica Neue');
  ascent-override: 115.1741%;
  descent-override: 28.7935%;
  size-adjust: 86.8251%;
}
@font-face {
  font-family: 'Lobster Fallback: Arial';
  src: local('Arial');
  ascent-override: 113.5679%;
  descent-override: 28.392%;
  size-adjust: 88.053%;
}

बदली गई वैल्यू का हिसाब लगाने के लिए, @capsize/metrics पैकेज का इस्तेमाल भी किया जा सकता है. साथ ही, उन्हें सीएसएस में खुद भी लागू किया जा सकता है.

const fontMetrics = require(`@capsizecss/metrics/inter`);
const fallbackFontMetrics = require(`@capsizecss/metrics/arial`);
const mainFontAvgWidth = fontMetrics.xAvgWidth / fontMetrics.unitsPerEm;
const fallbackFontAvgWidth = fallbackFontMetrics.xAvgWidth / fallbackFontMetrics.unitsPerEm;
let sizeAdjust = mainFontAvgWidth / fallbackFontAvgWidth;
let ascent = fontMetrics.ascent / (unitsPerEm * fontMetrics.sizeAdjust));
let descent = fontMetrics.descent / (unitsPerEm * fontMetrics.sizeAdjust));
let lineGap = fontMetrics.lineGap / (unitsPerEm * fontMetrics.sizeAdjust));