เจาะลึกเว็บเบราว์เซอร์สมัยใหม่ (ตอนที่ 2)

Mariko Kosaka

สิ่งที่เกิดขึ้นในการนําทาง

บทความนี้เป็นส่วนที่ 2 ของชุดบล็อก 4 ส่วนที่อธิบายการทำงานภายในของ Chrome ในโพสต์ก่อนหน้า เราได้ดูวิธีที่กระบวนการและเธรดต่างๆ จัดการส่วนต่างๆ ของเบราว์เซอร์ ในโพสต์นี้ เราจะเจาะลึกวิธีที่แต่ละกระบวนการและแต่ละเธรดสื่อสารกันเพื่อแสดงเว็บไซต์

มาดูกรณีการใช้งานการท่องเว็บแบบง่ายๆ กัน คุณพิมพ์ URL ลงในเบราว์เซอร์ จากนั้นเบราว์เซอร์จะดึงข้อมูลจากอินเทอร์เน็ตและแสดงหน้าเว็บ ในโพสต์นี้ เราจะมุ่งเน้นที่ส่วนที่ผู้ใช้ขอเว็บไซต์และเบราว์เซอร์เตรียมที่จะแสดงผลหน้าเว็บ หรือที่เรียกว่าการไปยังส่วนต่างๆ

โดยเริ่มต้นจากกระบวนการของเบราว์เซอร์

กระบวนการของเบราว์เซอร์
รูปที่ 1: UI เบราว์เซอร์ที่ด้านบน แผนภาพกระบวนการเบราว์เซอร์ที่มี UI, เครือข่าย และสตอเรจ ที่ด้านล่าง

ดังที่ได้อธิบายไว้ในส่วนที่ 1: CPU, GPU, หน่วยความจำ และสถาปัตยกรรมแบบหลายกระบวนการ ทุกอย่างที่อยู่นอกแท็บจะจัดการโดยกระบวนการของเบราว์เซอร์ กระบวนการของเบราว์เซอร์มีเธรด เช่น เธรด UI ที่วาดปุ่มและช่องป้อนข้อมูลของเบราว์เซอร์ เธรดเครือข่ายที่จัดการสแต็กเครือข่ายเพื่อรับข้อมูลจากอินเทอร์เน็ต เธรดพื้นที่เก็บข้อมูลที่ควบคุมการเข้าถึงไฟล์ และอื่นๆ เมื่อคุณพิมพ์ URL ในแถบที่อยู่ เทรด UI ของกระบวนการเบราว์เซอร์จะจัดการอินพุตของคุณ

การนำทางที่ง่าย

ขั้นตอนที่ 1: การจัดการอินพุต

เมื่อผู้ใช้เริ่มพิมพ์ในแถบที่อยู่ สิ่งแรกที่ UI Thread จะถามคือ "นี่คือคำค้นหาหรือ URL ใช่ไหม" ใน Chrome แถบที่อยู่ยังเป็นช่องป้อนข้อมูลการค้นหาด้วย ด้าย UI จึงต้องแยกวิเคราะห์และตัดสินใจว่าจะส่งคุณไปยังเครื่องมือค้นหาหรือไปยังเว็บไซต์ที่คุณขอ

การจัดการการป้อนข้อมูลของผู้ใช้
รูปที่ 1: เทรด UI ที่ถามว่าอินพุตคือคำค้นหาหรือ URL

ขั้นตอนที่ 2: เริ่มการนำทาง

เมื่อผู้ใช้กด Enter เทรด UI จะเริ่มต้นการเรียกใช้เครือข่ายเพื่อรับเนื้อหาเว็บไซต์ แถบหมุนที่แสดงสถานะการโหลดจะปรากฏที่มุมของแท็บ และชุดข้อความของเครือข่ายจะดำเนินการตามโปรโตคอลที่เหมาะสม เช่น การค้นหา DNS และการสร้างการเชื่อมต่อ TLS สำหรับคำขอ

การเริ่มการนำทาง
รูปที่ 2: เทรด UI ที่สื่อสารกับเทรดเครือข่ายเพื่อไปยัง mysite.com

