ภาพรวม Pretext.JS
Pretext.JS คือเอนจินจัดวางตัวอักษรด้วย JavaScript/TypeScript ล้วน ที่มีความเร็วสูง ออกแบบมาเพื่อคำนวณและจัดตำแหน่งข้อความหลายบรรทัดด้วยเลขคณิตล้วน ๆ โดยไม่ต้องยุ่งกับ Document Object Model (DOM) เลย ช่วยตัดคอขวดด้านประสิทธิภาพจาก “forced synchronous reflows” ที่เกิดจากการวัด DOM แบบเดิม เช่น getBoundingClientRect() ทำให้การจัดวางข้อความเร็วและมีประสิทธิภาพกว่ามาก พัฒนาบนหลักการ “วัดครั้งเดียว ใช้จัด layout ได้ตลอดไป” ทำให้การคำนวณ layout ครั้งถัด ๆ ไปแทบจะเกิดขึ้นทันที
วัตถุประสงค์หลัก
ให้การวัด layout ข้อความ (เช่น ความสูง และจำนวนบรรทัด) ที่มีประสิทธิภาพสูง แม่นยำ และไม่มีการ reflow เหมาะกับเว็บอินเทอร์เฟซที่ซับซ้อนและเปลี่ยนแปลงตลอดเวลา แก้ปัญหาสำคัญเรื่องประสิทธิภาพจาก browser thrashing ที่เกิดจากการวัด DOM ซ้ำไปซ้ำมา
กลุ่มผู้ใช้เป้าหมาย
นักพัฒนาเว็บและทีมที่สร้าง UI ที่ต้องเน้นประสิทธิภาพและมีข้อความจำนวนมาก เช่น แอปที่ใช้ virtual scrolling list, อินเทอร์เฟซแชทของ AI, code editor, กระดานไวท์บอร์ดแบบร่วมมือกัน, data visualization และทุกกรณีที่ต้องการ layout ข้อความแบบไดนามิกที่ลื่นไหล รวดเร็ว และตอบสนองดี โดยไม่ลดทอนประสบการณ์ผู้ใช้
รายละเอียดฟังก์ชันและการทำงาน
Pretext.JS ทำงานหลัก ๆ สองขั้นตอน:
-
prepare(text, font)
ฟังก์ชันนี้รันหนึ่งครั้งสำหรับข้อความและสไตล์ฟอนต์ที่กำหนด ทำการจัดรูปแบบ whitespace ใหม่ ใช้กฎ Unicode line-break แบ่งส่วนข้อความ และวัดความกว้าง advance width ของ glyph แต่ละ segment อย่างแม่นยำผ่าน Canvas font engine ของเบราว์เซอร์ จากนั้นเก็บผลลัพธ์ไว้ใน “handle” ที่นำกลับมาใช้ซ้ำได้ -
layout(handle, containerWidth, lineHeight)
ฟังก์ชันนี้ใช้เพียงเลขคณิตและรันได้แทบจะทันที เมื่อมี handle ที่เตรียมไว้ ความกว้างของคอนเทนเนอร์ และ line height มันจะคำนวณจุดตัดบรรทัดโดยบวกความกว้างของ segment ต่าง ๆ คิดจำนวนบรรทัดรวม และหาความสูงรวมของข้อความ ที่สำคัญคือขั้นตอนนี้ไม่อ่าน DOM เลย ทำให้ไม่มี reflow เกิดขึ้น
ความสามารถหลัก
-
Zero DOM Reads
หลังจากเรียกprepare()ครั้งแรกแล้ว การเรียกlayout()ทั้งหมดจะเป็นการคำนวณเชิงเลขล้วน ๆ ไม่แตะgetBoundingClientRect(),offsetHeightหรือ forced synchronous reflows อีกต่อไป -
Real Font Metrics
ใช้ Canvas font engine แบบ native ของเบราว์เซอร์ในการวัดความกว้าง glyph เพื่อให้ผล layout ตรงกับการเรนเดอร์จริงของเบราว์เซอร์อย่างแม่นยำ -
Multilingual by Design
รองรับระบบการเขียนที่ซับซ้อนอย่างสมบูรณ์ เช่น CJK (จีน ญี่ปุ่น เกาหลี), อาหรับ, ฮีบรู, ไทย และฮินดี พร้อมการแบ่งข้อความตาม Unicode ที่ถูกต้องและจัดการ bidirectional text ได้ -
TypeScript-Native
พัฒนาด้วย TypeScript ตั้งแต่ต้น ให้ประเภทข้อมูล (types) ที่ชัดเจนครบถ้วนสำหรับทุกฟังก์ชัน พารามิเตอร์ และค่าที่ส่งกลับ โดยไม่ต้องพึ่งแพ็กเกจ@typesภายนอก -
Reusable Prepared Handles
การเรียกprepare()เพียงครั้งเดียวจะได้ handle ที่นำกลับมาใช้คำนวณ layout ได้กับหลายความกว้างของคอนเทนเนอร์ (เช่น มือถือ แท็บเล็ต เดสก์ท็อป) ด้วย overhead ที่ต่ำมาก -
Zero Runtime Dependencies
สร้างบนมาตรฐาน API ของเบราว์เซอร์ล้วน ๆ ทำให้ bundle มีขนาดเล็กและไม่ต้องกังวลกับปัญหาจากแพ็กเกจภายนอก
ประโยชน์ต่อผู้ใช้
-
ประสิทธิภาพสูงมาก
ทำให้การจัด layout ข้อความเร็วขึ้นได้ถึงราว 500 เท่าเมื่อเทียบกับวิธีที่พึ่ง DOM แบบดั้งเดิม รองรับการเลื่อนหน้าจอที่ลื่นที่ 60fps และ UI ที่ตอบสนองได้ดีแม้มี element ข้อความแบบไดนามิกนับพัน -
ประสบการณ์ผู้ใช้ดีขึ้น
ลดปัญหา UI “thrashing” การเคลื่อน/ขยับ และการสั่นของ layout ทำให้ประสบการณ์การมองเห็นลื่นไหลและนิ่ง โดยเฉพาะใน feed เนื้อหาแบบ dynamic หรืออินเทอร์เฟซแชท -
Layout แม่นยำ
ให้ค่าการวัดข้อความที่ตรงกับการเรนเดอร์จริงของเบราว์เซอร์ ป้องกันความไม่สอดคล้องด้านภาพ -
ลดความซับซ้อนในการพัฒนา
มี API แบบ TypeScript-native ที่เข้าใจง่าย ช่วยซ่อนความยุ่งยากของการวัดข้อความ และเพิ่มประสิทธิภาพการทำงานของนักพัฒนา -
พร้อมสำหรับแอประดับสากล
การรองรับระบบการเขียนหลากหลายอย่างแข็งแรง ทำให้สร้างแอประดับสากล (internationalized applications) ได้จริง -
น้ำหนักเบาและเสถียร
ไม่มี dependency ภายนอก ทำให้ bundle เล็กลงและลดจุดล้มเหลว (point of failure)
ความเข้ากันได้และการผสานรวม
-
Framework-Agnostic
ในฐานะไลบรารี JavaScript/TypeScript ล้วน Pretext.JS สามารถผสานรวมได้อย่างราบรื่นกับทุกเฟรมเวิร์กเว็บสมัยใหม่ (เช่น React, Vue, Angular, Svelte) หรือโค้ด JavaScript เปล่า ๆ -
รองรับเบราว์เซอร์สมัยใหม่
ใช้มาตรฐาน API ของเบราว์เซอร์ที่มีอยู่ในสภาพแวดล้อมเว็บสมัยใหม่ทั้งหมด -
การติดตั้ง
ติดตั้งได้ง่ายผ่านตัวจัดการแพ็กเกจยอดนิยม: npm, pnpm และ bun -
การผสานกับ TypeScript
การรองรับ TypeScript แบบ native ทำให้รวมเข้ากับโปรเจกต์ TypeScript ได้อย่างราบรื่นโดยไม่ต้องตั้งค่าเพิ่มเติม
ตัวอย่างการใช้งานจริงและเดโม
-
Virtual Scroll
เดโมการเรนเดอร์แถวที่มีความสูงแปรผัน 10,000 แถว ด้วยการเลื่อนที่ลื่น 60fps โดยคำนวณทั้งหมดโดยไม่อ่าน DOM -
AI Chat
ใช้ล่วงหน้าคำนวณความสูงของ chat bubble สำหรับข้อความตอบแบบสตรีมจาก AI เพื่อลบปัญหา layout shift และอาการกระตุก -
Internationalization
โชว์ layout ที่แม่นยำสำหรับ feed เนื้อหาหลายภาษา ที่ผสมภาษาจีน อาหรับ เกาหลี และตัวอักษรละตินใน virtualized list เดียวกัน -
Community Showcases
มีตัวอย่างการใช้งานสร้างสรรค์ เช่น เอฟเฟกต์เขียนตัวอักษรบนทราย การแสดงข้อความแบบ geometric และการพันข้อความรอบวัตถุ 3D แบบเรียลไทม์ แสดงให้เห็นความยืดหยุ่นของไลบรารี
วิธีเข้าถึงและเริ่มใช้งาน
-
การติดตั้ง
- ใช้ npm:
$ npm install @chenglou/pretext - ใช้ pnpm:
$ pnpm add @chenglou/pretext - ใช้ bun:
$ bun add @chenglou/pretext
- ใช้ npm:
-
การใช้งาน
- import ฟังก์ชัน
prepareและlayout:
import { prepare, layout } from '@chenglou/pretext' - เรียก
prepare(text, font)หนึ่งครั้งเพื่อรับ handle ที่นำกลับมาใช้ซ้ำได้ - เรียก
layout(handle, containerWidth, lineHeight)เพื่อรับค่าความสูงและจำนวนบรรทัดอย่างฉับไว
- import ฟังก์ชัน
-
การทดลองใช้งาน
มี live playground และเดโมหลากหลายให้ลองเล่นและทำความเข้าใจได้ทันทีบนเว็บไซต์ทางการ (pretextjs.dev)