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