เมื่อถึงจุดนี้ เทรดของเครือข่ายอาจได้รับส่วนหัวการเปลี่ยนเส้นทางของเซิร์ฟเวอร์ เช่น HTTP 301 ในกรณีนี้ เธรดเครือข่ายจะสื่อสารกับเธรด UI ว่าเซิร์ฟเวอร์กำลังขอเปลี่ยนเส้นทาง จากนั้นระบบจะเริ่มคําขอ URL อื่น

ขั้นตอนที่ 3: อ่านคำตอบ

การตอบสนองของ HTTP
รูปที่ 3: ส่วนหัวการตอบกลับซึ่งมี Content-Type และเพย์โหลด ซึ่งเป็นข้อมูลจริง

เมื่อเริ่มได้รับเนื้อหาของคำตอบ (เพย์โหลด) เทรดของเครือข่ายจะดูไบต์ 2-3 ตัวแรกของสตรีม หากจําเป็น ส่วนหัว Content-Type ของการตอบกลับควรระบุประเภทของข้อมูล แต่เนื่องจากส่วนหัวนี้อาจขาดหายไปหรือไม่ถูกต้อง ระบบจึงทำการสนิฟประเภท MIME ที่นี่ การดำเนินการนี้ "ยุ่งยาก" ตามที่แสดงความคิดเห็นไว้ในซอร์สโค้ด คุณสามารถอ่านความคิดเห็นเพื่อดูว่าเบราว์เซอร์ต่างๆ จัดการคู่ประเภทเนื้อหา/เพย์โหลดอย่างไร

หากคำตอบเป็นไฟล์ HTML ขั้นตอนถัดไปคือการส่งข้อมูลไปยังกระบวนการแสดงผล แต่หากเป็นไฟล์ ZIP หรือไฟล์อื่นๆ แสดงว่าเป็นคำขอดาวน์โหลด จึงต้องส่งข้อมูลไปยังเครื่องมือจัดการการดาวน์โหลด

การตรวจหาประเภท MIME
รูปที่ 4: เทรดของเครือข่ายที่ถามว่าข้อมูลการตอบกลับเป็น HTML จากเว็บไซต์ที่ปลอดภัยหรือไม่

ซึ่งการตรวจสอบ SafeBrowsing ก็จะเกิดขึ้นที่นี่ด้วย หากโดเมนและข้อมูลการตอบกลับดูเหมือนจะตรงกับเว็บไซต์ที่เป็นอันตรายซึ่งทราบแล้ว เทรดของเครือข่ายจะแจ้งเตือนให้แสดงหน้าคำเตือน นอกจากนี้ ระบบจะตรวจสอบการบล็อกการอ่านจากแหล่งที่มาข้ามเว็บไซต์ (CORB) เพื่อให้แน่ใจว่าข้อมูลข้ามเว็บไซต์ที่ละเอียดอ่อนจะไม่เข้าสู่กระบวนการแสดงผล

ขั้นตอนที่ 4: ค้นหากระบวนการแสดงผล

เมื่อการตรวจสอบทั้งหมดเสร็จสิ้นและเทรดเธรดเครือข่ายมั่นใจว่าเบราว์เซอร์ควรไปยังเว็บไซต์ที่ขอ เทรดเธรดเครือข่ายจะแจ้งให้เทรดเธรด UI ทราบว่าข้อมูลพร้อมแล้ว จากนั้นเธรด UI จะค้นหากระบวนการแสดงผลเพื่อแสดงผลหน้าเว็บต่อ

ค้นหากระบวนการแสดงผล
รูปที่ 5: เทรดของเครือข่ายบอกเทรด UI ให้ค้นหากระบวนการแสดงผล

