2 คะแนน โดย GN⁺ 2024-10-01 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การถกเถียงเรื่องเว็บคอมโพเนนต์ไม่ใช่เรื่องของการเลือกอย่างใดอย่างหนึ่งระหว่าง ประสิทธิภาพสูงสุด กับ มาตรฐานแพลตฟอร์ม และตั้งแต่สมมติฐานว่ามันต้องมาแทนที่เฟรมเวิร์ก JavaScript ทั้งหมดก็เกินไปแล้ว
  • Custom Elements มีโอเวอร์เฮดเพราะใช้ DOM เป็นอินเทอร์เฟซ แต่ในผลิตภัณฑ์จริง ต้องตัดสินโดยพิจารณาไม่ใช่แค่ประสิทธิภาพ แต่รวมถึง ความสามารถในการบำรุงรักษา·ความปลอดภัย·การใช้งาน·การเข้าถึง ด้วย
  • ต้นทุนของเฟรมเวิร์กในการรองรับเว็บคอมโพเนนต์สามารถดูดซับได้ด้วยการตรวจสอบง่าย ๆ บางอย่าง และการที่เป็นฟีเจอร์มาตรฐานก็ไม่ได้หมายความว่าทุกเฟรมเวิร์กจำเป็นต้องนำไปใช้
  • เว็บคอมโพเนนต์มีจุดอ่อนในเรื่อง server-side rendering (SSR), การเข้าถึง และการทำงานร่วมกันบางส่วน จึงยังมีสถานการณ์ที่ React·Solid·Svelte เหมาะสมกว่า
  • ในสภาพแวดล้อมอย่าง Salesforce ที่แอปแบบ client rendering, ตลาดคอมโพเนนต์ และ ความเข้ากันได้ย้อนหลัง ระยะยาวเป็นเรื่องสำคัญ เว็บคอมโพเนนต์อาจเป็นตัวเลือกที่สมจริงได้

จุดเริ่มต้นของข้อถกเถียงและจุดยืนของผู้เขียน

  • ข้อถกเถียงล่าสุดต่อเนื่องมาจาก “Web Components Are Not the Future” ของ Ryan Carniato และ “Web Components Are Not the Future — They’re the Present” ของ Cory LaViska
  • ประเด็นไม่ได้อยู่ที่การโจมตีอีกฝ่าย แต่ใกล้เคียงกับคำถามว่านักพัฒนาที่มีข้อจำกัดต่างกันจะหา จุดร่วม กันได้หรือไม่
  • Ryan Carniato ได้รับการยกย่องสูงจากผลงานด้านประสิทธิภาพและการออกแบบเฟรมเวิร์กที่เห็นได้จาก Solid และ js-framework-benchmark
  • เว็บคอมโพเนนต์เองก็มีพื้นที่ใช้งานจริงที่เชื่อมโยงกับการทำเฟรมเวิร์ก, การสร้างคอมโพเนนต์, Web Components Community Group, กลุ่ม Accessibility Object Model และงานด้าน shadow DOM·custom elements·การเข้าถึง

ประสิทธิภาพ: ต้นทุนของ DOM เป็นเรื่องจริง แต่ไม่ใช่ทั้งหมด

  • จุดอ่อนพื้นฐานของเว็บคอมโพเนนต์คือการอิงกับ Custom Elements
    • เพราะอินเทอร์เฟซทั้งหมดต้องผ่าน DOM จึงเกิดโอเวอร์เฮดด้านประสิทธิภาพ
    • หากเป้าหมายคือเฟรมเวิร์กที่เร็วที่สุดแบบสัมบูรณ์ ก็ต้องลดจำนวนโหนด DOM ให้มากที่สุด และเมื่อใช้เกณฑ์นี้เว็บคอมโพเนนต์เสียเปรียบ
  • อย่างไรก็ตาม ประสิทธิภาพไม่ใช่เกณฑ์เดียวของการพัฒนาซอฟต์แวร์
    • ต้องพิจารณาความสามารถในการบำรุงรักษา, ความปลอดภัย, การใช้งาน และการเข้าถึงร่วมกันด้วย
    • หากไม่เรนเดอร์แอตทริบิวต์ aria-* การเรนเดอร์ DOM อาจเร็วขึ้นเล็กน้อย แต่สำหรับอินเทอร์เฟซที่เข้าถึงได้ สิ่งนี้อาจจำเป็น
    • micro-optimization เช่น for loop เร็วกว่า .forEach() หรือ var เร็วกว่า const/let มักไม่ค่อยคุ้มกับการยอมแลก
  • การลดจำนวนโหนด DOM ให้เหลือน้อยที่สุดคือแนวคิดหลักของ virtualization
    • บางครั้งแม้ไม่ใช่ตัวเลือกที่เร็วที่สุด วิธีที่เรียบง่ายกว่าก็เพียงพอแล้ว
    • components as elements ก็ไม่ใช่วิธีที่เหมาะที่สุดเช่นกัน แต่ไม่จำเป็นต้องตั้งเป้าว่าเหมาะที่สุดเสมอไป
  • วิธีใช้ custom elements ที่สร้างด้วยเฟรมเวิร์กต่างกันร่วมกันก็มีความหมายในงานจริง
    • อาจต้องย้ายจาก Framework A ไป Framework B แบบค่อยเป็นค่อยไป
    • บางกรณีต้องประกอบ micro frontend หลายตัวเข้าด้วยกัน
    • แม้ไม่ใช่อินเทอร์เฟซที่เร็วที่สุด แต่ก็อาจเป็น trade-off ที่จำเป็นได้
  • ในประสิทธิภาพเว็บจริง จุดที่ปรับปรุงได้ด้วยต้นทุนต่ำอย่าง layout thrashing, network waterfall และการ re-render ที่ไม่จำเป็น มักพบได้บ่อยกว่า
    • การแข่งขันอย่าง js-framework-benchmark น่าสนใจสำหรับผู้เขียนเฟรมเวิร์ก แต่ไม่ได้เป็นตัวตัดสินเสมอในสถานการณ์ผลิตภัณฑ์ทั่วไป
    • หากอยู่ในสภาพแวดล้อมที่ทรัพยากรจำกัดและทุกมิลลิวินาทีสำคัญ การเลือกทิ้งเว็บคอมโพเนนต์ก็สมเหตุสมผล

