1 คะแนน โดย GN⁺ 1 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในเดือนเมษายน Ladybird ได้ merge PR จำนวน 333 รายการจากผู้มีส่วนร่วม 35 คน และได้รับเงินสนับสนุนใหม่ 50,000 ดอลลาร์จาก Human Rights Foundation และ 1,000 ดอลลาร์จาก Jakub Stęplowski
  • มีการเพิ่ม ตัวดู PDF แบบอินไลน์, การเติมข้อความอัตโนมัติในแถบที่อยู่ตามประวัติการเข้าชม, ฟรอนต์เอนด์ Linux แบบ GTK4/libadwaita และ UI สำหรับจัดการ about:bookmarks ทำให้ความสามารถด้านการท่องเว็บและเดสก์ท็อป UI ขยายมากขึ้น
  • HTML parser สามารถ parse เนื้อหาการตอบกลับแบบค่อยเป็นค่อยไป และ speculative parser จะดึงทรัพยากรล่วงหน้า ขณะที่การคอมไพล์ระดับบนสุดของ JavaScript ถูกย้ายไปยัง background thread ช่วยลดเวลา main thread ลงได้ราว 200ms ตอนโหลด YouTube
  • JavaScript engine ปรับปรุงประสิทธิภาพของ Speedometer และการโหลดเว็บไซต์จริงด้วย for-in cache, ตัวจัดสรรรีจิสเตอร์แบบ O(1), การแชร์ identifier แบบ zero-copy, JS::Substring แบบ lazy และการปรับปรุง typed-array view cache
  • มีการเพิ่ม Cache/CacheStorage, image-set(), CSS anchor positioning, DNS แบบ asynchronous, GPU painting บน dmabuf, การใช้ mimalloc เป็นค่าเริ่มต้น และการบังคับใช้ Rust โดยคะแนน WPT เพิ่มจาก 2,003,537 เป็น 2,067,263

ขนาดการพัฒนาและผู้สนับสนุน

  • ในเดือนเมษายน Ladybird ได้ merge PR จำนวน 333 รายการจากผู้มีส่วนร่วม 35 คน โดยในจำนวนนี้มี 7 คนที่คอมมิตให้ Ladybird เป็นครั้งแรก
  • ผู้สนับสนุนรายใหม่ ได้แก่ Human Rights Foundation ที่สนับสนุน 50,000 ดอลลาร์ ผ่านโครงการ “AI for Individual Rights” และ Jakub Stęplowski ที่สนับสนุน 1,000 ดอลลาร์
  • Ladybird ดำเนินงานทั้งหมดด้วยเงินสนับสนุนจากบริษัทและบุคคลที่สนับสนุนเว็บแบบเปิด

