برنامه‌های افزودنی Chrome: گسترش API برای پشتیبانی از پیمایش فوری

دیو تاپوسکا
Dave Tapuska

TL;DR: Extensions API به‌روزرسانی شده است تا از حافظه پنهان عقب و جلو و بارگیری پیش‌بارگیری از کش پشتیبانی کند. برای جزئیات به زیر مراجعه کنید.

Chrome سخت در تلاش است تا ناوبری را سریع کند. فن‌آوری‌های پیمایش فوری مانند حافظه پنهان عقب/ جلو (که در کروم 96 بر روی دسک‌تاپ ارسال شده است ) و قوانین گمانه‌زنی ( ارسال شده در Chrome 103) هم تجربه بازگشت و هم به جلو را بهبود می‌بخشند. در این پست، به‌روزرسانی‌هایی را که برای APIهای افزونه‌های مرورگر برای تطبیق با این جریان‌های کاری جدید انجام داده‌ایم، بررسی می‌کنیم.

آشنایی با انواع صفحات

قبل از معرفی Back/Forward Cache و پیش اجرا، یک برگه فردی فقط یک صفحه فعال داشت. این همان چیزی بود که همیشه قابل مشاهده بود. اگر کاربر به صفحه قبلی بازگردد، صفحه فعال از بین می رود (صفحه B) و صفحه قبلی در تاریخ به طور کامل بازسازی می شود (صفحه A). برنامه‌های افزودنی نیازی به نگرانی در مورد قسمتی از صفحات چرخه زندگی نداشتند، زیرا فقط یکی برای یک برگه وجود داشت، حالت فعال/مرئی.

حذف صفحه فعال
حذف صفحه فعال

با Back/Forward Cache و پیش اجرا، دیگر رابطه یک به یک بین برگه ها و صفحات وجود ندارد. اکنون، هر تب در واقع چندین صفحه و انتقال صفحات بین حالت ها را به جای تخریب و بازسازی ذخیره می کند.

به عنوان مثال، یک صفحه می تواند زندگی خود را به عنوان یک صفحه از پیش اجرا شده (غیر قابل مشاهده) آغاز کند، هنگامی که کاربر روی یک پیوند کلیک می کند، به یک صفحه فعال (قابل مشاهده) تبدیل می شود، و سپس زمانی که کاربر در حافظه پنهان برگشت/به جلو (قابل مشاهده نیست) ذخیره می شود. به صفحه دیگری هدایت می شود، بدون اینکه صفحه هرگز از بین برود. بعداً در این مقاله به ویژگی‌های جدیدی که برای کمک به افزونه‌ها برای درک وضعیت صفحه‌ها در معرض دید قرار گرفته‌اند نگاه می‌کنیم.

انواع صفحات
انواع صفحات.

توجه داشته باشید که یک برگه می‌تواند دارای یک سری صفحات از پیش اجرا شده (نه فقط یک)، یک صفحه فعال (قابل مشاهده) و یک سری صفحات ذخیره‌سازی شده Back/Forward باشد.

چه چیزی برای توسعه دهندگان برنامه افزودنی تغییر می کند؟

FrameId == 0

در Chromium، ما به بالاترین/اصلی ترین قاب به عنوان بیرونی ترین قاب اشاره می کنیم.

نویسندگان برنامه افزودنی که FrameId خارجی ترین قاب را 0 فرض می کنند (بهترین روش قبلی) ممکن است مشکلاتی داشته باشند. از آنجایی که یک برگه اکنون می تواند چندین فریم خارجی داشته باشد (صفحات از قبل اجرا شده و ذخیره شده)، این فرض که بیرونی ترین فریم برای یک برگه وجود دارد، نادرست است. frameId == 0 همچنان بیرونی ترین فریم صفحه فعال را نشان می دهد، اما بیرونی ترین فریم صفحات دیگر در همان برگه غیرصفر خواهد بود. یک frameType فیلد جدید برای رفع این مشکل اضافه شده است. به بخش "چگونه می توانم تشخیص دهم که یک قاب بیرونی ترین قاب است؟" بخش این پست

چرخه زندگی فریم ها در مقابل اسناد

مفهوم دیگری که در پسوندها مشکل ساز است، چرخه عمر قاب است. یک فریم میزبان یک سند (که با یک URL متعهد مرتبط است). سند می‌تواند تغییر کند (مثلاً با پیمایش) اما FrameId تغییر نمی‌کند، و بنابراین دشوار است که چیزی در یک سند خاص با frameIds مرتبط شود. ما مفهوم یک documentId را معرفی می کنیم که یک شناسه منحصر به فرد برای هر سند است. اگر یک فریم پیمایش شود و یک سند جدید باز شود، شناسه تغییر خواهد کرد. این فیلد برای تعیین زمان تغییر وضعیت چرخه عمر صفحات (بین prerender/active/cache) مفید است زیرا ثابت می ماند.

رویدادهای ناوبری وب

رویدادها در فضای نام chrome.webNavigation می‌توانند چندین بار در یک صفحه بسته به چرخه حیاتی که در آن قرار دارد فعال شوند. به «چگونه می‌توانم بفهمم صفحه در چه چرخه زندگی است؟» مراجعه کنید. و "چگونه تعیین کنم که یک صفحه چه زمانی انتقال می یابد؟" بخش ها

چگونه می توانم بگویم که صفحه در چه چرخه ای قرار دارد؟