เนื่องจากคำขอเครือข่ายอาจใช้เวลาหลายร้อยมิลลิวินาทีจึงจะได้รับการตอบกลับ ระบบจึงใช้การเพิ่มประสิทธิภาพเพื่อเร่งกระบวนการนี้ เมื่อเธรด UI ส่งคำขอ URL ไปยังเธรดเครือข่ายในขั้นตอนที่ 2 นั้น เธรดจะทราบอยู่แล้วว่ากำลังไปยังเว็บไซต์ใด ด้าย UI จะพยายามค้นหาหรือเริ่มกระบวนการแสดงผลล่วงหน้าควบคู่ไปกับคำขอเครือข่าย วิธีนี้จะช่วยให้กระบวนการแสดงผลอยู่ในสถานะรออยู่แล้วเมื่อเธรดเครือข่ายได้รับข้อมูล หากทุกอย่างเป็นไปตามที่คาดไว้ ระบบอาจไม่ใช้กระบวนการสแตนด์บายนี้หากการนําทางเปลี่ยนเส้นทางข้ามเว็บไซต์ ซึ่งในกรณีนี้อาจต้องใช้กระบวนการอื่น

ขั้นตอนที่ 5: ยืนยันการนําทาง

เมื่อข้อมูลและกระบวนการแสดงผลพร้อมแล้ว ระบบจะส่ง IPC จากกระบวนการเบราว์เซอร์ไปยังกระบวนการแสดงผลเพื่อส่งผ่านการนําทาง และยังส่งสตรีมข้อมูลเพื่อให้กระบวนการแสดงผลรับข้อมูล HTML ได้อย่างต่อเนื่อง เมื่อกระบวนการเบราว์เซอร์ได้รับการยืนยันว่ามีการคอมมิตในกระบวนการแสดงผลแล้ว การนำทางจะเสร็จสมบูรณ์และระยะการโหลดเอกสารจะเริ่มขึ้น

เมื่อถึงจุดนี้ แถบที่อยู่จะอัปเดต และตัวบ่งชี้ความปลอดภัยและ UI การตั้งค่าเว็บไซต์จะแสดงข้อมูลเว็บไซต์ของหน้าใหม่ ระบบจะอัปเดตประวัติเซสชันของแท็บเพื่อให้ปุ่มย้อนกลับ/ไปข้างหน้าไปยังเว็บไซต์ที่เพิ่งไปยัง ระบบจะจัดเก็บประวัติเซสชันไว้ในดิสก์เมื่อคุณปิดแท็บหรือหน้าต่าง เพื่อให้กู้คืนแท็บ/เซสชันได้ง่ายขึ้น

ยืนยันการนําทาง
รูปที่ 6: IPC ระหว่างเบราว์เซอร์และกระบวนการแสดงผล เป็นการขอแสดงผลหน้าเว็บ

ขั้นตอนเพิ่มเติม: การโหลดเริ่มต้นเสร็จสมบูรณ์

เมื่อการนําทางเสร็จสมบูรณ์แล้ว กระบวนการแสดงผลจะโหลดทรัพยากรและแสดงผลหน้าเว็บต่อไป เราจะอธิบายรายละเอียดเกี่ยวกับสิ่งที่จะเกิดขึ้นในระยะนี้ในโพสต์ถัดไป เมื่อกระบวนการแสดงผลของโปรแกรมแสดงผล "เสร็จสิ้น" การแสดงผลแล้ว ก็จะส่ง IPC กลับไปที่กระบวนการเบราว์เซอร์ (การดำเนินการนี้เกิดขึ้นหลังจากที่เหตุการณ์ onload ทั้งหมดเริ่มทํางานในเฟรมทั้งหมดในหน้าเว็บและดําเนินการเสร็จสิ้นแล้ว) เมื่อถึงจุดนี้ เทรด UI จะหยุดไอคอนหมุนที่แสดงว่ากำลังโหลดในแท็บ

เราใช้คำว่า "เสร็จสิ้น" เนื่องจาก JavaScript ฝั่งไคลเอ็นต์อาจยังโหลดทรัพยากรเพิ่มเติมและแสดงผลมุมมองใหม่หลังจากนี้

หน้าเว็บโหลดเสร็จ
รูปที่ 7: IPC จากโปรแกรมแสดงผลไปยังกระบวนการเบราว์เซอร์เพื่อแจ้งว่าหน้าเว็บ "โหลด" แล้ว

