วิธีใหม่ในการลดผลกระทบจากการโหลดฟอนต์: CSS Font Descriptors

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ แบบอักษรของเว็บมักจะแย่สำหรับประสิทธิภาพของเว็บ และไม่มีกลยุทธ์การโหลดแบบอักษรใดที่มีประสิทธิภาพเป็นพิเศษในการแก้ไขปัญหาดังกล่าว ตัวเลือกแบบอักษรที่กำลังจะมีขึ้นในท้ายที่สุดอาจช่วยให้จัดแนวแบบอักษรสำรองกับแบบอักษรสุดท้ายได้ง่ายขึ้น

การโหลดแบบอักษรเป็นปัญหาด้านประสิทธิภาพของเว็บมาช้านานแล้ว และไม่มีตัวเลือกที่ดีที่นี่ หากคุณต้องการใช้แบบอักษรบนเว็บ ตัวเลือกของคุณคือ Flash of Invisible Text (หรือที่เรียกว่า FOIT) ซึ่งข้อความจะถูกซ่อนไว้จนกว่าจะดาวน์โหลดแบบอักษรหรือ Flash of Unstyled Text (FOUT) ที่คุณใช้แบบอักษรระบบทางเลือกในตอนแรก จากนั้นอัปเกรดเป็น แบบอักษรเว็บเมื่อดาวน์โหลด ไม่มีตัวเลือกใดที่ "ชนะ" จริง ๆ เพราะทั้งสองไม่เป็นที่น่าพอใจจริงๆ

ไม่ใช่ font-display เพื่อแก้ปัญหานี้ใช่หรือไม่

คุณสมบัติ font-display สำหรับ @font-face มอบทางเลือกดังกล่าวให้กับนักพัฒนาเว็บ ในขณะที่ก่อนหน้านี้เบราว์เซอร์ตัดสินใจว่า (IE และ Edge ชอบ FOUT ในอดีต ในขณะที่เบราว์เซอร์อื่นๆ ชอบ FOIT) อย่างไรก็ตาม ยิ่งไปกว่านั้น มันยังแก้ปัญหาไม่ได้จริงๆ

ไซต์จำนวนหนึ่งย้ายไปที่ font-display: swap เมื่อเปิดตัวครั้งแรกและ Google Fonts ยังทำให้เป็นค่าเริ่มต้นในปี 2019 ความคิดที่นี่คือจะดีกว่าสำหรับประสิทธิภาพในการ แสดงข้อความโดยเร็วที่สุด แม้ว่า อยู่ในฟอนต์สำรอง จากนั้นจึงสลับฟอนต์เมื่อดาวน์โหลดในที่สุด

ฉันก็สนับสนุนเรื่องนี้เช่นกัน แต่ฉันรู้สึกหงุดหงิดกับ "เอฟเฟกต์ไฮเดรชัน" มากขึ้นเมื่อการดาวน์โหลดแบบอักษรเว็บและตัวอักษรขยาย (หรือหดตัว) เนื่องจากความแตกต่างระหว่างแบบอักษร Smashing Magazine เช่นเดียวกับผู้จัดพิมพ์ส่วนใหญ่ ใช้แบบอักษรของเว็บ และภาพหน้าจอด้านล่างแสดงความแตกต่างระหว่างการแสดงผลเริ่มต้น (ด้วยแบบอักษรสำรอง) และการแสดงผลขั้นสุดท้าย (ด้วยแบบอักษรของเว็บ):

ภาพหน้าจอสองภาพในบทความ Smashing Magazine ที่มีแบบอักษรต่างกัน ข้อความมีขนาดแตกต่างกันอย่างเห็นได้ชัดและสามารถใส่ประโยคเพิ่มเติมได้เมื่อใช้แบบอักษรเว็บ
บทความ Smashing Magazine ที่มีแบบอักษรสำรองและแบบอักษรเว็บแบบเต็ม (ตัวอย่างขนาดใหญ่)