ฟีเจอร์การท่องเว็บและฟรอนต์เอนด์

  • ตัวดู PDF แบบอินไลน์

    • PDF จะถูก เรนเดอร์แบบอินไลน์ ผ่านตัวดู pdf.js ที่ bundle มาให้(#9132)
    • pdf.js เป็นตัวดู PDF ที่เขียนด้วย JavaScript, HTML และ CSS ล้วน ๆ พร้อมความสามารถในการเปลี่ยนหน้า เลือกข้อความ ซูม และค้นหาภายในเอกสาร
    • ระหว่างการโหลด Intel ISA Manual ด้วย pdf.js พบจุดที่ควรปรับปรุงใน typed-array view cache และการ invalidation ของ :has()
  • ประวัติการเข้าชมและการเติมข้อความอัตโนมัติในแถบที่อยู่

    • เมื่อพิมพ์ในแถบที่อยู่ จะมีคำแนะนำที่อิงตามประวัติการเข้าชมแสดงขึ้นมาอย่างครบถ้วน รวมถึง favicon และชื่อของหน้าที่เคยเข้าชม ทางลัดไปยังเครื่องมือค้นหา และการเติม URL ทั่วไปให้สมบูรณ์(#8933)
    • HistoryStore ที่ใช้ SQLite จะเก็บชื่อ favicon จำนวนครั้งที่เข้าชม และเวลาที่เข้าชมล่าสุดของการนำทางทั้งหมด
    • หน้า settings ด้านความเป็นส่วนตัวได้เชื่อม “Clear browsing history” แล้ว และทั้ง UI ของ Qt และ AppKit ก็เรนเดอร์แถวแบบ rich ใหม่ได้
  • ฟรอนต์เอนด์ GTK4 / libadwaita

    • Ladybird ได้เพิ่มฟรอนต์เอนด์ Linux แบบใหม่ที่สร้างบน GTK4 และ libadwaita โดยมีให้ใช้ควบคู่กับฟรอนต์เอนด์ Qt เดิม(#8691)
    • ได้แรงบันดาลใจจาก GNOME Web(Epiphany) และใช้เมนูแฮมเบอร์เกอร์กับแท็บ AdwTabView โดยไม่มี menubar ตามแนวทางการออกแบบของ GNOME
    • รองรับการเติมข้อความอัตโนมัติในแถบ URL และไอคอนความปลอดภัย การค้นหาในหน้า โหมดเต็มหน้าจอ เมนูคอนเท็กซ์ กล่องโต้ตอบ alert/confirm/prompt/color/file คลิปบอร์ด หลายหน้าต่าง ธีมสว่าง/มืด และการสเกล DPR
    • เนื่องจากยังอยู่ในระยะเริ่มต้น จึงยังมีความสามารถไม่เทียบเท่าฟรอนต์เอนด์ Qt และ AppKit
  • บุ๊กมาร์ก

    • บุ๊กมาร์กที่เพิ่มเข้ามาเมื่อเดือนที่แล้ว ตอนนี้มี UI สำหรับจัดการเพิ่มเติมแล้ว
    • สามารถจัดการบุ๊กมาร์กและโฟลเดอร์ได้ในหน้า about:bookmarks(#8825)
    • หน้าใหม่รองรับการนำเข้าบุ๊กมาร์กและการส่งออก(#8938)
    • มีการเพิ่มเมนูคอนเท็กซ์สำหรับแก้ไขบุ๊กมาร์กและโฟลเดอร์(#8715)
    • มีการเพิ่ม timestamp date_added ให้กับบุ๊กมาร์กและโฟลเดอร์ทั้งหมด(#8867)
    • แถบบุ๊กมาร์กรองรับการเปิดแท็บใหม่ คัดลอก URL และการเปิดแท็บใหม่ด้วยการคลิกกลางหรือ Ctrl/Cmd+คลิก(#8758)
    • มีการเชื่อมต่อ HTML5 drag and drop API แล้ว โดย about:bookmarks ใช้สำหรับจัดเรียงใหม่ และยังทำงานบนหน้าเว็บทั่วไปด้วย(#8783)

การแยกวิเคราะห์ HTML, การรันสคริปต์, ไปป์ไลน์การเรนเดอร์

  • การแยกวิเคราะห์ HTML แบบคาดเดาและแบบค่อยเป็นค่อยไป

    • ตัวแยกวิเคราะห์ HTML ถูกเปลี่ยนให้ค่อย ๆ ใช้เนื้อหาของ response body แบบทีละส่วนได้(#9151)
    • ไบต์จะผ่านตัวถอดรหัสข้อความแบบสตรีมมิงก่อนเข้าสู่ tokenizer เป็นหน่วยชังก์ และเมื่ออินพุตไม่เพียงพอ tokenizer จะหยุดแล้วกลับมาทำงานต่อเมื่อมีข้อมูลเพิ่มเข้ามา
    • แทนที่โมเดลเดิมที่ต้องรอรับเนื้อหาทั้งหมดก่อนจึงเริ่มแยกวิเคราะห์
    • มีการทำ speculative HTML parser ด้วย(#9114)
    • เมื่อ parser หลักถูกบล็อกด้วยสคริปต์ภายนอกแบบ synchronous ตัว tokenizer แยกต่างหากจะสแกนอินพุตที่ยังไม่ได้แยกวิเคราะห์ล่วงหน้า และออก speculative fetch สำหรับรีซอร์ส <script src>, <link rel=stylesheet|preload>, <img src>
    • ติดตาม <base href> และข้ามภายใน template กับ foreign content ได้อย่างถูกต้อง
    • speculative parser ถูกเชื่อมเข้ากับ preload map ของเอกสาร ทำให้รีซอร์สที่พบจากการคาดเดาถูก deduplicate กับการดึงข้อมูลภายหลังของ parser ปกติ(#9164)
  • การคอมไพล์ JavaScript นอกเธรด

    • การสร้างไบต์โค้ดสำหรับโค้ดระดับบนสุดของสคริปต์ที่ดึงมา จะทำงานบน background thread pool(#9118)
    • worker thread จะสร้างไบต์โค้ดและข้อมูลที่จำเป็นต่อการสร้าง Executable โดยงานที่แตะต้อง VM หรือ GC heap จะยังคงอยู่บน main thread
    • รองรับ classic script, module และ IIFE ระดับบนสุด และเพียงแค่การโหลด YouTube ก็ย้ายเวลา main thread ราว 200ms ไปยัง background thread ได้แล้ว
  • การแรสเตอร์ไรซ์แยกตาม Navigable

    • แต่ละ Navigable จะถูกแรสเตอร์ไรซ์แยกจากกันบนเธรดของตัวเอง(#8793)
    • ก่อนหน้านี้ iframe จะถูกเพนต์แบบ synchronous เป็น nested display list ภายใน display list ของพาเรนต์ ทำให้มีเพียง rendering thread ของ traversable ระดับบนสุดเท่านั้นที่ทำงาน
    • ตอนนี้ display list ของพาเรนต์จะอ้างอิงผลลัพธ์ที่แรสเตอร์ไรซ์แล้วของแต่ละ iframe ผ่าน ExternalContentSource ดังนั้นการ invalidation ของ iframe จึงไม่ต้องให้พาเรนต์เขียนใหม่อีก
    • นอกจากเพิ่มความขนานแล้ว ยังเป็นงานเตรียมการสำหรับการย้าย iframe ไปยัง sandbox process แยกต่างหากด้วย
  • การเพนต์ GPU บน Linux ที่ใช้ dmabuf

    • ในบิลด์ Vulkan บน Linux นั้น WebContent เคยเพนต์ลงบน Skia surface ที่รองรับด้วย GPU แต่บัฟเฟอร์ที่แชร์กับ UI process เป็น CPU bitmap จึงเกิด GPU-to-CPU readback ทุกครั้งที่ flush
    • ตอนนี้ SharedImage สามารถบรรจุ Linux dmabuf handle ได้แล้ว ทำให้ front/back buffer คงอยู่บน GPU ไปจนถึง UI process(#8917, #8920)

ประสิทธิภาพและความเข้ากันได้ของเอนจิน JavaScript

  • การปรับแต่งประสิทธิภาพการเรียกแบบ JS-to-JS

    • มีการรวม PR หลายรายการเพื่อให้คำสั่ง Call, Return, End ยังคงอยู่ภายใน AsmInt assembly interpreter ในกรณีทั่วไป(#8891, #8909, #8912)
    • การบันทึก/กู้คืนรีจิสเตอร์ใช้ ARM64 paired load/store (ldp/stp) ที่ปรับแต่งด้วยมือ
    • การเรียก native function ก็ถูก dispatch จาก AsmInt โดยตรงผ่าน variant RawNativeFunction แบบใหม่ที่เก็บ ordinary function pointer แทน AK::Function(#8922)
  • ตัวจัดสรรรีจิสเตอร์ของไบต์โค้ดแบบ O(1)

    • เดิม Generator::allocate_register จะสแกนพูลที่ใช้งานได้เพื่อหารีจิสเตอร์หมายเลขต่ำสุด และระหว่างการโหลด x.com ฟังก์ชันนี้เพียงอย่างเดียวใช้เวลาไปราว 800ms
    • หลังสิ้นสุดช่วงที่ต้องรักษาความเทียบเท่ากับไปป์ไลน์ C++/Rust ตัวจัดสรรจึงถูกเปลี่ยนเป็นสแตก LIFO แบบเรียบง่าย(#9007)
  • การวนลูป for-in แบบแคช

    • ตำแหน่ง for (key in obj) จะเก็บแคช snapshot ของ enumerable key ที่ถูก flatten แล้ว และนำกลับมาใช้ใหม่ตราบเท่าที่ shape, indexed storage และ prototype chain ของ receiver ยังไม่เปลี่ยน(#8856)
    • Speedometer 2 เพิ่มจาก 67.7 → 73.6 และ Speedometer 3 เพิ่มจาก 4.11 → 4.22
  • การปรับปรุงเอนจินอื่น ๆ

    • parser แชร์ชื่อ identifier แบบ zero-copy ตลอดทั้ง lexer, parser และ scope collector ทำให้การ parse เร็วขึ้น 1.14 เท่า บน JS corpus ของเว็บไซต์ และลด RSS ลง 282MB(#8801)
    • การต่อสตริงสั้นจะข้ามการใช้ rope representation เมื่อผลลัพธ์สุดท้ายจะถูกสังเกตเป็น flat string อยู่แล้ว ทำให้เร็วขึ้น 2.13 เท่า ในลูป a + b ที่หนาแน่น(#9184)
    • lexical-this arrow function จะไม่จัดสรร function environment ในทุกครั้งที่เรียก ส่งผลให้ไมโครบेंช์มาร์กดีขึ้น 2.13 เท่า(#9192)
    • sparse array จะไม่จ่ายต้นทุนทันทีสำหรับ hole และ Array(20_000_000) จะคงอยู่เป็นเมทาดาทาเป็นส่วนใหญ่ แทนที่จะทำงานตามสัดส่วนกับ virtual element จำนวน 20 ล้านตัว(#8847)
    • ชนิด JS::Substring แบบ lazy ใหม่รองรับ regexp capture และ string builtin อย่าง slice, split, indexed access และทำให้ Octane regexp benchmark ดีขึ้น 1.066 เท่า(#8863)
    • source position ใน source map ของไบต์โค้ดถูกเก็บรักษาไว้ครบตลอดเส้นทาง ช่วยประหยัดเวลาบน x.com ได้ราว 250ms(#9027)
    • TransferArrayBuffer แบบ zero-copy ช่วยประหยัดเวลาการโหลด YouTube ได้ราว 130ms(#9088)
    • cached typed-array view ถูกเปลี่ยนจาก WeakHashSet เป็น intrusive list ช่วยประหยัดเวลาราว 250ms เมื่อตอนโหลด Intel ISA PDF ใน pdf.js(#9180)
    • จากเดิม Promise ทุกตัวจะจัดสรร PromiseResolvingFunction cell 2 ตัวที่มี AK::Function closure แบบไม่ capture เปลี่ยนมาเป็น static function ที่ dispatch ผ่าน enum Kind ทำให้ไม่ต้องมีการจัดสรรแยกต่อ resolver อีกต่อไป(#9188)
    • ข้ามการทำ property-table marking สำหรับ non-dictionary shape ทำให้เวลา GC ระหว่างการโหลด maptiler.com ลดลง 1.3 วินาที(#9044)
    • เพิ่ม fast path ให้ Array.prototype.indexOf สำหรับ packed array(#9123)
    • Array.prototype.sort นำ UTF-16 ที่แคชไว้กลับมาใช้แทนการ transcoding ใหม่ทุกครั้งที่มีการเปรียบเทียบ(#9036)
    • เพิ่มการ import WASM, JSON, CSS modules(#6029)
    • ข้อเสนอ ShadowRealm ถูกถอดการรองรับออก เนื่องจากกระบวนการทำให้เป็นมาตรฐานหยุดชะงัก(#8753)

API แพลตฟอร์มเว็บและ CSS

  • Cache และ CacheStorage

    • Cache และ CacheStorage ถูกนำไปใช้งานแบบครบวงจร end-to-end แล้ว(#8745)
    • 9 เมธอด ได้แก่ open, has, delete, keys, match, matchAll, add, addAll, put ทำงานโดยอิงกับสตอเรจชั่วคราวแบบ in-memory
  • ฟีเจอร์ CSS และการแก้ไขการเรนเดอร์

    • เพิ่มการรองรับพื้นฐานสำหรับ image-set() ทั้งรูปแบบมาตรฐานและรูปแบบที่มี prefix -webkit- โดยจะเลือกตัวเลือกความละเอียดที่ตรงกับ device pixel ratio มากที่สุดในช่วง paint และข้าม MIME type ที่ไม่รองรับ(#9090)
    • ด้วยการรองรับ image-set() ทำให้ภาพส่วนหัวของ gocomics.com แสดงผลได้
    • เพิ่มการรองรับเบื้องต้นสำหรับ position-anchor และ CSS anchor positioning ทำให้ตำแหน่งของมือและปืนบน cssdoom.wtf ถูกแก้ไข(#8686)
    • การทำ color interpolation ถูกเขียนใหม่ให้ตรงตาม css-color-4 โดยทำ interpolation บน float แทน u8 และจัดการ missing/powerless component, out-of-gamut sRGB และ alpha multiplier อย่างสม่ำเสมอ(#8934)
    • legacy presentational HTML attribute อย่าง align, bgcolor จะไม่เขียนค่าลงใน cascaded properties โดยตรงอีกต่อไป แต่ผ่าน cascade แบบเดียวกับ author declaration ทั่วไป ทำให้การแทนที่ var() และ fallback เมื่อ invalid-at-computed-value-time ทำงานได้ถูกต้อง(#9176)
    • การเปลี่ยนแปลง cascade ของ presentational hint ช่วยแก้ crash บน html.spec.whatwg.org
    • <thead>, <tbody>, <tfoot>, <tr> สะท้อน align presentational attribute แล้ว ทำให้การจัดวางปุ่มบน bricklink.com ถูกแก้ไข(#9177)
    • การทำ interpolation ของ stroke-dasharray ทำให้เส้น dash ของ SVG แอนิเมชันได้อย่างลื่นไหล(#9133)
    • องค์ประกอบที่มี attribute autofocus จะได้รับ focus จริงเมื่อหน้าเว็บโหลด(#9016)
    • list marker ของข้อความ RTL ถูกวางไว้ด้านขวา ทำให้การเรนเดอร์รายการบน Arabic Wikipedia ถูกแก้ไข(#9099)
    • baseline ของ inline flex/grid container ถูกอิงจาก first line box ของ child แทนที่จะเป็น wrapped line สุดท้าย ทำให้การจัดแนวข้อความลิงก์และไอคอนบน nos.nl ถูกแก้ไข(#9183)

เครือข่ายและการทำให้สไตล์เป็นโมฆะ

  • เครือข่าย

    • getaddrinfo จะไม่บล็อก event loop อีกต่อไป
    • LibDNS รันการ lookup ใน thread pool และส่ง query A กับ AAAA แบบขนาน พร้อมรวม concurrent lookup สำหรับชื่อเดียวกันเข้าด้วยกัน(#9109)
    • มีการแก้ไขเส้นทาง preconnect ของ RequestServer ที่เคยข้าม resolver เพื่อให้ถูกส่งผ่านเส้นทาง DNS pool เดียวกัน หลังพบว่า threaded resolver ของ libcurl ทำให้เกิด pthread_join บน main thread(#9109)
    • เมื่อ WebContent ช้ากว่าเครือข่าย การระบาย queued response data ของ RequestServer มีความซับซ้อน O(n²) และเมื่อเปิดวิดีโอ YouTube ใช้เวลาใน memcpy ราว 30 วินาที และใน Vector::remove 3 วินาที
    • AllocatingMemoryStream ถูกเปลี่ยนเป็น singly-linked chunk list ทำให้การ consume กลายเป็น O(1)(#9028)
    • มีการประกาศรองรับ AVIF และ WebP ใน Accept header ของคำขอรูปภาพเพื่อให้สอดคล้องกับเอนจินอื่น ๆ โดย CDN บางรายใช้ header นี้เพื่อตัดสินใจว่าจะส่งฟอร์แมตใหม่หรือใช้ JPEG fallback(#9046)
  • การทำให้สไตล์เป็นโมฆะ

    • selector invalidation แบบเดิมเรียบง่ายภายใต้สมมติฐานว่า selector มองลงด้านล่างเท่านั้น แต่ :host และ :has() ทำให้การเปลี่ยนแปลงของ descendant สามารถเปลี่ยนผลของ :has() ใน ancestor ได้ จึงจำเป็นต้องมีการ walk ย้อนขึ้นด้านบน
    • ปรับให้เมื่อ stylesheet mutation เปลี่ยนเพียง scope เดียว จะไม่ต้อง rebuild style scope cache ทั้งหมด ส่งผลให้เวลา rebuild rule cache ของ Reddit ลดลงจาก 13.2 วินาที → 3.2 วินาที(#9138)
    • sibling structural invalidation จะไม่แพร่ไปยัง descendant ที่ไม่ได้สังเกตตำแหน่งอีกต่อไป ทำให้การ recompute ที่ไม่จำเป็นใน Reddit infinite scroll ลดลง 11%(#9155)
    • mutation invalidation ของ :has() จะข้าม anchor ที่ไม่ได้รับผลกระทบ และวัดได้ว่าลดลงอย่างมากบน azure.com(#9168)
    • ใน Intel ISA PDF จำนวนการเยี่ยม child-list ของ :has() ลดลงจาก 71k → 1.6k และประหยัดเวลาโหลด pdf.js ได้ราว 650ms(#9179)
    • ชุดทดสอบ structural-invalidation ใหม่เผยให้เห็นการตกหล่นของ invalidation หลายกรณี และได้มีการแก้ไขแล้ว(#9095)
    • ยังรวมการปรับปรุงเล็ก ๆ รอบ ๆ hover, stylesheet mutation scope, custom-property map และ computed-style diffing(#9077, #9049, #9079, #9080, #9141)

การจัดสรรหน่วยความจำและระบบบิลด์

  • mimalloc เป็นตัวจัดสรรหน่วยความจำค่าเริ่มต้น

    • โค้ด C++ และ Rust ใช้ allocator instance เดียวของ mimalloc v2 ร่วมกัน โดยไม่ต้องผ่าน system allocator แยกกัน(#8752)
    • เนื่องจากไม่ได้ override malloc() ทั้งระบบ ไลบรารี third-party จึงยังคงรักษา allocator contract ของตัวเองไว้ได้
    • benchmark ของ JS ดีขึ้นโดยรวม
  • การบังคับใช้ Rust และการจัดระเบียบระบบบิลด์

    • ตัวเลือกบิลด์ ENABLE_RUST ถูกถอดออก ทำให้ Rust กลายเป็นข้อบังคับ(#8742)
    • ระบบบิลด์ GN ถูกลบออกทั้งหมด ทำให้เหลือ CMake เป็นมาตรฐานเดียว(#8931)
  • การเปลี่ยนแปลงด้าน GC และหน่วยความจำ

    • คอมไพล์ด้วย -ftrivial-auto-var-init=zero เพื่อเขียนทับ pointer เก่าของ GC เป็น 0 เมื่อเข้าสู่ฟังก์ชัน และทำให้ conservative stack scanner เจอสิ่งเหล่านี้น้อยลง(#9171)
    • property UsedValues ที่แทบไม่ถูกใช้งานถูกย้ายไปไว้หลัง lazy pointer ทำให้ struct ลดขนาดจาก 424 ไบต์ → 176 ไบต์ และระหว่างโหลด sainsburys.co.uk เวลา LayoutState::populate_node_from() ลดลงจาก 139ms → 65ms(#9104)
    • fetch body chunk ที่เดิมผ่านเส้นทาง pull-promise และต้องจัดสรร GC object 7 ชิ้นต่อ chunk ถูกเปลี่ยนให้ส่งตรงเข้า byte stream controller(#9169)

การทำงานของเว็บไซต์ที่ดีขึ้น

  • Reddit

    • แกลเลอรีภาพแบบแครูเซลของ Reddit ใช้งานได้แล้ว และมีการแก้บั๊ก layout ที่ไม่เกี่ยวข้องกัน 2 จุด รอบ descendant ที่จัดวางแบบ absolutely positioned ของ split inline รวมถึง ::slotted() matching (#9148)
    • ด้วย TextDecoderStream ทำให้ SPA ไม่กลืนการคลิกลิงก์อีกต่อไป จึงเปิดคอมเมนต์ได้
    • infinite scroll ก็ได้รับผลจากงานด้าน structural invalidation ด้วย
  • YouTube

    • YouTube ได้รับผลจาก off-thread top-level JS compile, off-thread WOFF2 decompression, การลด @font-face fetch fanout, การแก้ memory churn ของ RequestServer และ zero-copy TransferArrayBuffer
    • off-thread WOFF2 decompression ยังช่วยประหยัดเวลาใน Gmail ได้ราว 170ms (#8976)
    • ในการโหลดครั้งแรก @font-face fetch fanout ลดลงจาก 177 → ราว 9 รายการ (#9032)
  • เว็บไซต์อื่น ๆ

    • gocomics.com แสดงภาพส่วนหัวได้แล้วด้วย image-set()
    • yandex.com/maps ทำให้การเรนเดอร์ vector-tile WebGL ใช้งานได้จากการแก้ WebGL รวมถึงส่วนขยาย WEBGL_debug_renderer_info (#9043)
    • strava.com ล็อกอินได้แล้ว เพราะ Navigator.getBattery โยน error type ตามที่สเปกกำหนด แทนที่จะเป็นข้อผิดพลาดเฉพาะของตัวเอง (#8770)
    • GitHub Insights โหลดเร็วขึ้นราว 100ms ด้วย selector cache ของ Element.matches() และ .closest() (#8987)
    • หน้าเปรียบเทียบโน้ตบุ๊กของ tweakers.net เร็วขึ้นราว 31% จาก indexed HTMLFormElement property name lookup (#9009)
    • neon.com ไม่แครชอีกต่อไป (#8812)
    • channel4.com แก้ปัญหาการจัดแนวแนวตั้งของ category text ได้ด้วยการแก้ flex auto-margin resolution (#9050)
    • Cloudflare Turnstile ยังผ่านไม่ได้ แต่ล้มเหลวได้เร็วขึ้นมากด้วย auth-scheme handling, การปรับแต่ง Array.prototype.shift() และการเสริมความแข็งแรงของ UA event handler สำหรับ <input> range และ number element (#9063)

WPT และการเปลี่ยนแปลงของแพลตฟอร์มอื่น ๆ

  • Web Platform Tests

    • คะแนน WPT เพิ่มจาก 2,003,537 → 2,067,263 ทำให้เดือนนี้เพิ่มขึ้น 63,726 subtest
    • อย่างไรก็ตาม WPT ได้นำ test262 ซึ่งเป็น ECMAScript conformance suite อย่างเป็นทางการมา upstream จึงมี JavaScript subtest เพิ่มอีก 53,207 รายการ
    • Ladybird รัน test262 แยกต่างหากมาหลายปีแล้ว และเนื่องจาก LibJS conformance อยู่ในระดับดี จึงผ่านได้ 52,045 รายการ หรือ 97.8% ของชุดนี้
    • จากการเพิ่มขึ้น 63.7k ครั้งนี้ ราว 52k มาจากการนำเข้า test262 และอีกราว 11.7k คือความคืบหน้าใหม่ของแพลตฟอร์มเบราว์เซอร์จริง ๆ
    • การนำเข้า test262 ทำให้ WPT วัด JavaScript conformance ร่วมกับส่วนอื่น ๆ ของแพลตฟอร์มได้
  • ข้อความ, เลย์เอาต์, โปรเซส, UI

    • selection และ hit testing ของข้อความที่มี ligature เปลี่ยนจากโครงสร้างที่สมมติว่าหนึ่ง glyph ต่อหนึ่ง code unit มาเป็นการวนผ่าน grapheme cluster และกระจาย glyph advance ไปยัง grapheme เหล่านั้น (#8829)
    • การตั้งค่า innerHTML ให้ shadow root จะไม่ทำให้ layout tree ของทั้ง document เป็นโมฆะอีกต่อไป และลดเวลา layout-and-paint ลง 21% บน pomax.github.io/bezierinfo (#9191)
    • ต่อให้ popup tab นำทางไปยัง site อื่น WebContent process ของ parent ก็จะไม่ถูกปิดอีกต่อไป (#8730)
    • ใน Qt UI สามารถวนแท็บที่เปิดอยู่ได้ด้วย Ctrl+Tab และ Ctrl+Shift+Tab (#8704)
    • สามารถเลื่อนหน้าจอด้วยการลากขณะกดปุ่มเมาส์กลางค้างไว้ หรือคลิกค้างไว้กับที่เพื่อเข้าสู่โหมด autoscroll ได้ (#8881, #8928)
    • เมื่อข้อความที่ป้อนในแถบที่อยู่ไม่สามารถ sanitize ให้เป็น URL หรือคำค้นหาได้ จะแสดง error page ที่เหมาะสมแทนการทิ้งอินพุตเงียบ ๆ (#9072)
    • มีการติดตั้งใช้งาน TextDecoderStream ซึ่งเป็น streaming counterpart ของ TextDecoder และเก็บ partial UTF-8 ที่ขอบเขตของ chunk ไว้ก่อน ทำให้แก้ไขคอมเมนต์บน Reddit ได้ (#9143)
    • ข้อความ BroadcastChannel แบบข้ามโปรเซสถูกส่งผ่าน IPC ระหว่าง WebContent และ WebWorker process ทำให้ listener ทำงานเหมือนเบราว์เซอร์อื่น ไม่ว่าจะอยู่ใน process ใดก็ตาม (#8865)

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

 
GN⁺ 1 시간 전
ความเห็นจาก Hacker News
  • ถ้าอยากใช้เบราว์เซอร์ที่ไม่มี JavaScript โปรโตไทป์เบราว์เซอร์ที่ Dioxus ทำอยู่ก็กำลังดีขึ้นมากเหมือนกัน
    Dioxus ซึ่งเป็น Rust GUI framework กำลังพัฒนาเป็นส่วนหนึ่งของ native renderer และมีทิศทางจะทำทางเลือกแทน Skia เองแบบ Flutter แต่บนเว็บทำงานตามมาตรฐาน HTML/CSS แทนที่จะใช้แต่ canvas แบบ Flutter web
    ไม่พึ่งพาโค้ดเบราว์เซอร์เดิมอย่าง Chromium, Gecko, WebKit และใกล้เคียงกับการทำใหม่แทบทั้งหมดตั้งแต่ต้นโดยใช้ Rust crates อย่าง stylo และ taffy ที่ Servo ใช้อยู่ด้วย: https://github.com/DioxusLabs/blitz (/apps/browser)
  • ส่วนที่ยากที่สุดของการพัฒนาเบราว์เซอร์คือ ความเข้ากันได้กับเว็บแบบที่มนุษย์สร้างอุปสรรคขึ้นมาเอง มาโดยตลอด
    หลายเว็บไซต์บังคับบล็อกการโหลดจากบางเบราว์เซอร์และยอมให้เฉพาะ Chromium เท่านั้น นี่คือความจริงที่ Ladybird ต้องเจอ และเป็นปัจจัยใหญ่ที่ขัดขวางการแข่งขันของเบราว์เซอร์ใหม่
    ส่วน DRM Widevine ก็เป็นสิ่งที่เบราว์เซอร์ใหม่ได้มายากมาก แม้แต่ Zen Browser ที่มีผู้ใช้ 10 ล้านคนก็ยังได้มาไม่สำเร็จ
    • น่าเสียดายที่คนรุ่นใหม่ไม่ได้เรียนรู้บทเรียนจาก IE และกลับกลายเป็นฝ่ายที่บ่นก่อนหากอีกฝ่ายไม่เดินตามกระแสของ Chrome OS Platform
    • ผมไม่แน่ใจว่าการบล็อกแบบนั้นเกิดขึ้นบ่อยแค่ไหน
      ตลอด 20 ปีที่ผ่านมา ผมใช้แต่ Firefox และไม่เคยเจอเว็บที่บังคับให้เปลี่ยนไปใช้ Chromium เพื่อความเข้ากันได้เลยสักครั้ง
    • ถ้าอุปสรรคเทียมแบบนี้ส่งผลต่อการทำงานร่วมกันมากขนาดนั้น ก็แปลว่าผ่านด่านยากไปแล้ว 99% และส่วนใหญ่ข้ามได้ด้วยการ ปลอม User-Agent string
      Widevine เป็นด่านจริงก็จริง แต่ในทางปฏิบัติก็แค่กันการเล่น 4K บนบางสตรีมมิงไซต์อย่าง Netflix, Disney เป็นต้น
      เมื่อดูจากที่ Zen มีผู้ใช้ถึง 10 ล้านคนได้โดยไม่มี Widevine ก็คงยากจะบอกว่านี่เป็นปัจจัยชี้ขาดมากนัก
    • Ladybird เริ่ม รายงานตัวเองเป็น Chrome แล้วเมื่อไม่นานมานี้ก็เพราะเหตุผลนี้เอง
    • ถ้าเพื่อการทดสอบความเข้ากันได้ ก็สามารถเลียนแบบ User-Agent ได้
      ถ้าควบคุมตัวเบราว์เซอร์เองได้ ก็แทบไม่มีอะไรทำไม่ได้เลยนอกจากปัญหาที่เกี่ยวกับ DRM
  • ดูเหมือนจะใช้งานได้ดีขึ้นมากพอสมควรแล้ว
    โพสต์แบบนี้ทำให้นึกถึงความสนุกเวลาอ่านอัปเดตของเกมอีมูเลเตอร์
    ประมาณว่า “แก้บั๊ก X แล้วทำให้ Y ทำงานถูกต้อง ส่งผลให้เกม Z รันได้” ซึ่งครั้งนี้สิ่งที่แก้อย่างหนึ่งคือ CSS Doom เลยมีส่วนทับซ้อนกับฝั่งเกมอยู่เหมือนกัน
    • เป็นอุปมาเปรียบเทียบที่ตรงดี
      เคยได้ยิน Andreas พูดหลายครั้งว่าการทำเบราว์เซอร์ก็เหมือน การทำอีมูเลเตอร์
      แต่ละเว็บไซต์ใช้ฟีเจอร์ต่างกันไปคนละแบบ และเขาเปรียบเว็บไซต์เหมือน ROM
  • Ladybird กำลังคืบหน้าได้ดีจริงๆ
    ผมเป็นผู้ใช้ Firefox รุ่นเก่า แต่ถ้า Ladybird เข้าสู่ช่วงอัลฟาระยะแรกจริงๆ และเริ่มมี precompiled build ออกมา ผมตั้งใจจะลองใช้ตั้งแต่ช่วงแรกแน่นอน
    • ถ้าอยากลองรันดูตอนนี้ การ build ในเครื่องทำได้ง่าย และใช้แค่ไม่กี่คำสั่งเพื่อติดตั้ง dependency กับรัน build script: https://github.com/LadybirdBrowser/ladybird/blob/master/Docu...
    • อย่างน้อย Mozilla ก็น่าจะต้องการแรงกระตุ้นหนักๆ
    • คอมไพล์เองก็ค่อนข้างง่าย โดยเฉพาะถ้าขอให้ Claude Code ช่วยทำให้
  • เห็นคำว่า GTK4 / libadwaita frontend แล้วชอบเลย
    ผมชอบ GTK UI/UX มากกว่า Qt ก็เลยตั้งตารอความคืบหน้าฝั่งนี้
  • strava.com : Login works now that Navigator.getBattery throws the spec-mandated error type instead of one of our own (#8770).
    ทำไม Strava ถึงอยากรู้ระดับแบตเตอรี่ของผม?
    • น่าจะเป็นไปได้มากที่สุดว่าใช้เพื่อสร้าง ลายนิ้วมือเฉพาะตัว สำหรับการติดตาม
    • อาจเป็นไปได้ว่าใช้ Battery API เป็น heuristic เพื่อเลือกเวอร์ชันเว็บไซต์ที่ประหยัดพลังงานกว่า
      อาจมีเวอร์ชันเว็บเฉพาะสำหรับประเทศกำลังพัฒนา หรือถ้าแบตเหลือน้อยก็อาจลดความถี่ในการดึงตำแหน่งเพื่อประหยัดพลังงาน
      ทั้งหมดนี้เป็นแค่การคาดเดา แต่การที่ไซต์อย่าง Strava ขอข้อมูลแบตเตอรี่ก็ไม่ได้ไร้เหตุผลไปเสียทีเดียว เพียงแต่โดยรวมก็ดูน่าสงสัยนิดหน่อย
    • Strava เป็นบริการติดตามเส้นทาง
      ถ้าสมมุติว่าใช้งานผ่านเว็บไซต์ได้ด้วย ก็มีแนวโน้มสูงว่าเขาอยากปรับ ความถี่ในการดึงตำแหน่ง เพื่อหาจุดสมดุลระหว่างความแม่นยำกับการใช้พลังงาน
    • บอตที่พยายามเดารหัสผ่านแบบ brute force อาจไม่ได้ implement API นั้นให้เหมือนอุปกรณ์จริง
  • โพสต์ก่อนหน้า: https://news.ycombinator.com/item?id=47985497
  • ผมชอบทิศทางที่ SerenityOS มุ่งไปมาก และหวังว่าจะรักษาความโฟกัสแบบนั้นไว้ในเบราว์เซอร์ Ladybird ด้วย
    • เท่าที่ผมรู้ ตอนนี้ Ladybird แยกจาก SerenityOS อย่างสมบูรณ์แล้ว(https://hackaday.com/2024/07/02/fork-ladybird-browser-and-se...) ทำให้ผู้มีส่วนร่วมกับ Ladybird สามารถโฟกัสกับตรงนี้ได้เต็มที่
  • ยินดีด้วย
    แต่ภาพหน้าจอของ list marker ในข้อความ RTL ดูเหมือนกันอยู่นะ
    ทั้งสองกรณี list marker อยู่ทางซ้ายเหมือนกัน
    • ในภาพ “after” นี้ https://ladybird.org/assets/img/newsletter-apr-2026-rtl-afte... จุดนำหน้าข้อความในพาเนลล่างซ้ายอยู่ทางขวาของข้อความ
      ขณะที่ในภาพ “before” https://ladybird.org/assets/img/newsletter-apr-2026-rtl-befo... จุดนำหน้าข้อความไม่เพียงอยู่ทางซ้ายของข้อความ แต่ยังเยื้องไปทางซ้ายมากจนแทบจะหลุดออกนอกพาเนล
  • https://ladybird.org/assets/img/newsletter-apr-2026-reddit-g...
    ผมนับถือคนที่ใช้ Evangelion r/unixporn ในการทดสอบ Reddit บน Ladybird จริงๆ
    ผมไม่ได้ดู Evangelion เยอะมาก แต่ดูสารคดีวิเคราะห์มานับไม่ถ้วน และชอบมากถึงขั้นเคยใช้เป็นภาพพื้นหลังอยู่พักหนึ่ง
    ประเด็นสำคัญคือ Reddit ใช้งานบน Ladybird ได้ ซึ่งน่าทึ่งมาก
    ไม่รู้ว่า YouTube ใช้ได้ไหม แต่ถ้าใช้งานได้ด้วยก็จะยิ่งรู้สึกว่า Ladybird ใกล้พร้อมใช้จริงมากขึ้น
    ขอขอบคุณ https://jakubsteplow.ski/ ที่สนับสนุน Ladybird ด้วย
    ผมอยากให้มีการประกาศยกย่องคนที่บริจาคให้โครงการโอเพนซอร์สแบบจริงจังในทางที่ดีกว่าโฆษณา Google และหวังว่า Jakub จะพบแต่สิ่งดีๆ รวมถึงอยากให้คนอื่นๆ บริจาคให้โครงการอย่าง Ladybird อย่างอิสระด้วย
    ขอบคุณ Human Rights Foundation ที่ https://hrf.org/program/ai-for-individual-rights/ เช่นกัน
    น่าทึ่งและสร้างแรงบันดาลใจมากที่คนคนหนึ่งพาเบราว์เซอร์ไปได้ไกลขนาดนี้ ทั้งที่ตลาดแทบเป็นสภาพผูกขาดโดยรายเดียวหรือไม่กี่ราย
    • ผมชอบ EVA แต่ขอแนะนำอย่างระมัดระวัง
      มันมีอยู่ใหญ่ๆ สองด้าน ด้านหนึ่งคือ ไซไฟเมคา/เอเลียน/สัตว์ประหลาด ที่มีสุนทรียะเท่มาก และอีกด้านคือดราม่าส่วนบุคคลที่โฟกัสเรื่องการเกลียดตัวเองกับความโดดเดี่ยว
      สำหรับคนส่วนใหญ่ ด้านแรกน่าจะดึงดูดกว่า แต่สิ่งที่ยังคงอยู่มาจนถึงทุกวันนี้คือด้านหลัง
      ถ้าจะดู ควรระวังลำดับการรับชมด้วย
      มีไทม์ไลน์ของซีรีส์ทีวีต้นฉบับต่อด้วยภาพยนตร์ “End of Evangelion” และแยกอีกสายเป็นชุดภาพยนตร์ “Rebuild of Eva” ที่เริ่มจากการรีบูตเต็มตัว ก่อนจะกลายเป็นรีบูต/รีเมก/ภาคต่อขั้นสุดท้ายของต้นฉบับไปอย่างน่าประหลาด
    • https://ladybird.org/#about
      สำหรับคำถามว่า “ทุกวันนี้มีคนทำงานด้านเบราว์เซอร์อยู่กี่คน?” ตอนนี้ Ladybird ระบุว่ามี วิศวกรประจำที่ได้รับค่าจ้าง 8 คน และยังมีชุมชนผู้มีส่วนร่วมอาสาสมัครขนาดใหญ่ด้วย
    • YouTube ใช้งานบน Ladybird ได้
      อย่างอื่นส่วนใหญ่ก็ใช้ได้เช่นกัน แต่ปัญหาใหญ่ที่สุดนอกจากเรื่องความเร็วคือ การตรวจว่าเป็นมนุษย์หรือไม่ หลายแบบยังทำงานบน Ladybird ได้ไม่ดี