نوع DocumentLifecycle به تعدادی از افزونه‌های API که frameId قبلاً در دسترس بود، اضافه شده است. اگر نوع DocumentLifecycle در یک رویداد وجود داشته باشد (مانند onCommitted )، مقدار آن حالتی است که رویداد در آن ایجاد شده است. همیشه می توانید اطلاعات را از متدهای getFrame() و getAllFrames() WebNavigation جستجو کنید، اما استفاده از مقدار رویداد همیشه ترجیح داده می شود. اگر از هر یک از روش‌ها استفاده می‌کنید، توجه داشته باشید که وضعیت فریم ممکن است بین زمانی که رویداد ایجاد شده و زمانی که وعده‌های بازگشتی با هر دو روش حل می‌شود تغییر کند.

DocumentLifecycle دارای مقادیر زیر است:

  • "prerender " : در حال حاضر به کاربر ارائه نشده است اما در حال آماده شدن برای نمایش احتمالاً به کاربر است.
  • "active" : در حال حاضر به کاربر نمایش داده می شود.
  • "cached" : در حافظه پنهان Back/Forward ذخیره می شود.
  • "pending_deletion" : سند در حال نابودی است.

چگونه می توانم تشخیص دهم که یک قاب بیرونی ترین قاب است؟

ممکن است برنامه‌های افزودنی قبلاً بررسی کرده باشند که آیا frameId == 0 برای تعیین اینکه آیا رویداد رخ داده برای بیرونی‌ترین فریم است یا خیر. با چندین صفحه در یک برگه، اکنون چندین فریم بیرونی داریم، بنابراین تعریف FrameId مشکل ساز است. شما هرگز رویدادهای مربوط به یک قاب ذخیره‌سازی شده Back/Forward را دریافت نخواهید کرد. با این حال، برای فریم های از قبل اجرا شده، frameId برای بیرونی ترین فریم غیر صفر خواهد بود. بنابراین استفاده از frameId == 0 به عنوان سیگنالی برای تعیین اینکه آیا بیرونی ترین فریم است یا خیر، نادرست است.

برای کمک به این امر، نوع جدیدی به نام FrameType را معرفی کردیم تا تعیین اینکه آیا فریم واقعاً بیرونی ترین فریم است اکنون آسان است. FrameType دارای مقادیر زیر است:

  • "outermost_frame" : معمولاً به عنوان بالاترین فریم نامیده می شود. توجه داشته باشید که چندین مورد از این موارد وجود دارد. به عنوان مثال، اگر صفحاتی دارید که از قبل اجرا و ذخیره شده اند، هر یک دارای یک فریم خارجی است که می توان آن را بالاترین فریم نامید.
  • "fenced_frame" : برای استفاده در آینده رزرو شده است.
  • "sub_frame" : معمولا یک iframe است.

می‌توانیم DocumentLifecycle با FrameType ترکیب کنیم و تعیین کنیم که آیا فریم بیرونی‌ترین فریم است یا خیر. به عنوان مثال: tab.documentLifecycle === “active” && frameType === “outermost_frame”

چگونه مشکلات زمان استفاده را با فریم ها حل کنم؟

همانطور که در بالا گفتیم یک فریم میزبان یک سند است و فریم ممکن است به یک سند جدید هدایت شود، اما frameId تغییر نخواهد کرد. وقتی رویدادی را فقط با یک frameId دریافت می‌کنید، این مشکل ایجاد می‌کند. اگر URL قاب را جستجو کنید ممکن است با زمانی که رویداد رخ داده متفاوت باشد، به این مشکل زمان استفاده می گویند.

برای رفع این مشکل، documentIdparentDocumentId ) را معرفی کردیم. اکنون متد webNavigation.getFrame () frameId در صورت ارائه documentId اختیاری می کند. هر زمان که یک فریم پیمایش شود، documentId تغییر می کند.

چگونه می توانم زمان انتقال صفحه را تعیین کنم؟

سیگنال های واضحی برای تعیین زمان انتقال صفحه بین حالت ها وجود دارد.

بیایید به رویدادهای WebNavigation نگاه کنیم.

برای اولین پیمایش هر صفحه، چهار رویداد را به ترتیب فهرست شده در زیر مشاهده خواهید کرد. توجه داشته باشید که این چهار رویداد ممکن است با حالت "prerender" یا "active" بودن DocumentLifecycle رخ دهند.

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

این در نمودار زیر نشان داده شده است که نشان می دهد وقتی صفحه از پیش اجرا شده به صفحه فعال تبدیل می شود، documentId به "xyz" تغییر می کند.

هنگامی که صفحه از پیش اجرا شده به صفحه فعال تبدیل شود، documentId تغییر می کند
هنگامی که صفحه از پیش اجرا شده به صفحه فعال تبدیل شود، documentId تغییر می کند.

هنگامی که یک صفحه از کش برگشت/به جلو یا از قبل اجرا به حالت فعال منتقل می‌شود، سه رویداد دیگر وجود خواهد داشت (اما با "active" DocumentLifecyle ).

onBeforeNavigate
onCommitted
onCompleted

documentId مانند رویدادهای اصلی باقی خواهد ماند. هنگامی که documentId == xyz فعال می شود، در بالا نشان داده شده است. توجه داشته باشید که همان رویدادهای ناوبری فعال می شوند، به جز رویداد onDOMContentLoaded زیرا صفحه قبلاً بارگیری شده است.

اگر نظر یا سؤالی دارید، لطفاً در گروه chromium-extensions بپرسید.