ต้นทุนในการรองรับของเฟรมเวิร์กและสิทธิ์ในการเลือก

  • ไม่เห็นด้วยกับข้อกล่าวอ้างว่าการรองรับเว็บคอมโพเนนต์เป็นต้นทุนที่สูงเกินไปสำหรับผู้เขียนเฟรมเวิร์ก
    • การตรวจจับ props และ attributes สามารถจัดการได้ด้วยการตรวจ prop in element
    • การ ส่งออก เว็บคอมโพเนนต์อาจเจ็บปวดได้ แต่ไม่ใช่งานที่ทุกเฟรมเวิร์กจำเป็นต้องทำ
    • Vue 2 ใช้ web component wrapper library แยกต่างหาก และ Remount ก็มีอยู่โดยไม่ต้องมีอินพุตจากทีม React
  • เฟรมเวิร์กสามารถสร้างให้ยอดเยี่ยมได้แม้จะมองข้ามฟีเจอร์ที่เพิ่มเข้ามาในเว็บแพลตฟอร์มตั้งแต่ปี 2011 เป็นต้นมา
    • jQuery v1 ยังคงทำงานอยู่ในเว็บไซต์จำนวนมาก
    • เมื่อทีมประสิทธิภาพของเบราว์เซอร์ปรับแต่งแพตเทิร์นของนักพัฒนาเว็บในอดีต โค้ดเก่าอาจเร็วขึ้นในเบราว์เซอร์ใหม่ได้ด้วย
  • การเลือกยอมรับฟีเจอร์เว็บแพลตฟอร์มสมัยใหม่มาพร้อมข้อพิจารณาใหม่ ๆ
    • ฟีเจอร์อย่าง Symbol, Proxy, Promises ก็อยู่ในหมวดเดียวกัน
    • ด้วย ความเข้ากันได้ย้อนหลัง ของเว็บ โค้ดที่เขียนไว้สามารถทำงานต่อไปได้แม้ผ่านไป 10 ปี
  • เฟรมเวิร์กที่ไม่สนใจเว็บคอมโพเนนต์หรือไม่ต้องการรองรับก็เป็นไปได้อย่างเต็มที่
    • สามารถสร้าง UI ทั้งหมดด้วยเว็บคอมโพเนนต์ได้
    • อาจผสม HTML web components เข้าไปเพียงบางส่วนก็ได้
    • หรือเลือกไม่ใช้เลยก็ได้
    • เฟรมเวิร์กแบบ “no web components” ก็สามารถมีแฟน ๆ ได้

มาตรฐานคือจุดอ้างอิง ไม่ใช่ข้อบังคับ

  • เมื่อฟีเจอร์ใดกลายเป็นมาตรฐาน นักพัฒนาจะตระหนักถึงมันในฐานะตัวเปรียบเทียบพื้นฐาน
    • ผู้เขียนคอมโพเนนต์ต้องตัดสินว่า <slot> ของตนควรทำงานเหมือน <slot> แบบ native หรือไม่
    • ต้องเลือกว่าจะใช้ IntersectionObserver หรือ <img loading="lazy"> หรือจะสร้าง abstraction ของตัวเอง
  • มาตรฐานให้จุดอ้างอิงร่วมและ ศัพท์ร่วม
    • ทำให้มีเกณฑ์สำหรับเปรียบเทียบและเทียบเคียงแนวทางต่าง ๆ
    • แต่ไม่ได้หมายความว่าต้องใช้เพียงเพราะเป็นมาตรฐาน
  • บนเว็บยังมีทั้งฟีเจอร์ที่ไม่จำเป็นต้องใช้และ API เก่าที่คงอยู่ร่วมกัน
    • API ที่ deprecated อย่าง document.domain, with, <frame> ก็ยังได้รับการรองรับ
    • ฟีเจอร์ของเว็บแพลตฟอร์มสามารถเลือกใช้หรือทิ้งได้

จุดที่เว็บคอมโพเนนต์เหมาะและไม่เหมาะ

  • เว็บคอมโพเนนต์ทำหลายอย่างได้ดี แต่ไม่ใช่เครื่องมือสำหรับแทนที่เฟรมเวิร์ก JavaScript ทั้งหมด
  • จุดอ่อนมีทั้ง server-side rendering (SSR), การเข้าถึง และการทำงานร่วมกันบางส่วน
  • ยังมีหลายสถานการณ์ที่เฟรมเวิร์กอย่าง React, Solid, Svelte โดดเด่นกว่า
  • คำพูดว่า “เว็บคอมโพเนนต์ไม่ใช่อนาคต” อาจถูกต้องสำหรับนักพัฒนาหรือโปรเจกต์บางแบบ
  • แก่นของข้อถกเถียงอยู่ที่ข้อเท็จจริงว่าผู้คนต่างกันกำลังสร้างสิ่งต่างกันภายใต้ข้อจำกัดที่ต่างกัน

