ในโพสต์ก่อนหน้า ผมได้ให้ภาพรวมของเป้าหมายสถาปัตยกรรม RenderingNG และพร็อพเพอร์ตี้ที่สำคัญ โพสต์นี้จะอธิบายวิธีการตั้งค่าส่วนประกอบต่างๆ และวิธีที่ไปป์ไลน์การแสดงผลไหลผ่าน
ตั้งแต่ระดับสูงสุดไปจนถึง
- แสดงผลเนื้อหาเป็นพิกเซลบนหน้าจอ
- สร้างเอฟเฟกต์ภาพแบบเคลื่อนไหวในเนื้อหาจากสถานะหนึ่งไปยังอีกสถานะหนึ่ง
- เลื่อนเพื่อตอบสนองต่อการป้อนข้อมูล
- กำหนดเส้นทางอินพุตไปยังที่ที่เหมาะสมอย่างมีประสิทธิภาพเพื่อให้สคริปต์ของนักพัฒนาซอฟต์แวร์และระบบย่อยอื่นๆ ตอบสนองได้
เนื้อหาที่จะแสดงคือโครงสร้างของเฟรมสำหรับแต่ละแท็บเบราว์เซอร์ รวมถึง UI ของเบราว์เซอร์ และสตรีมของเหตุการณ์อินพุตดิบจากหน้าจอสัมผัส เมาส์ แป้นพิมพ์ และอุปกรณ์ฮาร์ดแวร์อื่นๆ
แต่ละเฟรมจะมีข้อมูลต่อไปนี้
- สถานะ DOM
- CSS
- แคนวาส
- แหล่งข้อมูลภายนอก เช่น รูปภาพ วิดีโอ แบบอักษร และ SVG
เฟรมคือเอกสาร HTML พร้อมด้วย URL หน้าเว็บที่โหลดในแท็บเบราว์เซอร์มีเฟรมระดับบนสุด เฟรมย่อยสำหรับ iframe แต่ละรายการที่รวมอยู่ในเอกสารระดับบนสุด และองค์ประกอบรองลงมาของ iframe ที่เกิดซ้ำ
เอฟเฟกต์ภาพคือการดำเนินการด้านกราฟิกที่ใช้กับบิตแมป เช่น เลื่อน เปลี่ยนรูปแบบ คลิป ฟิลเตอร์ ความทึบแสง หรือการรวม
คอมโพเนนต์ของสถาปัตยกรรม
ใน RenderingNG งานเหล่านี้จะแบ่งออกเป็นขั้นตอนย่อยและคอมโพเนนต์ของโค้ดต่างๆ ตามหลักตรรกะ คอมโพเนนต์ต่างๆ จะไปอยู่ในกระบวนการของ CPU, เทรด และคอมโพเนนต์ย่อยต่างๆ ภายในเทรดเหล่านั้น แต่ละแบบมีบทบาทสำคัญในการบรรลุความเสถียร ประสิทธิภาพที่รองรับการปรับขนาด และการขยายสำหรับเนื้อหาเว็บทั้งหมด
การแสดงผลโครงสร้างไปป์ไลน์
การแสดงผลการดำเนินการในไปป์ไลน์ที่มีระยะต่างๆ และอาร์ติแฟกต์ที่สร้างขึ้นระหว่างการดำเนินการ ระยะแต่ละขั้นแสดงถึงโค้ดที่ทำงานที่กำหนดไว้อย่างชัดเจน 1 งานภายในการแสดงผล อาร์ติแฟกต์คือโครงสร้างข้อมูลที่เป็นอินพุตหรือเอาต์พุตของระยะต่างๆ โดยอินพุตหรือเอาต์พุตแผนภาพจะมีลูกศรกำกับไว้
บล็อกโพสต์นี้จะไม่ได้ลงรายละเอียดเกี่ยวกับอาร์ติแฟกต์นี้มากนัก ซึ่งเราจะพูดถึงในโพสต์ถัดไป โครงสร้างข้อมูลและบทบาทใน RenderingNG
ขั้นตอนของไปป์ไลน์
ในแผนภาพก่อนหน้า ขั้นต่างๆ จะไม่แสดงด้วยสีที่บ่งชี้ว่ามีการดำเนินการในเทรดหรือกระบวนการใด
- สีเขียว: เทรดหลักของกระบวนการแสดงผล
- สีเหลือง: ตัวประมวลผลการแสดงผล
- สีส้ม: กระบวนการ Viz
บางกรณีเรียกใช้ได้หลายตำแหน่ง ทั้งนี้ขึ้นอยู่กับสถานการณ์ ซึ่งทำให้บางสีมี 2 สี
ขั้นตอนมีดังนี้
- เคลื่อนไหว: เปลี่ยนรูปแบบที่คำนวณแล้วและเปลี่ยนแปลงแผนผังพร็อพเพอร์ตี้เมื่อเวลาผ่านไปตามลำดับเวลาการประกาศ
- รูปแบบ: ใช้ CSS กับ DOM และสร้างรูปแบบที่คำนวณ
- เลย์เอาต์: กำหนดขนาดและตำแหน่งขององค์ประกอบ DOM บนหน้าจอ แล้วสร้างแผนผังส่วนย่อยที่เปลี่ยนแปลงไม่ได้
- การลงสีล่วงหน้า: ประมวลผลต้นไม้พร็อพเพอร์ตี้และinvalidateรายการที่แสดงและชิ้นส่วนพื้นผิวของ GPU ที่มีอยู่ตามความเหมาะสม
- เลื่อน: อัปเดตออฟเซ็ตการเลื่อนของเอกสารและองค์ประกอบ DOM ที่เลื่อนได้ โดยการเปลี่ยนแปลงแผนผังพร็อพเพอร์ตี้
- สี: ประมวลผลรายการที่แสดงที่อธิบายวิธีแรสเตอร์ชิ้นส่วนพื้นผิว GPU จาก DOM
- คอมมิต: คัดลอกแผนผังพร็อพเพอร์ตี้และรายการที่แสดงไปยังเทรดคอมโพสิเตอร์
- กำหนดเลเยอร์: แบ่งรายการที่แสดงเป็นรายการเลเยอร์ที่ประกอบขึ้นสำหรับการแรสเตอร์และภาพเคลื่อนไหวอิสระ
- แรสเตอร์ ถอดรหัส และระบายสี: เปลี่ยนรายการการแสดงผล รูปภาพที่เข้ารหัส และโค้ด Worklet สีตามลําดับเป็นชิ้นส่วนพื้นผิว GPU
- เปิดใช้งาน: สร้างเฟรมตัวประมวลผลที่แสดงวิธีวาดและจัดตำแหน่งชิ้นส่วน GPU บนหน้าจอ รวมถึงเอฟเฟกต์ภาพต่างๆ
- การรวมข้อมูล: รวมเฟรมคอมโพสิเตอร์จากเฟรมคอมโพสิเตอร์ที่มองเห็นได้ทั้งหมดลงในเฟรมคอมโพสิเตอร์ส่วนกลางเดียว
- วาด: เรียกใช้เฟรมคอมโพสิเตอร์ที่รวบรวมไว้บน GPU เพื่อสร้างพิกเซลบนหน้าจอ
คุณสามารถข้ามขั้นตอนต่างๆ ของไปป์ไลน์การแสดงผลได้หากไม่จำเป็น เช่น ภาพเคลื่อนไหวของเอฟเฟกต์ภาพและการเลื่อนอาจข้ามเลย์เอาต์ การลงสีล่วงหน้า และระบายสีได้ ซึ่งเป็นเหตุผลที่ภาพเคลื่อนไหวและการเลื่อนถูกระบุด้วยจุดสีเหลืองและสีเขียวในแผนภาพ หากข้ามเลย์เอาต์ ก่อนลงสี และสีได้สำหรับเอฟเฟกต์ภาพ องค์ประกอบทั้ง 2 นี้จะทำงานบนเทรดการจัดวางองค์ประกอบทั้ง 2 แบบและข้ามเทรดหลักได้
การแสดงภาพ UI ของเบราว์เซอร์ไม่ได้แสดงที่นี่โดยตรง แต่ก็ถือเป็นรูปแบบที่เรียบง่ายของไปป์ไลน์เดียวกันนี้ (และที่จริงแล้ว การใช้งานนี้ใช้โค้ดส่วนใหญ่) โดยทั่วไปวิดีโอ (ไม่ได้แสดงโดยตรง) จะแสดงผลผ่านโค้ดอิสระที่ถอดรหัสเฟรมเป็นชิ้นส่วนพื้นผิว GPU หลังจากนั้นจะเสียบเข้ากับเฟรมคอมโพสิเตอร์และขั้นตอนการวาด
กระบวนการและโครงสร้างเทรด
การประมวลผลของ CPU
การใช้กระบวนการของ CPU หลายอย่างจะทำให้ได้ประสิทธิภาพและการแยกความปลอดภัยระหว่างเว็บไซต์และจากสถานะเบราว์เซอร์ ทั้งยังแยกความเสถียรและความปลอดภัยออกจากฮาร์ดแวร์ GPU
- กระบวนการแสดงผลจะแสดงผล ทำให้เคลื่อนไหว เลื่อน และเส้นทางอินพุตสำหรับเว็บไซต์และแท็บเดียว ขั้นตอนการแสดงผลมีอยู่หลายขั้นตอน
- กระบวนการของเบราว์เซอร์จะแสดงผล เคลื่อนไหว และเส้นทางอินพุตสำหรับ UI ของเบราว์เซอร์ (ซึ่งรวมถึงแถบ URL, ชื่อแท็บ และไอคอน) และกำหนดเส้นทางอินพุตที่เหลือทั้งหมดไปยังกระบวนการแสดงผลที่เหมาะสม เบราว์เซอร์มีกระบวนการเพียง 1 กระบวนการเท่านั้น
- กระบวนการ Viz รวบรวมองค์ประกอบจากกระบวนการแสดงผลที่หลากหลาย รวมถึงกระบวนการของเบราว์เซอร์ โดยจะแรสเตอร์และวาดโดยใช้ GPU ขั้นตอนของ Viz มีอยู่เพียงขั้นตอนเดียว
ซึ่งเว็บไซต์ต่างๆ มักจะมาจากกระบวนการแสดงผลที่ต่างกัน (ในความเป็นจริง ใช้งานบนเดสก์ท็อปเสมอ หากทำได้บนอุปกรณ์เคลื่อนที่) ผมจะเขียนไว้ข้างล่างว่า "ทุกครั้ง" แต่ข้อควรระวังนี้มีผลในทุกกรณี)
แท็บเบราว์เซอร์หลายแท็บหรือหน้าต่างของเว็บไซต์เดียวกันมักจะอยู่ในกระบวนการแสดงผลที่ต่างกัน เว้นแต่แท็บเหล่านั้นจะมีความเกี่ยวข้องกัน (การเปิดอีกแท็บหนึ่ง) ภายใต้แรงกดดันในหน่วยความจำที่สูงใน Chromium เดสก์ท็อปอาจทำให้แท็บหลายแท็บจากเว็บไซต์เดียวกันเข้าสู่กระบวนการแสดงผลเดียวกันแม้จะไม่เกี่ยวข้องกัน
ภายในแท็บเบราว์เซอร์หนึ่งแท็บ เฟรมจากเว็บไซต์ต่างๆ จะอยู่ในกระบวนการแสดงผลที่ต่างกันเสมอ แต่เฟรมจากเว็บไซต์เดียวกันมักจะอยู่ในกระบวนการแสดงผลเดียวกัน จากมุมมองของการแสดงผล ข้อได้เปรียบที่สำคัญของกระบวนการแสดงผลหลายแบบคือ iframe และแท็บแบบข้ามเว็บไซต์จะมีการแยกประสิทธิภาพซึ่งกันและกัน นอกจากนี้ ต้นทางยังเลือกใช้การแยกได้มากขึ้น
Chromium ทั้งหมดมีกระบวนการ Viz เพียงกระบวนการเดียว เพราะปกติแล้วจะมี GPU และหน้าจอเพียงตัวเดียวให้วาด การแยก Viz ออกเป็นกระบวนการของตัวเองช่วยให้เกิดความเสถียรเมื่อเจอข้อบกพร่องในไดรเวอร์ GPU หรือฮาร์ดแวร์ และยังเหมาะสำหรับการแยกการรักษาความปลอดภัย ซึ่งสำคัญต่อ GPU API อย่าง Vulkan นอกจากนี้ยังเป็นสิ่งสำคัญสำหรับ ความปลอดภัยโดยทั่วไปด้วย
เนื่องจากเบราว์เซอร์สามารถมีแท็บและหน้าต่างได้หลายแท็บ และทุกแท็บมีพิกเซล UI ของเบราว์เซอร์ให้วาด คุณอาจสงสัยว่าทำไมจึงมีกระบวนการของเบราว์เซอร์เพียงกระบวนการเดียว เหตุผลคือมีแค่แท็บเดียวที่มีโฟกัสในแต่ละครั้ง ซึ่งจริงๆ แล้วแท็บเบราว์เซอร์ที่มองไม่เห็นนั้นมักจะปิดใช้งานและทำให้หน่วยความจำ GPU หายไปเกือบทั้งหมด อย่างไรก็ตาม มีการนำฟีเจอร์การแสดงผล UI ของเบราว์เซอร์ที่ซับซ้อนไปใช้งานมากขึ้นในกระบวนการแสดงผล (หรือที่เรียกว่า WebUI) การเปลี่ยนแปลงนี้ไม่ได้มีไว้เพื่อการแยกประสิทธิภาพเท่านั้น แต่เพื่อใช้ประโยชน์จากเครื่องมือแสดงผลเว็บของ Chromium ที่ใช้งานง่าย
ในอุปกรณ์ Android รุ่นเก่า ระบบจะแชร์กระบวนการแสดงผลและเบราว์เซอร์เมื่อใช้ใน WebView (แต่โดยทั่วไปจะไม่มีผลกับ Chromium บน Android เพียงแต่ WebView เท่านั้น) ใน WebView กระบวนการของเบราว์เซอร์จะแชร์กับแอปที่ฝังด้วย และ WebView มีกระบวนการแสดงผลเพียงกระบวนการเดียว
นอกจากนี้ บางครั้งอาจมีกระบวนการที่เป็นประโยชน์ในการถอดรหัสเนื้อหาวิดีโอที่ได้รับการคุ้มครอง กระบวนการนี้ไม่ได้แสดงไว้ข้างต้น
ชุดข้อความ
เทรดช่วยให้แยกประสิทธิภาพและการตอบสนองได้แม้ว่างานจะช้า ไปป์ไลน์พร้อมกัน และการบัฟเฟอร์หลายครั้ง
- เทรดหลักจะเรียกใช้สคริปต์ ลูปเหตุการณ์การแสดงผล วงจรเอกสาร การทดสอบ Hit การส่งเหตุการณ์ของสคริปต์ และการแยกวิเคราะห์ HTML, CSS และรูปแบบข้อมูลอื่นๆ
- ตัวช่วยเทรดหลักจะทำงานต่างๆ เช่น สร้างบิตแมปของรูปภาพและ Blob ที่ต้องใช้การเข้ารหัสหรือถอดรหัส
- Web Workers เรียกใช้สคริปต์ และเหตุการณ์การแสดงผลวนซ้ำสำหรับ OffscreenCanvas
- ชุดข้อความคอมโพสิตจะประมวลผลเหตุการณ์อินพุต ทำการเลื่อนและภาพเคลื่อนไหวของเนื้อหาเว็บ คำนวณการสร้างเลเยอร์ของเนื้อหาเว็บอย่างเหมาะสม และประสานงานการถอดรหัสรูปภาพ ระบายสี Worklet และงานแรสเตอร์
- ตัวช่วยเทรดคอมโพสิตจะประสานงานกับงานแรสเตอร์ของ Viz และดำเนินงานถอดรหัสรูปภาพ วาดภาพ Worklet และแรสเตอร์สำรอง
- เทรดสื่อ Demuxer หรือเอาต์พุตเสียงจะถอดรหัส ประมวลผล และซิงค์ข้อมูลสตรีมวิดีโอและเสียง (โปรดทราบว่าวิดีโอจะดำเนินการควบคู่ไปกับไปป์ไลน์การแสดงผลหลัก)
การแยกเทรดหลักและคอมโพสิเตอร์มีความสำคัญอย่างมากต่อการแยกประสิทธิภาพของภาพเคลื่อนไหวและการเลื่อนออกจากการทำงานของเทรดหลัก
จะมีเทรดหลักเพียง 1 เทรดต่อกระบวนการแสดงผล แม้ว่าหลายๆ แท็บหรือเฟรมจากเว็บไซต์เดียวกันอาจอยู่ในกระบวนการเดียวกัน อย่างไรก็ตามจะมีการแยกประสิทธิภาพออกจากงานที่ทำใน API ของเบราว์เซอร์หลายรายการ เช่น การสร้างบิตแมปและ Blob ของรูปภาพใน Canvas API จะทำงานในเทรดตัวช่วยเทรดหลัก
ในทำนองเดียวกัน มีเทรด Compositor เพียง 1 เทรดต่อกระบวนการแสดงผลเท่านั้น ปกติแล้วไม่ใช่ปัญหาที่จะมีเพียงรายการเดียว เนื่องจากการดำเนินการที่มีค่าใช้จ่ายสูงทั้งหมดในเทรด Compositor จะได้รับมอบสิทธิ์ให้กับเทรดของผู้ปฏิบัติงานคอมโพสิเตอร์หรือกระบวนการ Viz และสามารถดำเนินการควบคู่ไปกับการกำหนดเส้นทางอินพุต การเลื่อน หรือภาพเคลื่อนไหว ผู้ปฏิบัติงานเชิงประกอบจะเทรดงานที่มีการประสานงานต่างๆ ในกระบวนการ Viz แต่การเร่งความเร็ว GPU ในทุกที่อาจล้มเหลวด้วยเหตุผลที่อยู่เหนือการควบคุมของ Chromium เช่น ข้อบกพร่องของไดรเวอร์ ในสถานการณ์เช่นนี้ เทรดของผู้ปฏิบัติงานจะทำงานในโหมดสำรองบน CPU
จำนวนเทรดของผู้ปฏิบัติงานคอมโพสิเตอร์จะขึ้นอยู่กับความสามารถของอุปกรณ์ ตัวอย่างเช่น โดยทั่วไปเดสก์ท็อปจะใช้เทรดมากกว่า เนื่องจากมีแกน CPU มากกว่าและมีข้อจำกัดด้านแบตเตอรี่น้อยกว่าอุปกรณ์เคลื่อนที่ นี่คือตัวอย่างของการปรับขนาดและลดขนาด
โปรดทราบว่าสถาปัตยกรรมการแยกชุดข้อความของกระบวนการแสดงผลเป็นการประยุกต์ใช้รูปแบบการเพิ่มประสิทธิภาพที่แตกต่างกัน 3 รูปแบบดังนี้
- ชุดข้อความตัวช่วย: ส่งงานย่อยที่ทำงานเป็นเวลานานไปยังเทรดเพิ่มเติม เพื่อให้เทรดหลักตอบสนองต่อคำขออื่นๆ ที่เกิดขึ้นพร้อมกัน ตัวอย่างที่ดีของเทคนิคนี้คือตัวช่วยเทรดหลักและเทรดตัวช่วยคอมโพสิเตอร์
- การบัฟเฟอร์หลายรายการ: การแสดงเนื้อหาที่แสดงผลก่อนหน้านี้ขณะแสดงเนื้อหาใหม่ เพื่อซ่อนเวลาในการตอบสนองของการแสดงผล ชุดข้อความคอมโพสิเตอร์ใช้เทคนิคนี้
- การโหลดไปป์ไลน์พร้อมกัน: การเรียกใช้ไปป์ไลน์การแสดงผลในหลายตำแหน่งพร้อมกัน นี่เป็นวิธีที่การเลื่อนและภาพเคลื่อนไหวสามารถทำได้รวดเร็ว แม้ว่าจะมีการอัปเดตการแสดงผลเทรดหลักก็ตาม เนื่องจากการเลื่อนและภาพเคลื่อนไหวสามารถเรียกใช้พร้อมกันได้
กระบวนการของเบราว์เซอร์
- เธรดการแสดงผลและการประสานจะตอบสนองต่ออินพุตใน UI ของเบราว์เซอร์ กำหนดเส้นทางอินพุตอื่นๆ ไปยังกระบวนการแสดงผลที่ถูกต้อง วางเลย์เอาต์และระบายสี UI ของเบราว์เซอร์
- ตัวช่วยเหลือ Thread ในการแสดงผลและการประกอบรูปภาพจะเรียกใช้งานการถอดรหัสรูปภาพ รวมถึงแรสเตอร์หรือถอดรหัสสำรอง
เธรดการแสดงผลและการรวมการประมวลผลของกระบวนการของเบราว์เซอร์จะคล้ายกับโค้ดและฟังก์ชันของกระบวนการแสดงผล เว้นแต่ว่าเทรดหลักและเธรดคอมโพสิเตอร์จะถูกรวมเข้าด้วยกันเป็นหนึ่ง ในกรณีนี้ ไม่จำเป็นต้องใช้เทรดเดียวเนื่องจากไม่จำเป็นต้องแยกประสิทธิภาพออกจากงานเทรดหลักที่ใช้เวลานาน เนื่องจากไม่มีการออกแบบเลย
กระบวนการ Viz
- แรสเตอร์ GPU หลักจะแสดงรายการและเฟรมวิดีโอลงในชิ้นส่วนพื้นผิว GPU และวาดเฟรมคอมโพสิเตอร์ไปยังหน้าจอ
- เธรดองค์ประกอบดิสเพลย์จะรวมและเพิ่มประสิทธิภาพองค์ประกอบจากกระบวนการแสดงผลแต่ละกระบวนการ บวกกับกระบวนการของเบราว์เซอร์ ไว้ในเฟรมตัวประมวลผลภาพเดียวสำหรับการนำเสนอไปยังหน้าจอ
โดยทั่วไปแล้วการแรสเตอร์และการวาดจะเกิดขึ้นในเทรดเดียวกันเนื่องจากทั้งคู่อาศัยทรัพยากร GPU และการใช้ GPU แบบมัลติเทรดจึงทำได้ยาก (การเข้าถึง GPU แบบมัลติเทรดที่ง่ายขึ้นเป็นแรงจูงใจหนึ่งในการพัฒนามาตรฐาน Vulkan ใหม่) ใน Android WebView มีเทรดการแสดงผลระดับระบบปฏิบัติการแยกต่างหากสำหรับการวาด เนื่องจาก WebView ฝังอยู่ในแอปที่มาพร้อมเครื่อง แพลตฟอร์มอื่นๆ ก็น่าจะมีเทรดดังกล่าวในอนาคต
ตัวประมวลผลการแสดงผลอยู่ในเทรดอื่นเนื่องจากต้องมีการตอบสนองตลอดเวลา และไม่บล็อกแหล่งที่มาของความล่าช้าในเทรดหลักของ GPU สาเหตุหนึ่งที่ทำให้เทรดหลักของ GPU ล่าช้าคือการเรียกใช้โค้ดที่ไม่ใช่ Chromium เช่น ไดรเวอร์ GPU เฉพาะผู้ให้บริการ ซึ่งอาจทำได้ช้าในรูปแบบที่คาดเดาได้ยาก
โครงสร้างคอมโพเนนต์
ภายในเทรดหลักหรือเทรดตัวประกอบแต่ละชุดจะมีองค์ประกอบของซอฟต์แวร์เชิงตรรกะที่โต้ตอบกันอย่างมีโครงสร้าง
แสดงผลคอมโพเนนต์เทรดหลักของกระบวนการ
- ตัวแสดงผล Blink:
- ส่วนย่อยของแผนผังเฟรมในเครื่องแสดงถึงโครงสร้างของเฟรมในเครื่องและ DOM ภายในเฟรม
- คอมโพเนนต์ DOM และ Canvas API มีการใช้งาน API เหล่านี้ทั้งหมด
- ตัวเรียกใช้วงจรเอกสารจะเรียกใช้ไปป์ไลน์การแสดงผลจนถึงและรวมขั้นตอนคอมมิต
- คอมโพเนนต์การทดสอบและการส่ง Event Hit อินพุตจะทำการทดสอบ Hit เพื่อดูว่าเหตุการณ์ใดกำหนดเป้าหมายโดยเหตุการณ์ใดเหตุการณ์หนึ่ง และเรียกใช้อัลกอริทึมการส่งเหตุการณ์อินพุตและพฤติกรรมเริ่มต้น
- เครื่องจัดตารางเวลาและตัวเรียกใช้ Event Loop การแสดงผลจะตัดสินใจว่าจะเรียกใช้ใดในลูปเหตุการณ์และเมื่อใด โดยจะกำหนดเวลาให้แสดงผลตามความถี่ที่ตรงกับจอแสดงผลของอุปกรณ์
ส่วนย่อยของแผนผังเฟรมในเครื่องอาจดูซับซ้อนสักเล็กน้อย จำได้ว่าแผนผังเฟรมเป็นหน้าหลักและ iframe ย่อยๆ วนรอบ เฟรมจะอยู่ในเครื่องของกระบวนการแสดงผลหากแสดงผลในกระบวนการนั้น มิเช่นนั้นจะเป็นระยะไกล
คุณสามารถใส่สีเฟรมตามกระบวนการแสดงผลได้ ในรูปภาพก่อนหน้า วงกลมสีเขียวเป็นเฟรมทั้งหมดในกระบวนการแสดงผลครั้งเดียว ส่วนสีส้มอยู่ใน 1 วินาที ส่วนวงกลมสีฟ้าอยู่ใน 1 ใน 3
ส่วนย่อยของแผนผังเฟรมในเครื่องเป็นคอมโพเนนต์ที่เชื่อมต่อที่มีสีเดียวกันในแผนผังเฟรม รูปภาพมีเฟรมต้นไม้ในพื้นที่ 4 ต้นในภาพ ได้แก่ เว็บไซต์ A จำนวน 2 รายการสำหรับเว็บไซต์ ข และอีก 1 รายการสำหรับเว็บไซต์ ค แผนผังเฟรมในเครื่องแต่ละรายการจะมีคอมโพเนนต์โหมดแสดงภาพ Blink ของตนเอง ตัวแสดงผล Blink ของแผนผังเฟรมในเครื่องอาจอยู่ในกระบวนการแสดงผลเดียวกันกับเฟรมต้นไม้อื่นๆ ในเครื่องหรือไม่ก็ได้ (ซึ่งจะกำหนดโดยวิธีการเลือกกระบวนการแสดงผลตามที่อธิบายไว้ก่อนหน้านี้)
แสดงผลโครงสร้างเทรด Compositor ของกระบวนการ
องค์ประกอบ Compositor ของกระบวนการแสดงผลมีดังนี้
- ตัวแฮนเดิลข้อมูลที่คงรายการเลเยอร์แบบผสม รายการการแสดงผล และแผนผังพร็อพเพอร์ตี้
- โปรแกรมเรียกใช้วงจรที่เรียกใช้ภาพเคลื่อนไหว เลื่อน ผสม แรสเตอร์ รวมถึงถอดรหัสและเปิดใช้งานขั้นตอนของไปป์ไลน์การแสดงผล (โปรดทราบว่าภาพเคลื่อนไหวและการเลื่อนอาจเกิดขึ้นได้ทั้งในเทรดหลักและตัวจัดวางองค์ประกอบ)
- เครื่องจัดการการทดสอบอินพุตและ Hit จะประมวลผลอินพุตและทดสอบ Hit ที่ความละเอียดของเลเยอร์แบบผสม เพื่อพิจารณาว่าท่าทางสัมผัสการเลื่อนสามารถเรียกใช้บนเทรดคอมโพสิเตอร์ได้หรือไม่ และการทดสอบ Hit กระบวนการแสดงผลใดควรกำหนดเป้าหมาย
ตัวอย่างในทางปฏิบัติ
ตอนนี้เรามาทำให้สถาปัตยกรรมเป็นรูปธรรมด้วยตัวอย่างกัน ในตัวอย่างนี้มีแท็บ 3 แท็บ ได้แก่
แท็บ 1: foo.com
<html>
<iframe id=one src="foo.com/other-url"></iframe>
<iframe id=two src="bar.com"></iframe>
</html>
แท็บ 2: bar.com
<html>
…
</html>
แท็บ 3: baz.com
html
<html>
…
</html>
กระบวนการ ชุดข้อความ และโครงสร้างคอมโพเนนต์ของแท็บเหล่านี้จะมีลักษณะดังต่อไปนี้
ต่อไปเราจะขอดูตัวอย่าง 1 ตัวอย่าง จากงานหลัก 4 อย่างในการแสดงภาพ ซึ่งคุณจำได้มีดังนี้
- แสดงผลเนื้อหาเป็นพิกเซลบนหน้าจอ
- ทำให้เอฟเฟกต์ภาพเคลื่อนไหวในเนื้อหาจากสถานะหนึ่งไปยังอีกสถานะหนึ่ง
- เลื่อนเพื่อตอบสนองต่อการป้อนข้อมูล
- กำหนดเส้นทางอินพุตไปยังที่ที่เหมาะสมอย่างมีประสิทธิภาพเพื่อให้สคริปต์ของนักพัฒนาซอฟต์แวร์และระบบย่อยอื่นๆ ตอบสนองได้
วิธีแสดงผล DOM ที่เปลี่ยนแปลงสำหรับแท็บที่ 1
- สคริปต์ของนักพัฒนาซอฟต์แวร์จะเปลี่ยน DOM ในกระบวนการแสดงผลสำหรับ foo.com
- ตัวแสดงผล Blink จะบอกตัวจัดวางองค์ประกอบว่าจำเป็นต้องมีการแสดงภาพ
- ตัวจัดวางองค์ประกอบบอก Viz ว่าต้องแสดงผล
- Viz จะส่งสัญญาณชี้จุดเริ่มต้นของการแสดงภาพกลับไปที่ตัวจัดวางองค์ประกอบ
- คอมโพสิเตอร์จะส่งต่อสัญญาณเริ่มต้นไปยังตัวแสดงผล Blink
- ตัวเรียกใช้ลูปเหตุการณ์ของเทรดหลักจะทำงานวงจรเอกสาร
- เทรดหลักจะส่งผลลัพธ์ไปยังเทรด Compositor
- ตัวเรียกใช้ลูปเหตุการณ์ของคอมโพสิเตอร์จะเรียกใช้วงจรการประกอบภาพ
- ระบบจะส่งงานแรสเตอร์ไปยัง Viz เพื่อทำแรสเตอร์ (มักมีงานเหล่านี้มากกว่า 1 รายการ)
- Viz แรสเตอร์เนื้อหาใน GPU
- Viz รับทราบว่างานแรสเตอร์ทำงานเสร็จแล้ว หมายเหตุ: Chromium มักไม่รอให้แรสเตอร์ทำงานเสร็จและใช้สิ่งที่เรียกว่าโทเค็นการซิงค์แทน ซึ่งจะต้องแก้ไขด้วยงานแรสเตอร์ก่อนดำเนินการตามขั้นตอนที่ 15
- ระบบจะส่งเฟรมคอมโพสิเตอร์ไปยัง Viz
- Viz จะรวมเฟรมคอมโพสิเตอร์สำหรับกระบวนการแสดงผล foo.com, กระบวนการแสดงผล iframe bar.com และ UI ของเบราว์เซอร์
- Viz กำหนดเวลาเสมอ
- Viz จะวาดเฟรมคอมโพสิเตอร์ที่รวบรวมไว้ในหน้าจอ
วิธีทำให้การเปลี่ยนตามการเปลี่ยนรูปแบบของ CSS เคลื่อนไหวในแท็บที่ 2
- เทรด Compositor สำหรับกระบวนการแสดงผล bar.com จะทำเครื่องหมายภาพเคลื่อนไหวในลูปเหตุการณ์ Compositor โดยการเปลี่ยนแปลงพร็อพเพอร์ตี้ทรีที่มีอยู่ จากนั้นระบบจะเรียกใช้วงจรตัวจัดวางองค์ประกอบอีกครั้ง (อาจมีงานแรสเตอร์และถอดรหัส แต่จะไม่ปรากฏในที่นี้)
- ระบบจะส่งเฟรมคอมโพสิเตอร์ไปยัง Viz
- Viz จะรวมเฟรมตัวประมวลผลสำหรับกระบวนการแสดงผล foo.com, กระบวนการแสดงผล bar.com และ UI ของเบราว์เซอร์
- Viz กำหนดเวลาเสมอ
- Viz จะวาดเฟรมคอมโพสิเตอร์ที่รวบรวมไว้ในหน้าจอ
หากต้องการเลื่อนหน้าเว็บในแท็บที่ 3 ให้ทำดังนี้
- ลำดับของเหตุการณ์
input
(เมาส์ การแตะ หรือแป้นพิมพ์) มาถึงกระบวนการของเบราว์เซอร์ - แต่ละเหตุการณ์จะได้รับการกำหนดเส้นทางไปยังเธรดกระบวนการแสดงผลของ baz.com
- ตัวจัดวางองค์ประกอบจะกำหนดว่าเทรดหลักจำเป็นต้องทราบเกี่ยวกับเหตุการณ์หรือไม่
- ระบบจะส่งเหตุการณ์ไปยังเทรดหลัก หากจำเป็น
- เทรดหลักเริ่มการทำงานของ Listener เหตุการณ์
input
(pointerdown
,touchstar
,pointermove
,touchmove
หรือwheel
) เพื่อดูว่า Listener จะเรียกใช้preventDefault
ในเหตุการณ์หรือไม่ - เทรดหลักจะแสดงผลว่าระบบเรียกใช้
preventDefault
ไปยังตัวจัดวางองค์ประกอบหรือไม่ - ไม่เช่นนั้น ระบบจะส่งเหตุการณ์อินพุตกลับไปยังกระบวนการของเบราว์เซอร์
- กระบวนการของเบราว์เซอร์จะแปลงเบราว์เซอร์เป็นท่าทางสัมผัสการเลื่อนโดยรวมเข้ากับเหตุการณ์ล่าสุดอื่นๆ
- ระบบจะส่งท่าทางสัมผัสการเลื่อนไปยังเธรดกระบวนการแสดงผลของ baz.com อีกครั้ง
- และจะใช้การเลื่อนตรงนี้ และเทรด Compositor สำหรับกระบวนการแสดงผล bar.com จะทำเครื่องหมายภาพเคลื่อนไหวในลูปเหตุการณ์ของ Compositor
ซึ่งจะเปลี่ยนแปลงออฟเซ็ตการเลื่อนในแผนผังพร็อพเพอร์ตี้ และเรียกใช้วงจรตัวจัดวางองค์ประกอบอีกครั้ง
และยังบอกให้เทรดหลักเริ่มการทำงานของเหตุการณ์
scroll
ด้วย (ไม่ได้แสดงที่นี่) - ระบบจะส่งเฟรมคอมโพสิเตอร์ไปยัง Viz
- Viz จะรวบรวมเฟรมคอมโพสิเตอร์สำหรับกระบวนการแสดงผล foo.com, กระบวนการแสดงผล bar.com และ UI ของเบราว์เซอร์
- Viz กำหนดเวลาเสมอ
- Viz จะวาดเฟรมคอมโพสิเตอร์ที่รวบรวมไว้ในหน้าจอ
วิธีกำหนดเส้นทางเหตุการณ์ click
บนไฮเปอร์ลิงก์ใน iframe #two ในแท็บที่ 1 ให้ทำดังนี้
- เหตุการณ์
input
(เมาส์ การแตะ หรือแป้นพิมพ์) มาถึงกระบวนการของเบราว์เซอร์ โดยจะทำการทดสอบ Hit โดยประมาณเพื่อระบุว่ากระบวนการแสดงผล iframe bar.com ควรได้รับการคลิกและส่งที่นั่น - เทรด Compositor สำหรับ bar.com กำหนดเส้นทางเหตุการณ์
click
ไปยังเทรดหลักสำหรับ bar.com และกำหนดเวลางานวนซ้ำของเหตุการณ์การแสดงผลเพื่อประมวลผล - ตัวประมวลผลเหตุการณ์อินพุตสำหรับการทดสอบ Hit เทรดหลักของ bar.com เพื่อระบุองค์ประกอบ DOM ใน iframe ที่มีการคลิกและทำให้เหตุการณ์
click
เริ่มทำงานสำหรับสคริปต์เพื่อสังเกตการณ์ ไม่ได้ยินpreventDefault
ระบบจะนำทางไปยังไฮเปอร์ลิงก์ - เมื่อโหลดหน้าเว็บปลายทางของไฮเปอร์ลิงก์ สถานะใหม่จะแสดงผลโดยมีขั้นตอนคล้ายกับตัวอย่าง "การแสดงผล DOM ที่เปลี่ยนแปลง" ด้านบน (การเปลี่ยนแปลงในภายหลังเหล่านี้ไม่ปรากฏที่นี่)
บทสรุป
เยี่ยมเลย มีรายละเอียดเยอะมาก คุณจะเห็นได้ว่าการแสดงผลใน Chromium ค่อนข้างซับซ้อน การจำและทบทวนส่วนประกอบต่างๆ ทั้งหมดอาจใช้เวลานาน ดังนั้นอย่ากังวลถ้าทุกอย่างดูจะมากเกินไป
สิ่งสำคัญที่สุดคือมีไปป์ไลน์การแสดงผลที่เรียบง่ายตามแนวคิด ซึ่งผ่านการแยกส่วนอย่างละเอียดและใส่ใจในรายละเอียด ได้แยกออกเป็นองค์ประกอบหลายๆ ส่วนที่ทำงานได้ในตัวเอง จากนั้นจะแยกองค์ประกอบเหล่านี้ผ่านกระบวนการและชุดข้อความพร้อมกันเพื่อเพิ่มประสิทธิภาพที่ปรับขนาดได้และโอกาสในการขยายการใช้งานให้ได้มากที่สุด
องค์ประกอบแต่ละอย่างมีบทบาทสำคัญในการเพิ่มประสิทธิภาพการทำงานและฟีเจอร์ต่างๆ ของเว็บแอปที่ทันสมัยทั้งหมด เร็วๆ นี้เราจะเผยแพร่ข้อมูลเชิงลึก และบทบาทสำคัญของแต่ละกลุ่ม
แต่ก่อนหน้านั้น ฉันจะอธิบายว่าโครงสร้างข้อมูลหลักที่กล่าวถึงในโพสต์นี้ (ข้อมูลที่ระบุในด้านข้างของแผนภาพไปป์ไลน์การแสดงผล) มีความสำคัญพอๆ กับ RenderingNG ที่เป็นคอมโพเนนต์ของโค้ดอย่างไร
ขอขอบคุณที่อ่าน โปรดอดใจรอ
ภาพโดย Una Kravets