TL;DR: Extensions API ได้รับการอัปเดตให้รองรับแคชย้อนหลัง/ไปข้างหน้า รวมถึงการโหลดการไปยังส่วนต่างๆ ล่วงหน้า โปรดดูรายละเอียดด้านล่าง
Chrome พยายามทําให้การนำทางรวดเร็ว เทคโนโลยีการนําทางทันที เช่น Back-Forward Cache (มีให้ใช้งานบนเดสก์ท็อปใน Chrome 96) และกฎการคาดคะเน (มีให้ใช้งานใน Chrome 103) ช่วยปรับปรุงทั้งประสบการณ์การย้อนกลับและเดินหน้า ในโพสต์นี้ เราจะพูดถึงการอัปเดตที่เราทำกับ API ของส่วนขยายเบราว์เซอร์เพื่อรองรับเวิร์กโฟลว์ใหม่เหล่านี้
ทำความเข้าใจประเภทของหน้า
ก่อนที่จะมี Back-Forward Cache และการแสดงผลล่วงหน้า แท็บแต่ละแท็บจะมีหน้าเว็บที่ใช้งานอยู่เพียงหน้าเดียว ตัวเลือกนี้แสดงอยู่เสมอ หากผู้ใช้กลับไปที่หน้าก่อนหน้า ระบบจะทำลายหน้าเว็บที่ใช้งานอยู่ (หน้า B) และสร้างหน้าก่อนหน้าในประวัติขึ้นมาใหม่ทั้งหมด (หน้า A) ส่วนขยายไม่จําเป็นต้องกังวลว่าหน้าเว็บอยู่ในช่วงใดของวงจรเนื่องจากมีเพียงหน้าเดียวสําหรับแท็บหนึ่งๆ นั่นคือสถานะ "ใช้งานอยู่/แสดงอยู่"
เมื่อใช้ Back-Forward Cache และการแสดงผลล่วงหน้า แท็บและหน้าเว็บจะไม่มีความสัมพันธ์แบบ 1:1 อีกต่อไป ตอนนี้แต่ละแท็บจะจัดเก็บหน้าเว็บหลายหน้าและหน้าเว็บจะเปลี่ยนสถานะไปมาแทนที่จะทำลายและสร้างใหม่
เช่น หน้าเว็บอาจเริ่มต้นเป็นหน้าที่แสดงผลล่วงหน้า (ไม่แสดง) จากนั้นเปลี่ยนเป็นหน้าที่ใช้งานอยู่ (แสดง) เมื่อผู้ใช้คลิกลิงก์ จากนั้นระบบจะจัดเก็บหน้าเว็บดังกล่าวไว้ในแคช Back/Forward (ไม่แสดง) เมื่อผู้ใช้ไปยังหน้าอื่น โดยที่หน้าเว็บดังกล่าวจะไม่ถูกทำลาย เราจะดูพร็อพเพอร์ตี้ใหม่ที่แสดงในบทความนี้เพื่อช่วยให้ชิ้นงานเข้าใจสถานะของหน้า
โปรดทราบว่าแท็บหนึ่งๆ อาจมีหน้าเว็บที่แสดงผลล่วงหน้าหลายหน้า (ไม่ใช่แค่หน้าเดียว) หน้าที่ใช้งานอยู่ (แสดงอยู่) หน้าเดียว และหน้าเว็บที่แคชไว้สำหรับ "ย้อนกลับ/ไปข้างหน้า" หลายหน้า
มีอะไรเปลี่ยนแปลงสำหรับนักพัฒนาส่วนขยายบ้าง
FrameId == 0
ใน Chromium เราเรียกเฟรมบนสุด/เฟรมหลักว่าเฟรมด้านนอกสุด
ผู้เขียนส่วนขยายที่ถือว่า frameId ของเฟรมด้านนอกสุดคือ 0 (แนวทางปฏิบัติแนะนำก่อนหน้านี้) อาจพบปัญหา
เนื่องจากตอนนี้แท็บมีเฟรมด้านนอกสุดได้หลายเฟรม (หน้าเว็บที่แสดงผลล่วงหน้าและแคชไว้) การคาดการณ์ว่าแท็บมีเฟรมด้านนอกสุดเพียงเฟรมเดียวจึงไม่ถูกต้อง frameId == 0
จะยังคงแสดงเฟรมด้านนอกสุดของหน้าที่ใช้งานอยู่ แต่เฟรมด้านนอกสุดของหน้าอื่นๆ ในแท็บเดียวกันจะไม่เป็น 0 เราได้เพิ่มช่องใหม่ frameType เพื่อแก้ไขปัญหานี้ ดูส่วน"ฉันจะรู้ได้อย่างไรว่าเฟรมเป็นเฟรมด้านนอกสุดหรือไม่" ของโพสต์นี้
วงจรชีวิตของเฟรมเทียบกับเอกสาร
แนวคิดอีกอย่างที่ทำให้เกิดปัญหากับส่วนขยายคือวงจรชีวิตของเฟรม เฟรมโฮสต์เอกสาร (ซึ่งเชื่อมโยงกับ URL ที่คอมมิต) เอกสารอาจเปลี่ยนแปลงได้ (เช่น โดยการไปยังส่วนต่างๆ) แต่ frameId จะไม่เปลี่ยนแปลง ดังนั้นจึงเชื่อมโยงสิ่งที่เกิดขึ้นในเอกสารหนึ่งๆ กับ frameId เพียงอย่างเดียวได้ยาก เราขอแนะนำแนวคิดของ documentId ซึ่งเป็นตัวระบุที่ไม่ซ้ำกันสำหรับเอกสารแต่ละรายการ หากมีการไปยังส่วนต่างๆ ของเฟรมและเปิดเอกสารใหม่ ตัวระบุจะเปลี่ยนไป ช่องนี้มีประโยชน์ในการระบุเวลาที่หน้าเว็บเปลี่ยนสถานะวงจร (ระหว่างการแสดงผลก่อนการโหลด/ใช้งานอยู่/แคชไว้) เนื่องจากค่านี้ยังคงเดิม
เหตุการณ์การไปยังส่วนต่างๆ ของเว็บ
เหตุการณ์ในเนมสเปซ chrome.webNavigation
สามารถทริกเกอร์หลายครั้งในหน้าเดียวกันโดยขึ้นอยู่กับวงจรของเหตุการณ์ ดูส่วน"ฉันจะทราบได้อย่างไรว่าหน้าเว็บอยู่ในวงจรใด" และ"ฉันจะทราบได้อย่างไรว่าหน้าเว็บมีการเปลี่ยนแปลงเมื่อใด"
ฉันจะทราบได้อย่างไรว่าหน้าเว็บอยู่ในวงจรใด
เราได้เพิ่มประเภท DocumentLifecycle
ลงใน API ของส่วนขยายหลายรายการที่เคยมี frameId
ให้บริการก่อนหน้านี้ หากมีประเภท DocumentLifecycle
ในเหตุการณ์ (เช่น onCommitted
) ค่าของประเภทนี้คือสถานะที่ระบบสร้างเหตุการณ์ คุณสามารถค้นหาข้อมูลจากเมธอด WebNavigation
getFrame()
และ getAllFrames()
ได้ทุกเมื่อ แต่การใช้ค่าจากเหตุการณ์เป็นวิธีที่แนะนำเสมอ หากคุณใช้วิธีใดวิธีหนึ่ง โปรดทราบว่าสถานะของเฟรมอาจเปลี่ยนแปลงระหว่างเวลาที่สร้างเหตุการณ์กับเวลาที่ Promise ของทั้ง 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"
เมื่อหน้าเว็บที่แสดงผลล่วงหน้ากลายเป็นหน้าเว็บที่ใช้งานอยู่
เมื่อหน้าเว็บเปลี่ยนจากแคชย้อนกลับ/ไปข้างหน้าหรือการแสดงผลล่วงหน้าเป็นสถานะใช้งาน จะมีเหตุการณ์อีก 3 รายการ (แต่ DocumentLifecyle
จะเปลี่ยนเป็น "active"
)
onBeforeNavigate
onCommitted
onCompleted
documentId
จะยังคงเหมือนเดิมกับในเหตุการณ์เดิม ดังที่แสดงด้านบนเมื่อ documentId
== xyz เปิดใช้งาน โปรดทราบว่าเหตุการณ์การนําทางเดียวกันจะเริ่มต้นขึ้น ยกเว้นเหตุการณ์ onDOMContentLoaded
เนื่องจากหน้าเว็บโหลดไปแล้ว
หากมีความคิดเห็นหรือข้อสงสัย โปรดสอบถามในแชทกลุ่ม chromium-extensions