ทำไมต้อง Lit
จุดอ่อนของ Vanilla Custom Elements
หัวข้อที่มีชื่อว่า “จุดอ่อนของ Vanilla Custom Elements”เมื่อ component ของคุณมี state และต้องอัปเดต UI ตามการเปลี่ยนแปลง Vanilla Custom Elements บังคับให้คุณเขียน boilerplate จำนวนมาก เช่น:
- เรียก
this.shadowRoot.innerHTML = ...ทุกครั้งที่ state เปลี่ยน - ผูก event listeners ซ้ำซ้อนทุกครั้งที่ re-render
- ไม่มี diffing — DOM ทั้งหมดถูกสร้างใหม่
การตั้ง innerHTML ซ้ำๆ นั้นไม่ใช่แค่ verbose แต่ยังมีปัญหาด้านประสิทธิภาพ เพราะทำลายและสร้าง DOM subtree ใหม่ทุกครั้ง รวมถึงลบ event listeners ที่ผูกไว้กับ child elements ทั้งหมด
Lit แก้ปัญหาอย่างไร
หัวข้อที่มีชื่อว่า “Lit แก้ปัญหาอย่างไร”Lit ใช้ html tagged template literal เพื่อสร้าง TemplateResult ซึ่ง Lit จะนำไป diff กับ DOM ที่มีอยู่ แทนที่จะสร้างใหม่ทั้งหมด วิธีนี้ทำให้:
- อัปเดตเฉพาะส่วนที่เปลี่ยนแปลง
- Event listeners ไม่ถูกลบและเพิ่มซ้ำ
- โค้ดกระชับและอ่านง่ายขึ้นมาก
ตัวอย่าง: Counter ด้วย Lit
หัวข้อที่มีชื่อว่า “ตัวอย่าง: Counter ด้วย Lit”class LitCounter extends LitElement { static properties = { count: { type: Number } }; constructor() { super(); this.count = 0; } render() { return html` <p>Count: <span>${this.count}</span></p> <button @click=${() => this.count++}>+</button> `; }}ลองใช้งาน counter ด้านล่างนี้:
เมื่อไหร่ที่ควรใช้ Lit และเมื่อไหร่ที่ไม่ควร
หัวข้อที่มีชื่อว่า “เมื่อไหร่ที่ควรใช้ Lit และเมื่อไหร่ที่ไม่ควร”ควรใช้ Lit เมื่อ:
- Component มี reactive state ที่ต้องอัปเดต UI
- ต้องการ scoped styles ที่จัดการง่าย
- กำลังสร้าง component library สำหรับใช้ข้าม frameworks
ไม่จำเป็นต้องใช้ Lit เมื่อ:
- Element เป็นแค่โครงสร้างแบบ static โดยไม่มี dynamic state
- ต้องการ bundle ขนาดเล็กที่สุดและ component ง่ายมาก
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
ใช้ LitElement (Lit) | Developer experience ดีขึ้นมากจาก reactive properties และ template diffing ที่ทำให้ไม่ต้องเขียน DOM update เอง | เพิ่ม runtime ประมาณ +5-6KB (gzip) เข้าไปใน bundle ของทุก component |
ใช้ raw HTMLElement (ไม่มี library) | ไม่มี runtime เพิ่มเลย และอิงตาม web standard ล้วนๆ ทำให้มีอายุการใช้งานยาวที่สุด | ต้องเขียน boilerplate เองทั้งหมด เช่น attribute parsing, dirty-checking และ DOM diffing ด้วยมือ |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- เลือก Lit ทั้งที่ element ไม่มี state — ถ้า component เป็นแค่โครงสร้าง static ล้วนๆ การดึง Lit เข้ามาเพิ่ม +5-6KB โดยไม่ได้ประโยชน์อะไร ใช้
HTMLElementเปล่าๆ ก็เพียงพอ - กลัวว่า Lit จะ “ผูกติด” กับ project ระยะยาว —
LitElementcompile ออกมาเป็น standard custom element ธรรมดา ไม่ได้ล็อก runtime แบบ framework ทั่วไป การย้ายออกในอนาคตจึงไม่ยากเท่าที่คิด - เขียน diffing เองทั้งที่ state ซับซ้อนหลายจุด — การจัดการ re-render ด้วยมือเมื่อมี state หลายตัวมักจบลงด้วยโค้ดที่หนักกว่าและบั๊กง่ายกว่าใช้ template diffing ของ Lit ที่ผ่านการทดสอบมาแล้ว
💡 ตัวอย่างจากของจริง
Google Material Web — ชุด component มาตรฐานของ Google (Material Design) สร้างด้วย Lit และใช้งานจริงในโปรดักต์ของ Google หลายตัว
Home Assistant — แพลตฟอร์ม home automation แบบ open-source ที่ได้รับความนิยมสูง สร้าง frontend UI ทั้งหมดด้วย custom elements ที่อิง Lit