เมื่อวางเคียงข้างกัน แบบอักษรของเว็บดูดีขึ้นมาก และเข้ากับแบรนด์ Smashing Magazine แต่เรายังเห็นว่าเลย์เอาต์ ข้อความของฟอนต์ทั้งสองมีความแตกต่างกัน ค่อนข้างมาก แบบอักษรมีขนาดแตกต่างกันมากและด้วยเหตุนี้ เนื้อหาบนหน้าจอจึงเปลี่ยนไป ในยุคของ Core Web Vitals และ Cumulative Layout Shifts (ค่อนข้างถูกต้อง!) ที่ได้รับการยอมรับว่าเป็นอันตรายต่อผู้ใช้ font-display: swap เป็นตัวเลือกที่ไม่ดีเพราะเหตุนั้น

ฉันเปลี่ยนกลับเป็นการ font-display: block ไซต์ที่ฉันดูแล เนื่องจากพบว่าการเปลี่ยนข้อความค่อนข้างสั่นคลอนและน่ารำคาญ แม้ว่า block จะไม่หยุดกะ (แบบอักษรยังคงแสดงเป็นข้อความที่มองไม่เห็น) ก็ตาม อย่างน้อยก็ทำให้ผู้ใช้สังเกตเห็นได้น้อยลง ฉันยังเพิ่มประสิทธิภาพด้วยการโหลดแบบอักษรด้วยการโหลดแบบอักษรล่วงหน้าที่ฉันสร้างให้มีขนาดเล็กที่สุดโดย ใช้แบบอักษรย่อยที่โฮสต์เอง — ดังนั้นผู้เยี่ยมชมมักจะเห็นแบบอักษรสำรองในช่วงเวลาเพียงเล็กน้อยเท่านั้น สำหรับฉัน "ระยะเวลาบล็อก" ของการ swap นั้นสั้นเกินไป และฉันต้องการรออีกสักหน่อยเพื่อให้การเรนเดอร์เริ่มต้นถูกต้อง

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

การใช้การ font-display: optional สามารถแก้ FOIT และ FOUT — ที่ค่าใช้จ่าย

อีกทางเลือกหนึ่งคือใช้ font-display: optional โดยพื้นฐานแล้วตัวเลือกนี้จะทำให้แบบอักษรของเว็บเป็นตัวเลือก หรือจะใส่อย่างอื่นแทนก็ได้ ถ้าแบบอักษรนั้นไม่มีอยู่ในขณะที่หน้าต้องการ ก็เป็นหน้าที่ของเบราว์เซอร์ที่จะไม่สลับเปลี่ยนมัน ด้วยตัวเลือกนี้ เราหลีกเลี่ยงทั้ง FOIT และ FOUT โดยพื้นฐานแล้วจะใช้เฉพาะแบบอักษรที่ดาวน์โหลดแล้วเท่านั้น

หากแบบอักษรของเว็บไม่พร้อมใช้งาน เราจะถอยกลับไปใช้แบบอักษรสำรอง แต่การนำทางหน้าถัดไป (หรือโหลดหน้านี้ใหม่) จะใช้แบบอักษรนั้น ซึ่งน่าจะดาวน์โหลดเสร็จแล้วในขณะนั้น อย่างไรก็ตาม หากแบบอักษรของเว็บไม่สำคัญสำหรับไซต์ อาจเป็นความคิดที่ดีที่จะลบออกทั้งหมด ซึ่งดียิ่งขึ้นสำหรับประสิทธิภาพของเว็บ!

การแสดงผลครั้งแรกมีความสำคัญและการโหลดครั้งแรกโดยไม่มีแบบอักษรของเว็บเลยดูเหมือนจะมากเกินไป ฉันยังคิด - ไม่มีหลักฐานสนับสนุนเรื่องนี้อย่างแน่นอน! — ว่าจะทำให้ผู้คนรู้สึกประทับใจ บางทีอาจไม่รู้ตัวว่ามีบางอย่าง "ปิด" เกี่ยวกับเว็บไซต์และอาจส่งผลต่อวิธีที่ผู้คนใช้เว็บไซต์

ดังนั้น ตัวเลือกแบบอักษรทั้งหมดจึงมีข้อเสีย รวมถึงตัวเลือกที่จะไม่ใช้แบบอักษรของเว็บเลย หรือใช้แบบอักษรของระบบ (ซึ่งมีการจำกัด — แต่อาจไม่ จำกัด เท่าที่หลายคนคิด!)