การนำทางแบบง่ายเสร็จสมบูรณ์แล้ว แต่จะเกิดอะไรขึ้นหากผู้ใช้ป้อน URL อื่นในแถบที่อยู่อีกครั้ง กระบวนการของเบราว์เซอร์จะทําตามขั้นตอนเดียวกันเพื่อไปยังเว็บไซต์อื่น แต่ก่อนที่จะดำเนินการดังกล่าว จะต้องตรวจสอบกับเว็บไซต์ที่แสดงผลอยู่ในปัจจุบันว่าสนใจเหตุการณ์ beforeunload หรือไม่

beforeunload สามารถสร้างการแจ้งเตือน "ออกจากเว็บไซต์นี้ไหม" เมื่อคุณพยายามออกจากหน้าเว็บหรือปิดแท็บ ทุกอย่างในแท็บ รวมถึงโค้ด JavaScript ของคุณจะได้รับการจัดการโดยกระบวนการแสดงผล ดังนั้นกระบวนการของเบราว์เซอร์จึงต้องตรวจสอบกับกระบวนการแสดงผลปัจจุบันเมื่อมีคำขอไปยังส่วนต่างๆ ใหม่เข้ามา

เครื่องจัดการเหตุการณ์ beforeunload
รูปที่ 8: IPC จากกระบวนการเบราว์เซอร์ไปยังกระบวนการแสดงผล ซึ่งบอกให้ทราบว่ากำลังจะไปยังเว็บไซต์อื่น

หากการนําทางเริ่มต้นจากกระบวนการแสดงผล (เช่น ผู้ใช้คลิกลิงก์หรือ JavaScript ฝั่งไคลเอ็นต์ทำงานwindow.location = "https://newsite.com") กระบวนการแสดงผลจะตรวจสอบตัวแฮนเดิล beforeunload ก่อน จากนั้นจะเข้าสู่กระบวนการเดียวกับที่เบราว์เซอร์เริ่มการนําทาง ข้อแตกต่างเพียงอย่างเดียวคือคําขอไปยังส่วนต่างๆ ของหน้าเว็บจะเริ่มต้นจากกระบวนการแสดงผลไปยังกระบวนการเบราว์เซอร์

เมื่อมีการนําทางใหม่ไปยังเว็บไซต์อื่นที่ไม่ใช่เว็บไซต์ที่แสดงผลอยู่ในปัจจุบัน ระบบจะเรียกใช้กระบวนการแสดงผลแยกต่างหากเพื่อจัดการการนําทางใหม่ ขณะที่ยังคงใช้กระบวนการแสดงผลปัจจุบันเพื่อจัดการเหตุการณ์ต่างๆ เช่น unload ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมสถานะวงจรหน้าเว็บ และวิธีเชื่อมต่อกับเหตุการณ์ด้วย Page Lifecycle API

การนำทางใหม่และการขนถ่าย
รูปที่ 9: IPC 2 รายการจากกระบวนการเบราว์เซอร์ไปยังกระบวนการแสดงผลใหม่เพื่อบอกให้แสดงผลหน้าเว็บ และบอกให้กระบวนการแสดงผลเก่ายกเลิกการโหลด

ในกรณีของ Service Worker

การเปลี่ยนแปลงล่าสุดอย่างหนึ่งในกระบวนการนําทางนี้คือการนำService Worker มาใช้ Service Worker เป็นวิธีเขียนพร็อกซีเครือข่ายในโค้ดแอปพลิเคชัน ซึ่งช่วยให้นักพัฒนาเว็บควบคุมสิ่งที่จะแคชไว้ในเครื่องและเวลาที่ควรรับข้อมูลใหม่จากเครือข่ายได้มากขึ้น หากตั้งค่า Service Worker ให้โหลดหน้าเว็บจากแคช ก็ไม่จำเป็นต้องขอข้อมูลจากเครือข่าย

สิ่งที่สำคัญที่ต้องจำคือ Service Worker คือโค้ด JavaScript ที่ทำงานในกระบวนการแสดงผล แต่เมื่อได้รับคําขอไปยังส่วนต่างๆ เบราว์เซอร์จะรู้ได้อย่างไรว่าเว็บไซต์มี Service Worker

