ส่วนขยายของ Chrome: การขยาย API เพื่อรองรับการนำทางแบบทันที

Dave Tapuska
Dave Tapuska

TL;DR: Extensions API ได้รับการอัปเดตให้รองรับ Back-Forward Cache กำลังโหลดการนำทางล่วงหน้า โปรดดูรายละเอียดด้านล่าง

Chrome ทำงานอย่างหนักเพื่อให้การนำทางรวดเร็ว การนำทางด่วน เทคโนโลยีอย่างเช่น แคชย้อนหลัง (จัดส่งแล้วบนเดสก์ท็อปในเดือน Chrome 96) และกฎการคาดเดา (จัดส่งแล้วใน Chrome 103) ปรับปรุงทั้งการย้อนกลับและในอนาคต ประสบการณ์การใช้งาน ในโพสต์นี้ เราจะมาดูการอัปเดตต่างๆ ที่เราได้ดำเนินการกับเบราว์เซอร์ API เพื่อรองรับเวิร์กโฟลว์ใหม่เหล่านี้

การทำความเข้าใจประเภทของหน้าเว็บ

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

วันที่ การปลดหน้าเว็บที่ใช้งานอยู่
การปลดหน้าที่ใช้งานอยู่

เมื่อใช้ Back-Forward Cache และการแสดงผลล่วงหน้า จะไม่มีการดำเนินการแบบ 1 ต่อ 1 อีกต่อไป ความสัมพันธ์ระหว่างแท็บและหน้า ตอนนี้แต่ละแท็บจัดเก็บ หน้าเว็บและหน้าเว็บเปลี่ยนไปมาระหว่างรัฐต่างๆ มากกว่าจะถูกทำลายและ ขึ้นมาใหม่

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

วันที่ ประเภทของหน้าเว็บ
ประเภทของหน้าเว็บ

โปรดทราบว่าแท็บหนึ่งๆ อาจมีหน้าที่แสดงผลล่วงหน้าหลายหน้า (ไม่ใช่แค่หน้าเดียว) หน้าเดียว หน้าใช้งานอยู่ (มองเห็นได้) และชุดของหน้าที่แคชไว้กลับ/ไปข้างหน้า

สิ่งที่เปลี่ยนแปลงไปสำหรับนักพัฒนาส่วนขยาย

FrameId == 0

ใน Chromium เราจะเรียกเฟรมที่อยู่บนสุด/เฟรมหลักว่าเป็นเฟรมด้านนอกสุด

ผู้เขียนส่วนขยายที่กำหนดให้มี frameId ของกรอบด้านนอกสุดเท่ากับ 0 (แนวทางปฏิบัติแนะนำก่อนหน้านี้) อาจมีปัญหา เนื่องจากตอนนี้แท็บสามารถมีเฟรมด้านนอกสุดได้หลายเฟรม (แสดงผลล่วงหน้าและแคชแล้ว ) สมมติว่ามีชั้นนอกสุด เฟรมของแท็บไม่ถูกต้อง frameId == 0 จะยังคงเป็นตัวแทน เฟรมด้านนอกสุดของหน้าเว็บที่ทำงาน แต่เฟรมด้านนอกสุดของ หน้าอื่นๆ ในแท็บเดียวกันจะไม่เป็น 0 ช่อง frameType ใหม่มี ได้รับการเพิ่ม เพื่อแก้ไขปัญหานี้ ดูบทความ "ฉันจะรู้ได้อย่างไรว่ากรอบคือกรอบด้านนอกสุด" ของโพสต์นี้

วงจรชีวิตของเฟรมเทียบกับเอกสาร

อีกแนวคิดหนึ่งที่เป็นปัญหากับส่วนขยายคือวงจรชีวิตของ เฟรม เฟรมจะโฮสต์เอกสาร (ซึ่งเชื่อมโยงกับ URL ที่คอมมิต) เอกสารสามารถเปลี่ยนแปลงได้ (เช่น ด้วยการไปยังส่วนต่างๆ) แต่ frameId จะไม่เปลี่ยนแปลง ดังนั้น ยากที่จะเชื่อมโยงว่าเกิดอะไรขึ้นในเอกสารบางฉบับ เพียง frameIds เราขอแนะนำแนวคิดของ documentId ซึ่งเป็นตัวระบุที่ไม่ซ้ำกัน สำหรับเอกสารแต่ละฉบับ หากมีการนำทางไปยังเฟรม เปิดเอกสารใหม่ที่ตัวระบุจะเปลี่ยนแปลง ช่องนี้มีประโยชน์สำหรับ กำหนดว่าหน้าเว็บจะเปลี่ยนสถานะวงจร (ระหว่าง การแสดงผลล่วงหน้า/ใช้งานอยู่/แคช) เนื่องจากยังคงเหมือนเดิม

เหตุการณ์การนําทางในเว็บ

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

ฉันจะทราบได้อย่างไรว่าหน้าเว็บอยู่ในวงจรของลูกค้าอย่างไร