ทำให้ฟอนต์สำรองของคุณตรงกับฟอนต์ของคุณมากขึ้น

จอกศักดิ์สิทธิ์ของการโหลดแบบอักษรเว็บคือการ ทำให้แบบอักษรสำรองใกล้เคียงกับแบบอักษรของเว็บจริงมากขึ้น เพื่อลดการเปลี่ยนแปลงที่เห็นได้ชัดเจนให้มากที่สุดเท่าที่จะเป็นไปได้ ดังนั้นการใช้การ swap จึงส่งผลกระทบน้อยลง แม้ว่าเราจะไม่สามารถหลีกเลี่ยงการเปลี่ยนแปลงทั้งหมดได้ แต่เราสามารถทำได้ดีกว่าในภาพหน้าจอด้านบน แอพ Font Style Matcher โดย Monica Dinculescu มักถูกอ้างถึงในบทความการโหลดแบบอักษรและให้เหลือบที่ยอดเยี่ยมของสิ่งที่ควรจะเป็นไปได้ที่นี่ ช่วยให้คุณ ซ้อนทับข้อความเดียวกันในแบบอักษรที่แตกต่างกันสองแบบ ได้ เพื่อดูว่าแตกต่างกันอย่างไร และปรับการตั้งค่าแบบอักษรเพื่อให้สอดคล้องกันมากขึ้น:

ภาพหน้าจอ Font Style Matcher แสดงสองชุดเหนือข้อความที่วางทับกัน โดยด้านบนมีความแตกต่างกันมาก และด้านล่างมีข้อความคล้ายกันมาก
ภาพหน้าจอ Font Style Matcher พร้อมค่าเริ่มต้น การตั้งค่าเดียวกันสำหรับแบบอักษรสองแบบ (บนสุด) และการตั้งค่าที่ปรับแล้วเพื่อให้เข้ากันได้ดียิ่งขึ้น (ด้านล่าง) (ตัวอย่างขนาดใหญ่)

ขออภัย ปัญหาของการจับคู่รูปแบบแบบอักษรคือเราไม่สามารถให้รูปแบบ CSS เหล่านี้ใช้ได้กับแบบอักษรทางเลือก เท่านั้น เราจึงต้องใช้ JavaScript และ FontFace.load API เพื่อปรับใช้ (หรือเปลี่ยนกลับ) ความแตกต่างของสไตล์เหล่านี้ เมื่อเว็บ โหลดแบบอักษร

จำนวนโค้ดไม่มากนัก แต่ก็ยังรู้สึกเหมือนต้องใช้ความพยายามมากกว่าที่ควรจะเป็น แม้ว่าจะมีข้อดีและความเป็นไปได้อื่น ๆ ในการใช้ JavaScript API สำหรับสิ่งนี้ตามที่ Zach Leatherman อธิบายในการพูดคุยที่ยอดเยี่ยมนี้ตั้งแต่ปี 2019 — คุณสามารถลดการรีโฟลว์และจัดการโหมด data-server และ prefers-reduced-motion ได้ (อย่างไรก็ตาม ที่ทั้งสองได้สัมผัสกับ CSS ตั้งแต่นั้นมา)

การจัดการฟอนต์แคชที่เรามีอยู่แล้วนั้นยังยากกว่าอีกด้วย ไม่ต้องพูดถึงความแตกต่างในสไตล์ทางเลือกต่างๆ ใน Smashing Magazine เราลองใช้ทางเลือกอื่นเพื่อใช้ประโยชน์จากแบบอักษรของระบบที่ผู้ใช้และระบบปฏิบัติการต่างๆ ได้ติดตั้งไว้ให้เกิดประโยชน์สูงสุด:

 font-family: Mija,-apple-system,Arial,BlinkMacSystemFont,roboto slab,droid serif,segoe ui,Ubuntu,Cantarell,Georgia,serif;

การรู้ว่าแบบอักษรใดใช้หรือมีการปรับเปลี่ยนแต่ละรายการและตรวจสอบว่ามีการใช้แบบอักษรอย่างถูกต้องอาจกลายเป็นเรื่องที่ซับซ้อนได้อย่างรวดเร็ว

