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