DocumentLifecycle มีการเพิ่มประเภทลงใน API ส่วนขยายจำนวนหนึ่งที่ frameId ถูก ที่เคยมีให้บริการก่อนหน้านี้ หากมีประเภท DocumentLifecycle อยู่ในเหตุการณ์ (เช่น onCommitted) ค่าของเหตุการณ์คือสถานะที่สร้างเหตุการณ์ คุณสามารถค้นหา ข้อมูลจาก WebNavigation getFrame() และ getAllFrames() แต่แนะนำให้ใช้ค่าจากเหตุการณ์เสมอ หากคุณใช้ อย่างใดอย่างหนึ่ง โปรดทราบว่าสถานะของเฟรมอาจเปลี่ยนแปลงระหว่างเวลาที่เกิดเหตุการณ์ เกิดขึ้น และเมื่อคำมั่นสัญญาจากทั้ง 2 วิธีได้รับการแก้ไข

DocumentLifecycle มีค่าต่อไปนี้

  • "prerender นิ้ว : ยังไม่นำเสนอต่อผู้ใช้ในขณะนี้ แต่กำลังเตรียมที่อาจจะแสดงต่อผู้ใช้
  • "active": แสดงต่อผู้ใช้
  • "cached": จัดเก็บไว้ในแคชย้อนหลัง
  • "pending_deletion": ระบบกำลังทำลายเอกสาร

ฉันจะทราบได้อย่างไรว่ากรอบเป็นกรอบด้านนอกสุด

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

เพื่อช่วยในเรื่องนี้ เราจึงได้เปิดตัวประเภทใหม่ที่ชื่อว่า FrameType ดังนั้น การพิจารณาว่าเฟรมอยู่ในเฟรมด้านนอกสุดจึงทำได้ง่ายๆ FrameType มีค่าต่อไปนี้

  • "outermost_frame": โดยทั่วไปจะเรียกว่าเฟรมระดับบนสุด โปรดทราบว่า สิ่งเหล่านี้สามารถทำได้หลายแบบ เช่น หากคุณมีการแสดงผลล่วงหน้าและแคช แต่ละหน้ามีเฟรมด้านนอกสุดซึ่งอาจเรียกว่าเฟรมบนสุด
  • "fenced_frame": สงวนไว้สำหรับการใช้งานในอนาคต
  • "sub_frame": โดยปกติจะเป็น iframe

เราสามารถรวม DocumentLifecycle กับ FrameType และกำหนดว่าเฟรมหนึ่งๆ เป็น เฟรมด้านนอกสุดที่ใช้งานอยู่ ดังตัวอย่างต่อไปนี้ tab.documentLifecycle === “active” && frameType === “outermost_frame”

ฉันจะแก้ปัญหาเกี่ยวกับเวลาของเฟรมได้อย่างไร

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

ในการแก้ปัญหานี้ เราจึงได้เปิดตัว documentId (และ parentDocumentId) webNavigation.getFrame() ตอนนี้ ค่า frameId จะเป็นแบบไม่บังคับ หากมี documentId documentId จะเปลี่ยนเมื่อใดก็ตามที่มีการนำทางในเฟรม

ฉันจะระบุเมื่อมีการเปลี่ยนหน้าได้อย่างไร

มีสัญญาณที่ชัดเจนที่จะระบุเมื่อมีการเปลี่ยนหน้าระหว่างรัฐต่างๆ

มาดูกันที่เหตุการณ์ WebNavigation

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

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

ภาพประกอบนี้แสดงให้เห็นในแผนภาพด้านล่างซึ่งแสดงการเปลี่ยนแปลงของ documentId เป็น "xyz" เมื่อหน้าที่แสดงผลล่วงหน้ากลายเป็นหน้าที่ใช้งานอยู่

วันที่ documentId จะเปลี่ยนแปลงเมื่อหน้าที่แสดงผลล่วงหน้ากลายเป็นหน้าที่ใช้งานอยู่
documentId จะเปลี่ยนแปลงเมื่อหน้าที่แสดงผลล่วงหน้ากลายเป็น หน้าที่ใช้งานอยู่

เมื่อหน้าเว็บเปลี่ยนจากแคชย้อนหลังหรือการแสดงผลล่วงหน้าไปเป็น สถานะใช้งานอยู่จะมีอีก 3 เหตุการณ์ (แต่มี DocumentLifecyle ซึ่งก็คือ "active")

onBeforeNavigate
onCommitted
onCompleted

documentId จะยังเหมือนเดิมเมื่อเกิดเหตุการณ์เดิม นี่คือ แสดงไว้ด้านบนเมื่อ documentId == xyz เปิดใช้งาน โปรดทราบว่า เหตุการณ์การนำทางเริ่มทำงานเดียวกัน ยกเว้น onDOMContentLoaded เหตุการณ์เนื่องจากหน้าถูกโหลดแล้ว

หากมีความคิดเห็นหรือคำถามใดๆ โปรดติดต่อเราที่ ส่วนขยาย Chromium กลุ่ม