ทางออกที่ดีกว่ากำลังจะมา

นั่นเป็นบทสรุปสั้น ๆ ว่าสิ่งต่าง ๆ เป็นอย่างไร ณ วันนี้ อย่างไรก็ตาม มีควันเริ่มปรากฏบนขอบฟ้า

ดังที่ได้กล่าวไว้ก่อนหน้านี้ ปัญหาหลักในการใช้ความแตกต่างของการจัดรูปแบบทางเลือกคือการเพิ่มแล้วนำออก จะเกิดอะไรขึ้นถ้าเราสามารถบอกเบราว์เซอร์ว่าความแตกต่างเหล่านี้มีไว้สำหรับฟอนต์สำรองเท่านั้น

นั่นคือสิ่งที่ชุด คำอธิบายฟอนต์ ใหม่ถูกเสนอให้เป็นส่วนหนึ่งของ CSS Fonts Module ระดับ 5 ทำ สิ่งเหล่านี้ถูกนำไปใช้กับการประกาศ @font-face ที่มีการกำหนดฟอนต์แต่ละตัว

Simon Hearne ได้เขียนเกี่ยวกับการอัปเดตที่เสนอนี้สำหรับข้อกำหนด font-face descriptors ซึ่งรวมถึง descriptors ใหม่สี่ตัว: ascent-override , descent-override , line-gap-override และ advance-override (ตั้งแต่หลุดออกมา) คุณสามารถเล่นกับสนามเด็กเล่น F-mods ที่ Simon สร้างขึ้นเพื่อโหลดแบบอักษรที่กำหนดเองและแบบอักษรสำรอง จากนั้นเล่นกับการแทนที่เพื่อให้ได้คู่ที่สมบูรณ์แบบ

ตามที่ Simon เขียน การรวมกันของสี่ descriptor นี้ทำให้เราสามารถแทนที่เลย์เอาต์ของฟอนต์ทางเลือกเพื่อให้ตรงกับฟอนต์ของเว็บ แต่จริงๆ แล้วพวกมันปรับเปลี่ยนการเว้นวรรคและการวางตำแหน่งในแนวตั้งเท่านั้น ดังนั้นสำหรับการเว้นวรรคระหว่างอักขระและตัวอักษร เราจะต้องจัดเตรียม CSS เพิ่มเติม

แต่สิ่งต่าง ๆ ดูเหมือนจะเปลี่ยนไปอีกครั้ง ล่าสุด advance-override ได้ถูกยกเลิกไปเนื่องจากตัวอธิบาย size-adjust ที่กำลังจะมีขึ้น ซึ่งช่วยให้เราลดการเลื่อนเลย์เอาต์โดยจับคู่ฟอนต์สำรองและฟอนต์เว็บหลักผ่านตัวคูณมาตราส่วนสำหรับร่ายมนตร์ (เปอร์เซ็นต์)

มันทำงานอย่างไร? สมมติว่าคุณมี CSS ต่อไปนี้:

 @font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } h1 { font-family: Lato, Arial, sans-serif; }

จากนั้นสิ่งที่คุณจะทำคือสร้าง @font-face สำหรับฟอนต์ Arial fallback และใช้ ตัวอธิบายตัว ปรับแต่งกับมัน คุณจะได้รับข้อมูลโค้ด CSS ต่อไปนี้:

 @font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } @font-face { font-family: "Lato-fallback"; size-adjust: 97.38%; ascent-override: 99%; src: local("Arial"); } h1 { font-family: Lato, Lato-fallback, sans-serif; }

ซึ่งหมายความว่าเมื่อใช้ Lato-fallback ในขั้นต้น (เนื่องจาก Arial เป็นฟอนต์ local เครื่องและสามารถใช้งานได้ทันทีโดยไม่ต้องดาวน์โหลดเพิ่มเติม) การตั้งค่าการ size-adjust และ ascent-override ทำให้คุณเข้าใกล้ฟอนต์ Lato มากขึ้น เป็นการประกาศพิเศษ @font-face ในการเขียน แต่ง่ายกว่าห่วงที่เราต้องข้ามไปก่อนอย่างแน่นอน!