การค้นหาขอบเขต Service Worker
รูปที่ 10: เทรดเวิร์กเครือข่ายในกระบวนการเบราว์เซอร์ที่ค้นหาขอบเขต Service Worker

เมื่อลงทะเบียน Service Worker แล้ว ระบบจะเก็บขอบเขตของ Service Worker ไว้เป็นข้อมูลอ้างอิง (อ่านเพิ่มเติมเกี่ยวกับขอบเขตได้ในบทความวงจรชีวิตของ Service Worker นี้) เมื่อมีการไปยังส่วนต่างๆ เทรดเธรดของเครือข่ายจะตรวจสอบโดเมนเทียบกับขอบเขตของ Service Worker ที่ลงทะเบียนไว้ หากลงทะเบียน Service Worker สําหรับ URL นั้นไว้ เทรดเธรด UI จะค้นหากระบวนการแสดงผลเพื่อเรียกใช้โค้ด Service Worker เซอร์วิสเวิร์กอาจโหลดข้อมูลจากแคช ซึ่งทำให้ไม่ต้องขอข้อมูลจากเครือข่าย หรืออาจขอทรัพยากรใหม่จากเครือข่าย

การนำทางของ ServiceWorker
รูปที่ 11: เทรด UI ในกระบวนการของเบราว์เซอร์ที่เริ่มต้นกระบวนการแสดงผลเพื่อจัดการเวิร์กเกอร์บริการ จากนั้นเทรดเวิร์กเกอร์ในกระบวนการแสดงผลจะขอข้อมูลจากเครือข่าย

คุณจะเห็นว่าการเดินทางไปกลับระหว่างกระบวนการเบราว์เซอร์และกระบวนการแสดงผลอาจทำให้เกิดความล่าช้าหากท้ายที่สุดแล้ว Service Worker ตัดสินใจที่จะขอข้อมูลจากเครือข่าย การโหลดเส้นทางล่วงหน้าเป็นกลไกในการเร่งกระบวนการนี้โดยการโหลดทรัพยากรควบคู่ไปกับการเปิดใช้งาน Service Worker โดยจะทำเครื่องหมายคำขอเหล่านี้ด้วยส่วนหัว ซึ่งช่วยให้เซิร์ฟเวอร์ตัดสินใจส่งเนื้อหาที่แตกต่างกันสำหรับคำขอเหล่านี้ได้ เช่น ส่งเฉพาะข้อมูลที่อัปเดตแล้วแทนที่จะเป็นเอกสารฉบับเต็ม

การโหลดการนำทางล่วงหน้า
รูปที่ 12: เทรด UI ในกระบวนการเบราว์เซอร์ที่เริ่มต้นกระบวนการแสดงผลเพื่อจัดการเวิร์กเกอร์บริการขณะส่งคำขอเครือข่ายไปพร้อมกัน

สรุป

ในโพสต์นี้ เราได้ดูสิ่งที่เกิดขึ้นระหว่างการนําทางและวิธีที่โค้ดเว็บแอปพลิเคชัน เช่น ส่วนหัวของคำตอบและ JavaScript ฝั่งไคลเอ็นต์โต้ตอบกับเบราว์เซอร์ การทราบขั้นตอนที่เบราว์เซอร์ใช้รับข้อมูลจากเครือข่ายจะช่วยให้เข้าใจเหตุผลที่พัฒนา API เช่น การโหลดนำทางล่วงหน้าได้ง่ายขึ้น ในโพสต์ถัดไป เราจะเจาะลึกวิธีที่เบราว์เซอร์ประเมิน HTML/CSS/JavaScript เพื่อแสดงผลหน้าเว็บ

คุณชอบโพสต์นี้ไหม หากมีข้อสงสัยหรือคำแนะนำสำหรับโพสต์ในอนาคต เรายินดีรับฟังจากคุณในส่วนความคิดเห็นด้านล่างหรือที่ @kosamari บน Twitter

ถัดไป: กระบวนการทํางานภายในของโปรแกรมแสดงผล