กรณี Salesforce และการตัดสินใจเชิงปฏิบัติ

  • Salesforce แสดงให้เห็นสภาพแวดล้อมที่เว็บคอมโพเนนต์อาจเหมาะสม
  • หากไม่ได้อยู่ภายใต้เงื่อนไขเหล่านี้ อาจไม่จำเป็นต้องสร้าง UI ทั้งหมดด้วยเว็บคอมโพเนนต์, shadow DOM และชุดองค์ประกอบที่เกี่ยวข้องทั้งหมด
  • บนเว็บแพลตฟอร์ม มีทั้งเกม, โปรเจกต์ศิลปะ และแอป SaaS ระดับองค์กรที่สร้างด้วยฟีเจอร์หลากหลายอย่าง WebGL, Wasm, Service Workers อยู่ร่วมกัน
  • เมื่อมีการเพิ่มฟีเจอร์ใหม่ให้แพลตฟอร์ม ความคิดสร้างสรรค์ไม่ได้ถูกจำกัดลง แต่โอกาสในการแสดงออกด้วยวิธีที่ไม่เคยจินตนาการมาก่อนกลับเพิ่มขึ้น
  • บทความที่ควรอ่านประกอบยังมี บทความ ของ Lea Verou และ บทความ ของ Baldur Bjarnason