โดยรวมแล้ว มี ตัวอธิบาย @font-face หลักสี่ตัวที่ รวมอยู่ในข้อมูลจำเพาะนี้: size-adjust , ascent-override , descent-override และ line-gap-override โดยที่อีกสองสามตัวยังคงได้รับการพิจารณาสำหรับตัวห้อย ตัวยก และกรณีการใช้งานอื่นๆ .

Malte Ubl ได้สร้างเครื่องมือที่มีประโยชน์มากในการคำนวณการตั้งค่าเหล่านี้โดยอัตโนมัติด้วยแบบอักษรสองแบบและเบราว์เซอร์ที่รองรับการตั้งค่าใหม่เหล่านี้ (เพิ่มเติมเกี่ยวกับสิ่งนี้ในอีกสักครู่!) ดังที่ Malte ชี้ให้เห็น คอมพิวเตอร์เก่งในเรื่องนั้น! ตามหลักการแล้ว เราอาจเปิดเผยการตั้งค่าเหล่านี้สำหรับแบบอักษรทั่วไปแก่นักพัฒนาเว็บ เช่น อาจให้คำแนะนำเหล่านี้ในคอลเล็กชันแบบอักษร เช่น Google Fonts ที่จะช่วยเพิ่มการรับเลี้ยงบุตรบุญธรรมได้อย่างแน่นอน

ตอนนี้ระบบปฏิบัติการที่แตกต่างกันอาจมี การตั้งค่าแบบอักษรที่แตกต่างกัน เล็กน้อย และการทำให้สิ่งเหล่านี้ถูกต้องโดยพื้นฐานแล้วเป็นงานที่เป็นไปไม่ได้ แต่นั่นไม่ใช่จุดมุ่งหมาย เป้าหมายคือการปิดช่องว่าง ดังนั้น การใช้ font-display: swap ไม่ใช่ประสบการณ์ที่น่ารำคาญอีกต่อไป แต่เราไม่จำเป็นต้องเลือกใช้แบบอักษรบนเว็บที่ optional หรือไม่มีเลย

เราจะเริ่มใช้งานได้เมื่อใด

มี การจัดส่งการตั้งค่าสามรายการใน Chrome แล้วตั้งแต่เวอร์ชัน 87 แม้ว่าตัวอธิบาย size-adjust คีย์จะยังไม่มีให้บริการในเบราว์เซอร์ที่เสถียร อย่างไรก็ตาม Chrome Canary มีสิ่งนี้ เช่นเดียวกับ Firefox ที่อยู่เบื้องหลังแฟล็ก ดังนั้นนี่ไม่ใช่แนวคิดที่เป็นนามธรรมที่อยู่ห่างไกล แต่เป็นบางสิ่งที่อาจจะเกิดขึ้นในไม่ช้า

ในขณะนี้ ข้อมูลจำเพาะมีข้อจำกัดความรับผิดชอบและคำเตือนทุกประเภทที่ยังไม่พร้อมสำหรับเรียลไทม์ แต่รู้สึกเหมือนกำลังไปที่นั่นอย่างแน่นอน เช่นเคย มีความสมดุลระหว่างเรา นักออกแบบ และนักพัฒนา การทดสอบและให้ข้อเสนอแนะ และไม่สนับสนุนการใช้งาน ดังนั้นการใช้งานจึงไม่ติดขัดเพราะมีคนจำนวนมากเกินไปที่ลงเอยด้วยการใช้แบบร่างก่อนหน้านี้

Chrome ได้ระบุเจตจำนงที่จะให้ size-adjust พร้อมใช้งานใน Chrome 92 ที่จะวางจำหน่ายในวันที่ 20 กรกฎาคม ซึ่งน่าจะบ่งชี้ว่ามันเกือบจะอยู่ที่นั่นแล้ว

ยังไม่พร้อม แต่ดูเหมือนว่าในอนาคตอันใกล้นี้ ในระหว่างนี้ ลองเล่นกับตัวอย่างใน Chrome Canary และดูว่าสามารถแก้ไขปัญหาการโหลดฟอนต์ของคุณและผลกระทบ CLS ที่เกิดขึ้นได้หรือไม่