1 ความคิดเห็น

 
GN⁺ 2024-10-01
ความคิดเห็นจาก Hacker News
  • พยายามทำความเข้าใจบทความที่อ้างถึง “Web Components Are Not the Future” แล้ว แต่ก็ไม่ได้มีเหตุผลที่โน้มน้าวใจมากนัก
    สภาพของ เฟรมเวิร์กฟรอนต์เอนด์ ในตอนนี้ยุ่งเหยิง และไม่อยากเรียนรู้เวทมนตร์ที่เข้าใจไม่ได้ก่อนจะอ่านเฟรมเวิร์กหรือเอกสารที่ซับซ้อน (useState, createSignal ฯลฯ)
    ถ้าเริ่มจาก Web Components จะรู้สึกเป็นธรรมชาติ และยังได้ความสามารถที่ที่อื่นไม่มี เช่น การแยกโดดเดี่ยวด้วย Shadow DOM
    มองว่าสิ่งเดียวที่ควรเหลือไว้จากยุค React คือ JSX และได้ทำไลบรารีสำหรับใช้ Web Components ร่วมกับ JSX: https://webjsx.org

    • ประโยคที่ว่า “ไม่อยากเรียนรู้เฟรมเวิร์กที่ซับซ้อน” มีหลายความคิดปนกันอยู่ จึงตีความยาก
      ไม่ชัดว่าไม่อยากเรียนรู้ตัวเฟรมเวิร์กเอง หรือต้องการสิ่งที่รู้สึกเหมือนเวทมนตร์จนไม่จำเป็นต้องเรียนรู้ หรืออยากอ่านเอกสารหรือไม่
      ใช้ Vue เป็นหลักมานาน และแม้ อีโคซิสเต็มของ SPA จะซับซ้อน แต่ถ้าต้องจัดการแอปไคลเอนต์ที่มีสถานะซับซ้อน ก็ไม่ค่อยรู้ว่าระบบแบบอื่นจะเป็นไปได้อย่างไร
    • ยังมีความแตกต่างในวิธีคิดเกี่ยวกับ UI ด้วย
      แพตเทิร์นพื้นฐานของ jQuery คือการเลือกองค์ประกอบแล้วเปลี่ยนมัน ซึ่งเป็นแนวทางที่เน้น side effect ส่วน React หรือ Vue.js ช่วยให้สร้างคอมโพเนนต์ที่สถานะของ UI ถูกกำหนดด้วยข้อมูล
      เมื่อข้อมูลเปลี่ยน ก็อัปเดตด้วยการเปลี่ยน DOM ให้น้อยที่สุด และแนวทางนี้ทำให้วิดเจ็ต UI อ่านง่ายและดูแลรักษาง่ายขึ้นมากตามบริบทของตำแหน่งที่ใช้งาน
      เว็บไซต์และเว็บแอปเดสก์ท็อปในปัจจุบันซับซ้อนกว่าเมื่อ 20 ปีก่อนมาก ดังนั้นถ้าไม่ได้จะสร้างแค่ UI ง่าย ๆ นวัตกรรมด้านการจัดการสถานะจึงสำคัญ
    • ในการเขียนแอป React ไม่จำเป็นต้องรู้ว่า useState ทำงานภายในอย่างไร และวิธีใช้งานก็ค่อนข้างเป็นธรรมชาติ
      ในทางกลับกัน ไลบรารีที่เสนอขึ้นมาดูเหมือนต้องใช้ โมเดลความคิด ที่ซับซ้อนกว่าตั้งแต่เริ่ม
      แม้การเข้าใจรายละเอียดของเฟรมเวิร์กอย่างลึกซึ้งจะเป็นเรื่องที่ดี แต่ React ประสบความสำเร็จตรงที่ทำให้สร้างแอปที่ค่อนข้างซับซ้อนได้แม้แทบไม่รู้โมเดลภายในเลย
    • Angular ไม่ได้ยากขนาดนั้น และใช้เวลาประมาณหนึ่งสัปดาห์ก็เรียนรู้จนถึงระดับที่สร้างไซต์ซับซ้อนหรือส่ง PR ที่ใช้ได้ได้แล้ว
      อาจเป็นเพราะเป็นนักพัฒนาที่ทำมาตั้งแต่ยุคเบต้าของ C# และตั้งแต่ช่วงต้นของ HTML/JS/CSS ด้วย แต่ก็เข้าใจได้เร็ว
      ตอนเปลี่ยน พอร์ทัลจัดการโครงสร้างพื้นฐานหลัก ที่เก่าและซับซ้อน ก็เลือก Angular และมันเสถียร รวดเร็ว ดูดี ทุกคนพอใจ
      “เส้นโค้งการเรียนรู้ที่ชัน” ดูเหมือนจะมาจากนักพัฒนาที่เข้าวงการมาโดยรู้แค่ JavaScript กับ React นิดหน่อยเป็นหลัก และถ้ามีประสบการณ์มากกว่านี้ก็เรียนรู้ได้ทันที
    • ถ้าเป็นนักพัฒนาที่สงสัยว่าภายใน useState เป็นอย่างไร ก็สามารถไปถึงคำตอบที่สมเหตุสมผลและถูกต้องได้ภายในไม่กี่วินาที
      มันไม่ซับซ้อนหรือเป็นเวทมนตร์ และการทำ implementation ขั้นต่ำที่คล้าย React hooks ทำได้ในไม่กี่ร้อยบรรทัด
      การทำ useState และ runFunctionComponent แบบพื้นฐานนั้นง่ายกว่างานส่วนใหญ่ในเทอม 3 ของวิทยาการคอมพิวเตอร์ระดับมหาวิทยาลัย
      ถ้านี่คือเกณฑ์ของคำว่าเวทมนตร์ รอบตัวก็คงเต็มไปด้วย Warlock เลเวล 20 ที่สร้าง Eldritch Invocation ใหม่ได้แม้ระหว่างกินมื้อเช้า
  • เหตุผลหนึ่งที่ข้อถกเถียงนี้สวนทางกันคือ แต่ละฝ่ายกำลัง optimize คนละสิ่ง
    ถ้ากำลังสร้างผลิตภัณฑ์หลักในสตาร์ทอัพที่ได้รับเงิน VC ซึ่งต้องเคลื่อนที่เร็วและดูแลรักษาต่อเนื่อง เฟรมเวิร์กอาจเหมาะ
    แต่ในห้องแล็บวิชาการ มักไม่มีงบมากพอสำหรับดูแลแอปที่สร้างไว้แล้ว และมันต้องทำงานต่อไปได้แม้ทุนสนับสนุนจะย้ายไปโครงการใหม่แล้ว
    งานเขียนแอป Vue ใหม่เป็น Web Components ใกล้เสร็จแล้ว โดยสถานะเดิมคือ dependency ผุพังจนไม่สามารถอัปเดตได้
    ก่อนหน้านี้เสียเวลาไปกับการแก้นรก dependency และก็คงต้องทำต่อไปเรื่อย ๆ แต่พอลอง Web Components แล้วรู้สึกดีทันทีจึงเปลี่ยนมาใช้
    dependency ลดจากประมาณ 15 ตัวเหลือประมาณ 1 ตัว (d3js) และไม่เสียใจเลย
    แอปเก่า https://bam.iobio.io/, แอปใหม่ https://bam2.iobio.io/

    • บางครั้งก็เข้าใจตรรกะนี้ได้ยาก
      ไม่มีใครบังคับให้ต้องอัปเดตเฟรมเวิร์กเป็นเวอร์ชันล่าสุดเสมอไป ดังนั้นก็น่าจะอยู่กับ Vue เวอร์ชันเดิมที่ใช้อยู่ได้
      ถ้าไม่มีเหตุผลพิเศษ ก็อาจใช้เวอร์ชันเดิมไปจนจบได้
      ไม่ได้หมายความว่าเดิมที use case นั้นไม่จำเป็นต้องใช้ Vue หรือการเอา dependency ออกเป็นการตัดสินใจที่แย่ แต่ถ้าชอบ Vue ก็ไม่เห็นแรงบังคับว่าต้องอยู่บนเวอร์ชันล่าสุด
    • ถ้าสามารถเอา dependency ออกจนเหลือแค่ d3js ได้ แล้วจะทำสิ่งเดียวกันโดยยังคง dependency ของ Vue ไว้ไม่ได้หรือ
      สงสัยว่าเหตุผลที่ Vue ต้องการ dependency เพิ่มเติมนั้นอยู่ฝั่งระบบ build หรือเปล่า
    • ถ้าคุ้นเคยแล้ว คิดว่า การพัฒนา Web Components จะไม่ช้ากว่าเฟรมเวิร์กใด ๆ
      ดังนั้นจึงไม่ค่อยเข้าใจว่าทำไมอีโคซิสเต็ม VC ถึงอยู่ไม่ได้ถ้าไม่มีเฟรมเวิร์ก
    • เชื่อได้ยากว่ากำลังเขียน Web Components ทั้งหมดด้วยมือ และก็ดูยากที่จะบอกว่าไม่มี dependency ภายนอกเลย
  • ชอบที่ Svelte รองรับการสร้าง Web Components ผ่าน Custom Elements API
    เพราะ Svelte คอมไพล์เป็น JS/HTML/CSS ปกติ จึงเป็นธรรมชาติที่จะสร้างคอมโพเนนต์ที่ใช้ซ้ำได้และทำงานได้ทั้งกับเฟรมเวิร์กใด ๆ หรือ vanilla JS: https://svelte.dev/docs/custom-elements-api

    • Rich ก็ยอมรับว่านี่ไม่ใช่เป้าหมายลำดับแรกของ Svelte ดังนั้นจึงไม่น่าแปลกใจถ้าของจริงจะไม่ถึงระดับที่สัญญาไว้
    • Vue ก็มีฟีเจอร์นี้เช่นกัน: https://vuejs.org/guide/extras/web-components
  • ผมติดตามการถกเถียงเรื่อง Web Components มาหลายปีแล้ว แต่ในฐานะนักพัฒนา full-stack ยังไม่ค่อยเข้าใจว่ามันจะช่วยให้ชีวิตดีขึ้นได้อย่างไร
    ตัวอย่างส่วนใหญ่ที่เห็นก็แค่เอาข้อมูลไปใส่ใน HTML เป็นเทมเพลต ซึ่งทำได้อยู่แล้วด้วย handlebars
    ผมพลาดอะไรไปหรือเปล่า

    • “เว็บ” มีทั้งโมเดลที่มอง HTML เป็นเอกสาร และโมเดลที่มอง HTML เป็น scene graph ของแอปที่ซับซ้อนกว่า
      ถ้าใช้ HTML เป็นเอกสาร Web Components ก็ช่วยเพิ่มฟีเจอร์โต้ตอบแบบเรียลไทม์ที่เจ๋งขึ้นได้
      ตัวอย่างเช่น เทอร์มินัลอีมูเลเตอร์ที่เชื่อมกับ WebSocket, date picker, องค์ประกอบฟอร์มแบบกำหนดเอง, แผนที่, ตารางข้อมูล, วิดเจ็ตแท็บ และคอมโพเนนต์แบบกำหนดเองที่ jquery-ui เคยมีให้
      ทำได้แม้ไม่มี Web Components แต่ถ้าทำเป็นคอมโพเนนต์แบบกำหนดเอง HTML จะสะอาดกว่าและยังคงดูเป็นเอกสารมากกว่า
      ถ้ามีไลบรารี Web Components ที่สอดคล้องกันก็คงดี และดูเหมือนว่า HTMX กับ server-sent events ก็ทำแชตเรียลไทม์ที่ค่อนข้างดีได้
    • ทำ การแยกส่วนแบบเนทีฟ ได้อย่างสมบูรณ์
      เบราว์เซอร์จะแยก HTML, CSS และ JS ทั้งหมดให้อยู่คนละส่วนโดยไม่ต้องใช้ลูกเล่นพิเศษ
      ข้อดีคือสร้าง Web Component แล้วนิยาม API ของ JS, HTML, CSS ให้ชัดเจนในระดับตัวแปร จากนั้นนำไปใส่ในสภาพแวดล้อมใดก็ได้โดยไม่พัง หรือไม่ต้องสร้างเขาวงกตของ CSS namespace ที่ซับซ้อนกับ dependency ของเฟรมเวิร์ก
    • ดีมากสำหรับ progressive enhancement
      เช่น สามารถเพิ่มฟีเจอร์อย่างการกรองหรือการจัดเรียงแบบลากแล้ววางด้วย Web Component ที่ครอบตารางไว้ และแม้ JS จะถูกปิดหรือโหลดล้มเหลว ผู้ใช้ก็ยังได้รับตารางและคอนเทนต์พื้นฐาน
      เมื่อก่อนสิ่งนี้ดีกว่าหน้าขาวของเฟรมเวิร์กฝั่งฟรอนต์เอนด์มาก แต่ตอนนี้ server-side rendering ทำได้แพร่หลายแล้ว ข้อดีจึงลดลง
      การ encapsulate สไตล์ก็ดี แต่ทุกวันนี้มี headless UI library และ scoped styles ของเฟรมเวิร์กแพร่หลาย จึงดูไม่จำเป็นเร่งด่วนเท่าเมื่อ 10 ปีก่อน
      อย่างไรก็ตาม ถ้าจะใช้ slot ก็ต้องเลือก Shadow DOM ทำให้น่ารำคาญตรงที่เวลาเขียนคอมโพเนนต์ใช้ซ้ำของตัวเอง จะไม่สามารถสไตลิงด้วยวิธีใส่ stylesheet ไฟล์เดียวไว้ในเพจได้
    • เหตุผลที่ตัวอย่างทั้งหลายหลีกเลี่ยง API แบบไดนามิก น่าจะเป็นเพราะส่วนนั้นหน้าตาแย่มากและมี state เยอะ
      ถ้าเดโมโชว์ การปรับ DOM ด้วยมือ 200 บรรทัด ก็คงพูดยากว่า Web Components คืออนาคต
    • Web Components ทำให้สามารถใช้ UI component ที่สร้างด้วยเฟรมเวิร์กอื่นในเฟรมเวิร์กของเราได้
      แค่นั้นเอง และสำหรับวัตถุประสงค์อื่นๆ ส่วนใหญ่ก็ค่อนข้างไม่ดีนัก
      นอกจากนี้ยังทำให้เผยแพร่ UI component ให้ทำงานได้กับทุกเฟรมเวิร์กโดยไม่ต้องสร้าง 7 เวอร์ชัน
  • ส่วนที่แย่ที่สุดของ Web Components และ Shadow DOM คือมันอาจทำให้ ส่วนขยายเบราว์เซอร์ ทำงานได้ไม่ถูกต้อง หรือทำงานไม่ได้เลย
    ผู้ผลิตเบราว์เซอร์เองก็ไม่ได้รีบร้อนจะแก้สถานการณ์นี้

    • ความสามารถในการปรับแต่ง ของ user agent คือ killer feature ของเว็บ
  • ผมคิดว่า “ความผิดพลาด” ใหญ่ที่สุดอย่างหนึ่งของ Web Components คือการที่ผู้คนผูกมันไว้กับ Shadow DOM ในหัว
    ในการพัฒนาแอป ถ้ายึด live DOM ไว้ Web Components จะกลายเป็นตัวเลือกที่เบาและง่ายมาก
    คุณยังใช้เครื่องมือ CSS ที่ต้องการอย่าง bootstrap, tailwind ต่อไปได้ พร้อมได้ functional encapsulation ที่ยอดเยี่ยมแทบไม่มีต้นทุน โดยเฉพาะถ้าใช้สิ่งอย่าง lit-html เป็น renderer
    ทีมต่างๆ โดยมากรู้สึกสดใหม่กับการทำงานด้วย Web Components แบบเนทีฟ และนักพัฒนาที่มาจากโลกของเฟรมเวิร์ก หลังปรับตัวราวหนึ่งสัปดาห์ก็มักไม่อยากกลับไปอีก
    แค่ใช้ property ของคลาสแบบง่ายๆ และเรียก render function เองจาก set() ก็ได้ประโยชน์ของ reactivity โดยไม่ต้องแบกความยุ่งยากของเฟรมเวิร์ก
    ปัญหาคือมีแหล่งข้อมูลไม่มากที่สอนวิธีเริ่มด้วย “โหมดง่าย”
    เอกสารเริ่มต้นส่วนใหญ่ผลักเข้าไปสู่เทคนิคที่เจ็บปวดอย่าง Shadow DOM, CSS parts ซึ่งเหมาะกับคนเขียนไลบรารีมากกว่านักพัฒนาแอป
    น่าจะต้องเขียนไกด์แบบ “The Good Parts” ที่บอกว่าจะทำให้ชีวิตง่ายขึ้นด้วย Web Components ได้อย่างไร

    • ผมใช้ Shadow DOM ทุกวัน แต่ส่วนที่ทำให้ผู้คนสับสนที่สุดใน Web Components ก็มักเป็นส่วนนี้เอง อาจเพราะจริงๆ แล้วไม่จำเป็น
      ทางเลือกหนึ่งคือ “HTML web components” ที่ใช้แต่ live DOM, ให้ความสำคัญกับ server-side rendering ก่อน และเหมาะกับการแทนที่ “การปรุงรสแบบ jQuery”: https://adactio.com/journal/20618
      อีกอย่างคือ “Shadow gristle” ที่ใช้ Shadow DOM ให้น้อยที่สุดเท่าที่ทำได้ และถ้าต้องการสไตลิงหรือการประกอบส่วน ก็ปล่อยไว้ใน live DOM: https://glazkov.com/2023/03/02/shadow-gristle/
    • ถ้าคุณเขียนเรื่องนี้ ผมอยากอ่านนะ ฟังก็ได้เหมือนกัน
      เทคโนโลยีนี้ดูเหมือนจะเป็นได้ทั้งพรและคำสาป ขึ้นอยู่กับวิธีใช้ ผมเลยกำลังรวบรวมแหล่งข้อมูลและคอมเมนต์ที่เกี่ยวข้องอยู่
    • ที่ทำงานก่อนหน้านี้ใช้สแต็กเดียวกัน คือ WC ที่ไม่มี Shadow DOM กับ lit-html เท่านั้น และมันดีมาก
      สิ่งที่ดีที่สุดคือไม่ต้องตกลงไปใน dependency hell ทุกสองสัปดาห์
    • ใช่เลย ตรงนั้นแหละ สิ่งที่ตอนนี้ขาดไปคือ slot สำหรับ light DOM
  • ความสามารถในการทำงานร่วมกันเป็นข้อดีที่ใหญ่ที่สุดจากมุมมองของผู้ใช้ แต่ดูเหมือนจะประเมินต่ำไปว่าต้องแลกมาด้วย ต้นทุนด้านประสิทธิภาพ เพราะแต่ละคอมโพเนนต์ที่ใช้ อาจพ่วง runtime ที่ไม่จำเป็นติดมาด้วย
    แนวทางที่แนะนำคือใช้เฟรมเวิร์กอย่าง Lit ร่วมกับ Web Components และเมื่อเวลาผ่านไป มีเฟรมเวิร์กใหม่เกิดขึ้น และคอมโพเนนต์ถูกผูกไว้กับเวอร์ชันเก่า ต้นทุนนี้ก็จะสะสม
    ผมไม่อยากแนะนำให้ใครไปในทิศทางที่มีไลบรารีซ้ำหลายตัวในหน้าเดียว และถ้าสิ่งนั้นถูกนับเป็น best practice ก็ไม่ดีในระยะยาว
    ผมดูบทความ โซเชียลมีเดีย และวิดีโอของผู้สนับสนุน Web Components มาหลายปี และผมน่าจะเป็นผู้ใช้กลุ่มเป้าหมายเสียด้วยซ้ำ แต่บนภาษีของความสามารถในการทำงานร่วมกัน ยังเต็มไปด้วยข้อเสียที่ไม่มีในเฟรมเวิร์กกระแสหลัก
    ภายใน ecosystem ของแต่ละเฟรมเวิร์ก ความสามารถในการทำงานร่วมกันทำงานได้ดี และแรงผลักดันแบบเดียวกับที่ทำให้นักพัฒนามองหาความสามารถในการทำงานร่วมกัน ก็ทำให้พวกเขามารวมตัวกันรอบเฟรมเวิร์กกระแสหลักจำนวนน้อย
    ผมมองว่า Web Components ตามไม่ทันในเชิงเทคนิค และเพิ่มความซับซ้อนมากมายให้กับเว็บแพลตฟอร์มเพื่อดีไซน์จากช่วงต้นทศวรรษ 2010: https://x.com/Rich_Harris/status/1840116730716119356

    • เคยพูดถึงในบทความอื่นแล้ว แต่ถ้ามองภาพใหญ่ ไม่ใช่ทุกเว็บแอปที่จะอ่อนไหวต่อประสิทธิภาพในทุก kB ที่เพิ่มขึ้น อีคอมเมิร์ซเป็นแบบนั้น แต่เครื่องมือด้าน productivity โดยทั่วไปไม่ใช่
      มีเฟรมเวิร์กที่ runtime เล็ก อยู่มากมายอย่าง Svelte และไม่ได้หมายความว่าจะเอา 100 ตัวมาไว้ในหน้าเดียว แต่สัก 5–6 ตัวผมคิดว่ายังโอเค
      ไม่ได้หมายความว่าเป็นอุดมคติ แต่ช่วยได้สำหรับการ migrate แบบค่อยเป็นค่อยไปหรือ micro frontend
      อ้างอิงเพิ่มเติม React 17 ก็เพิ่มความสามารถให้มี React หลายเวอร์ชันในหน้าเดียวกันได้เช่นกัน: https://nolanlawson.com/2021/08/01/why-its-okay-for-web-components-to-use-frameworks/, https://bundlephobia.com/package/svelte@4.2.19, https://legacy.reactjs.org/blog/2020/10/20/react-v17.html
    • ถึงจะพูดถูกก็เถอะ แต่เมื่อดูเว็บแอปส่วนใหญ่ที่สร้างกันในปัจจุบัน ปัญหา หลายไลบรารี ดูแทบจะเป็นแค่ค่าคลาดเคลื่อนจากการปัดเศษ
      React กับ react-dom รวมกันก็เกิน 100KB แล้ว ส่วน Svelte กับ Lit อยู่ที่หลัก KB ตัวเดียว
      ถ้าจะให้เข้าใกล้ระดับความบวมที่ผู้คนใช้กันทุกวันโดยไม่คิดอะไร คงใส่เฟรมเวิร์กได้อีกหลายตัวทีเดียว
    • มองให้กว้างขึ้น Web Components ต้องโน้มน้าว ผู้เขียนเฟรมเวิร์ก ให้ได้
      สัญญาณที่เห็นมาอย่างต่อเนื่องจนถึงตอนนี้ไม่ดีนัก และคอมมูนิตี้นั้นอยู่บน X โดยที่ Web Components ไม่ได้แก้ปัญหาของพวกเขา และแม้ในสถานการณ์ที่ดีที่สุดก็ยังใช้งานได้ไม่ดี
      ผมหวังว่าจะโน้มน้าวสำเร็จ แต่โดยทั่วไปพวกเขามักบอกว่า Web Components ล้มเหลว และโดยรวมแล้วส่งผลเสียต่อเว็บ
    • พูดตรง ๆ ผมไม่ค่อยเข้าใจข้อโต้แย้งนี้
      runtime ส่วนใหญ่ค่อนข้างเล็ก และการมี runtime สองตัวทำงานพร้อมกันก็ไม่ได้ทำให้มี overhead ด้านประสิทธิภาพมากนัก
      เว็บเฟรมเวิร์กสมัยใหม่ทั้งหมดเป็นแบบ reactive ถ้าไม่มีอะไรต้องตอบสนอง ก็ไม่ทำอะไร
      ผมมองไม่ค่อยเห็นเหตุผลว่าถ้าส่วนหนึ่งของหน้าใช้ React อีกส่วนใช้ Lit และอีกส่วนใช้ Svelte แล้วประสบการณ์ผู้ใช้หรือการใช้แบตเตอรี่จะเลวร้ายลงอย่างเห็นได้ชัดเมื่อเทียบกับหน้าที่ใช้เฟรมเวิร์กเดียว
      ทวีตที่อ้างถึงพูดถึงว่า Web Components เป็น “องค์ประกอบพื้นฐานที่มีประโยชน์สำหรับสร้างเฟรมเวิร์ก” หรือไม่ และแม้แต่แฟน ๆ ที่เคยใช้งานจริงก็คงไม่ได้บอกว่าใช่กันเป็นส่วนใหญ่
      Web Components เป็น กลไกการจัดส่ง และถ้าทางเลือกมีแค่การสร้างไลบรารีเดียวกัน 7 ครั้งสำหรับ React, Preact, Svelte, Solid, Vue และ vanilla JS นั่นก็แย่มาก
  • ผมชอบ Web Components และมองในแง่ดีว่ามันมีโอกาสพาเราออกจากนรก frontend ในปัจจุบันที่เราสร้างขึ้นมาเอง
    เมื่อเร็ว ๆ นี้ผมเพิ่งพรีเซนต์สั้น ๆ เกี่ยวกับอนาคตของ frontend และดูเหมือนคนอื่น ๆ ก็หวังจะเห็นทางออกเช่นกัน
    ผมสร้าง data table สำหรับ DB GUI และแม้โหลดหลายแสนแถว การเลื่อนก็ยังลื่นมาก
    กำลังจะเปิดเผยไลบรารี Web Component ในเร็ว ๆ นี้ด้วย ตอนนี้ยังเร็วและยังหยาบอยู่ แต่ก็อยากให้คนมาดูมากขึ้น: www.astra-ui.com

    • ผมคิดว่าทางเดียวที่จะออกจากนรก frontend ปัจจุบันได้คือการมี client-side import: https://github.com/whatwg/html/issues/2791
    • ผมดูเอกสารแล้ว บน Safari 18.0 ของ iPhone 15 Pro Max การ render แปลกมาก
      น่าจะจัดวาง sidebar ใหม่โดยคำนึงถึง responsive design สำหรับหน้าจอเล็ก และตั้ง max-width ให้ body แทน width
      ปุ่ม “explore components” ด้านล่างของหน้าแรกดูเหมือนไม่ได้ลิงก์ไปที่ไหน
      บอกว่า “ให้เรียนรู้จากการ implement คอมโพเนนต์ที่มีโครงสร้างดีและเข้าถึงได้” แต่ผมหาลิงก์ไปยัง implementation ในเอกสารไม่เจอ
      บอกว่า “ไม่มี dependency ให้ต้องดูแลหรืออัปเดต” แต่ astra-ui เองก็เหมือนเป็น dependency ไม่ใช่หรือ และก็มี changelog ด้วย: https://www.astra-ui.com/changes/
      ยังบอกด้วยว่า “ควบคุมโค้ดและ styling ได้อย่างสมบูรณ์” แต่ผมไม่เข้าใจว่าจะควบคุมได้สมบูรณ์อย่างไร ในเมื่อยังพึ่งพา implementation ที่ไลบรารีจัดให้
      ผมสงสัยว่าทำไมถึงตัดสินใจเปิดเผยไลบรารีนี้ การ open source ซอฟต์แวร์ภายในมีประโยชน์เมื่อบริษัทมีเป้าหมายเฉพาะ แต่โดยปกติมักกลายเป็นการใช้เวลาโดยไม่ได้รับผลตอบแทน
      ไลบรารีคอมโพเนนต์ต้องต่อสู้เพื่อให้ ecosystem นำไปใช้ ไม่อย่างนั้นก็ไม่มีผู้ชม และมีเหตุผลน้อยที่จะเปิดเผย
    • ทำไมถึงควรใช้สิ่งนี้แทนอะไรอย่าง Vue component
    • ทำไม Web Components ถึงยังไม่ลงหลักปักฐาน หรือยังไม่ถูกใช้อย่างแพร่หลายกว่านี้
      ดูเหมือนเป็นทางออกที่ยอดเยี่ยม
    • เขียนโค้ดโฆษณา frontend ของบริษัทใหม่ด้วย Web Components
  • เมื่อไม่กี่เดือนก่อน ผมเข้าทำงานที่ใหม่และรับช่วงต่อ codebase JS ขนาดประมาณ 250,000 บรรทัด
    มีคลาสยักษ์ตัวเดียวกับ subclass อีกไม่กี่ตัวที่ทำทุกอย่าง และบางไฟล์ก็ยาวถึง 30,000 บรรทัด
    ไม่มี framework และไม่มี reactivity ดังนั้นเมื่อคลิกปุ่ม ก็ต้องใช้ event listener อัปเดตทุกอย่างบนหน้าจอด้วยมือ
    เป็นโค้ดที่เหมือนมีใครสักคนถือหนังสือ JavaScript ขั้นพื้นฐานแค่เล่มเดียว แล้วถูกขังอยู่ในห้องเดี่ยวของอารามหลายปีจนเขียนมันออกมา
    เพราะต้องค่อย ๆ ทำทีละนิด จึงเริ่ม refactor ด้วย Web Components ซึ่งช่วยได้มาก และจนถึงตอนนี้ลดไปได้ 50,000 บรรทัดแล้ว
    แต่จุดประสงค์จริง ๆ คือการเรียนรู้ให้ครบว่าโค้ดเดิมทำอะไรบ้างก่อนจะเขียนใหม่

    • กุญแจสำคัญในการทำความเข้าใจ codebase เก่าและเข้าใจยาก คือการ refactor ทีละส่วนเล็ก ๆ
      การทำใหม่ด้วย Web Components เป็นวิธีหนึ่งในการบรรลุเป้าหมายนั้น และข้อดีคือไม่ได้ทิ้งทั้งหมดแล้วเริ่มใหม่
      แต่ก็มีความเสี่ยงว่าเมื่อทำไปได้ระดับหนึ่งแล้วถูกย้ายไปโปรเจกต์อื่น คนถัดไปจะเข้ามาเริ่ม refactor ในสไตล์ของตัวเอง จนกลายเป็น codebase เข้าใจยากที่มีสามสไตล์
      ถึงอย่างนั้นก็ยังดีกว่าเขียนใหม่ทีเดียวทั้ง 250,000 บรรทัด
  • สิ่งหนึ่งที่ชอบใน Web Components คือ อย่างน้อยในเชิงทฤษฎี มันสามารถทำงานได้แม้อยู่ในสถานะ ปิดใช้งาน JS
    ผมเคยทำแบบนั้นอยู่สองสามครั้งเพื่อ progressive enhancement
    โดยรวมแล้วเห็นด้วยกับที่ Nolan พูด Web Components ยังมีขอบคมอยู่พอสมควร จึงยากที่จะครองโลกในสภาพปัจจุบัน แต่ก็ค่อนข้างดีสำหรับ use case บางแบบ
    แต่อย่างไรก็ดี ผมไม่ค่อยเข้าใจคำพูดที่ว่ามันไม่เข้ากับ server-side rendering เพราะผมทำมาได้โดยไม่มีปัญหา

    • อยากรู้ว่าทำไมถึงพูดแบบนั้น
      เท่าที่เห็น หากต้องการลงทะเบียน template กับ tag เฉพาะ ดูเหมือนต้องใช้ JavaScript: https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots
    • ผมไม่เข้าใจว่ามันควรทำงานอย่างไร
      ใน ReactJS เราสามารถ server render component หรือ template ได้ และผมมองว่า JSX เป็นภาษา template ที่ค่อนข้างดี
      ผมเข้าใจว่า Web Components ไม่มีภาษา template ดี ๆ ที่ built-in มาให้ จึงต้องนำเข้ามาเอง
      ผมไม่รู้จักกลไกมาตรฐานที่นำชิ้นส่วน JS component ที่เชื่อมกับ tag มา แล้ว render HTML ที่จำเป็นโดยไม่ต้องรัน JS
    • ผมเป็นผู้เขียนบทความเอง เรื่องนี้พูดไว้ในบทความอื่นแล้ว แต่โดยพื้นฐานคือ ข้อดีด้าน interoperability ที่ได้ฝั่ง client ยังไม่มีบน server
      ในอนาคต ถ้าบน server สามารถ render Web Component framework 3 ตัวที่ต่างกัน ให้ประกอบกันได้ และ hydration ได้อย่างสะอาด ก็น่าจะถือว่าแก้ปัญหาแล้ว: https://nolanlawson.com/2023/08/23/use-web-components-for-what-theyre-good-at/