دعم المتصفح
في بعض الأحيان، تعلّق المتصفحات الحديثة الصفحات أو تتجاهلها تمامًا عندما تقييد موارد النظام. وفي المستقبل، سترغب المتصفحات في إجراء ذلك بشكل استباقي، بحيث تستهلك طاقة وذاكرة أقل. Page Lifecycle API يوفّر عناصر الجذب لمراحل النشاط المختلفة حتى تتمكن صفحاتك من التعامل مع هذه المتصفّحات بأمان. التدخلات دون التأثير على تجربة المستخدم. ألقِ نظرة على واجهة برمجة التطبيقات لمعرفة ما إذا كان عليك تطبيق هذه الميزات في تطبيقك أم لا.
الخلفية
دورة حياة التطبيقات هي الوسيلة الأساسية التي تديرها أنظمة التشغيل الحديثة الموارد. على أجهزة Android وiOS وإصدارات Windows الحديثة، يمكن تشغيل التطبيقات في أي وقت من خلال نظام التشغيل. وهذا يسمح لهذه المنصات بتبسيط إعادة تخصيص الموارد حيث يستفيد المستخدم منها بشكل أفضل.
لم تكن هناك دورة حياة كهذه على الويب في السابق، ويمكن الاحتفاظ بالتطبيقات حياتية إلى أجل غير مسمى. مع تشغيل أعداد كبيرة من صفحات الويب، يتطلب مثل الذاكرة ووحدة المعالجة المركزية (CPU) والبطارية والشبكة (CPU) من الممكن أن يشيع الاشتراك فيها مما يؤدي إلى تجربة سيئة للمستخدم النهائي.
على الرغم من أنّ منصة الويب تستضيف منذ فترة طويلة أحداثًا مرتبطة بحالات مراحل النشاط
— مثل load
unload
و
visibilitychange
— تسمح هذه الأحداث للمطوّرين فقط
للاستجابة للتغييرات في حالة مراحل نشاط المستخدم التي يبدأها المستخدم. لكي يعمل الويب
بشكل موثوق به على الأجهزة منخفضة الطاقة (وأن تكون أكثر وعيًا بالموارد بشكل عام على
على جميع الأنظمة الأساسية) إلى طريقة لاستعادة النظام بشكل استباقي أو إعادة تخصيصه
الموارد.
في الواقع، تتّخذ المتصفّحات اليوم تدابير نشطة للحفاظ على الموارد. للصفحات الموجودة في علامات التبويب في الخلفية، والعديد من المتصفحات (وخاصة Chrome) التي إلى القيام بالكثير من هذا - لتقليل البصمة الكربونية الإجمالية لمواردها.
تكمن المشكلة في أن المطورين ليس لديهم طريقة للاستعداد لهذه الأنواع من التدخلات التي بدأها النظام أو حتى معرفة أنها تحدث. يعني ذلك يجب أن تكون المتصفحات متحفظة أو قد تتعرض لمخاطر تعطُّل صفحات الويب.
Page Lifecycle API لحل هذه المشكلة عن طريق:
- تقديم وتوحيد مفهوم حالات مراحل النشاط على الويب.
- تحديد الحالات الجديدة التي يبدأها النظام والتي تسمح للمتصفحات بتقييد الموارد التي يمكن أن تستهلكها علامات التبويب المخفية أو غير النشطة.
- إنشاء واجهات برمجة تطبيقات وأحداث جديدة تسمح لمطوّري برامج الويب بالاستجابة لها الانتقال من وإلى الحالات الجديدة التي يبدأها النظام.
يوفّر هذا الحل إمكانية التنبؤ التي يحتاج إليها مطوّرو الويب لإنشاء المرونة في التعامل مع تدخلات النظام، وتسمح للمتصفحات بمزيد من تحسين موارد النظام بشكل مكثف، ليفيد جميع مستخدمي الويب في النهاية.
ستتناول بقية هذه المشاركة ميزات "دورة حياة الصفحة" الجديدة واستكشاف كيفية ارتباطها بجميع حالات أنظمة الويب الحالية والفعاليات. كما سيقدم أيضًا توصيات وأفضل الممارسات للأنواع من مطوّري برامج العمل يجب أن يقوموا به (ويجب عدم فعله) في كل ولاية.
نظرة عامة على حالات وأحداث الصفحة
جميع حالات مراحل نشاط الصفحة منفصلة وحصرية، أي أن تكون الصفحة يمكن أن تكون في حالة واحدة فقط في المرة. ومعظم التغييرات التي تطرأ على حالة مراحل نشاط الصفحة يمكن تتبّعها بشكل عام من خلال أحداث نموذج العناصر في المستند (DOM) (اطّلِع على اقتراحات المطوّرين لكل ولاية للاطّلاع على الاستثناءات).
ربما تكون أسهل طريقة لشرح حالات مراحل نشاط الصفحة، وكذلك الأحداث التي تشير إلى الانتقالات بينها — مع رسم تخطيطي:
الولايات
يشرح الجدول التالي كل حالة بالتفصيل. كما تسرد أيضًا المحتملة الحالات التي يمكن أن تأتي قبل وبعد الحدث بالإضافة إلى الأحداث التي يمكن للمطورين استخدامها لمراقبة التغييرات.
الحالة | الوصف |
---|---|
نشِط |
تكون الصفحة بالحالة نشطة إذا كانت مرئية وتتضمن التركيز على الإدخال.
الحالات السابقة المحتمَلة: |
غير نشِطة |
تكون الصفحة في حالة سلبية إذا كانت مرئية وتعمل لا تركز على الإدخال.
الحالات السابقة المحتمَلة:
الحالات التالية المحتمَلة: |
مخفية |
تكون الصفحة بالحالة مخفية إذا لم تكن مرئية (ولم يتم تمييزها تجميدها أو تجاهلها أو إنهاؤها).
الحالات السابقة المحتمَلة:
الحالات التالية المحتمَلة: |
مجمّدة |
في الحالة مجمّدة، يعلّق المتصفح تنفيذ
قابلة للتجميد
المهام في عنوان URL الخاص بالصفحة
قوائم الانتظار الخاصة بالمهام إلى أن يتم إلغاء تجميد الصفحة هذا يعني أشياء مثل
لا يتم تشغيل مؤقتات JavaScript واسترجاع استدعاءات استدعاء الدوال البرمجية. قيد التشغيل
المهام التي يمكن إنجازها (والأهم من ذلك،
توقف المتصفحات الصفحات للحفاظ على استخدام وحدة المعالجة المركزية (CPU)/البطارية/البيانات؛ هم تفعل ذلك أيضًا كطريقة لتفعيل التنقّل للخلف/للأمام — من خلال تجنُّب الحاجة إلى صفحة كاملة إعادة التحميل.
الحالات السابقة المحتمَلة:
الحالات التالية المحتمَلة: |
تم إنهاؤها |
كانت الصفحة بالحالة تم إنهاؤها بعد أن تبدأ إلغاء تحميلها ومحوها من الذاكرة من قبل المتصفح. لا مهام جديدة يمكن أن تبدأ في هذه الحالة، وقد لا تكون المهام الجارية وقتل إذا ركض لفترة طويلة.
الحالات السابقة المحتمَلة:
الحالات التالية المحتمَلة: |
تم التجاهل |
تكون الصفحة بالحالة تم تجاهلها عند إلغاء تحميلها من خلال للحفاظ على الموارد. ما مِن مهام أو استدعاءات للأحداث أو يمكن تشغيل أي نوع من JavaScript في هذه الحالة، إذ إنّ عمليات الإلغاء تتم عادةً في ظل قيود الموارد، حيث يكون بدء عمليات جديدة مستحيل. في علامة التبويب غير مستبعد (بما في ذلك عنوان علامة التبويب والرمز المفضّل) يظهر عادةً للمستخدم بالرغم من إزالة الصفحة.
الحالات السابقة المحتمَلة:
الحالات التالية المحتمَلة: |
فعاليات
تنشر المتصفحات الكثير من الأحداث، ولكن جزءًا صغيرًا منها فقط يشير إلى أي تغيير محتمل في حالة "دورة حياة الصفحة". يوضّح الجدول التالي جميع الأحداث التي تتعلق بدورة الحياة وتسرد الحالات التي قد ينتقلون إليها ومنها.
الاسم | التفاصيل |
---|---|
focus
|
عنصر DOM تم التركيز عليه.
ملاحظة: لا ينطبق حدث
الحالات السابقة المحتمَلة:
الحالات الحالية المحتمَلة: |
blur
|
فقد عنصر DOM تركيزه
ملاحظة: لا ينطبق حدث
الحالات السابقة المحتمَلة:
الحالات الحالية المحتمَلة: |
visibilitychange
|
عنوان المستند
تم تغيير قيمة |
freeze
*
|
تمّ تجميد الصفحة للتو. أي تقييم القابلة للتجميد في قوائم انتظار المهام على الصفحة.
الحالات السابقة المحتمَلة:
الحالات الحالية المحتمَلة: |
resume
*
|
استأنف المتصفح صفحة مجمّدة.
الحالات السابقة المحتمَلة:
الحالات الحالية المحتمَلة: |
pageshow
|
يتم الانتقال إلى إدخال سجلّ جلسة. يمكن أن يكون إما تحميل صفحة جديدة تمامًا أو صفحة مأخوذة من
ميزة "التخزين المؤقت للصفحات" إذا كانت الصفحة
تم أخذه من ميزة "التخزين المؤقت للصفحات" وهي
السمة
الحالات السابقة المحتمَلة: |
pagehide
|
يتم اجتياز إدخال سجل جلسة من. إذا كان المستخدم ينتقل إلى صفحة أخرى وكان المتصفّح قادرًا على إضافة
الصفحة الحالية إلى زر رجوع/إعادة توجيه
cache لإعادة استخدامها لاحقًا، وهي سمة
الحالات السابقة المحتمَلة:
الحالات الحالية المحتمَلة: |
beforeunload
|
أنت على وشك إلغاء تحميل النافذة والمستند وموارده. لا يزال المستند مرئيًا ولا يزال الحدث قابلاً للإلغاء في الوقت الحالي. نقطة واحدة.
ملاحظة مهمة: حدث
الحالات السابقة المحتمَلة:
الحالات الحالية المحتمَلة: |
unload
|
يتم الآن إلغاء تحميل الصفحة.
تحذير:
ولا يوصى أبدًا باستخدام حدث
الحالات السابقة المحتمَلة:
الحالات الحالية المحتمَلة: |
يشير الرمز * إلى حدث جديد تم تحديده من خلال Page Lifecycle API.
الميزات الجديدة المُضافة في الإصدار 68 من Chrome
يعرض الرسم البياني السابق حالتين يبدأ تشغيلهما من خلال النظام وليس بدء التشغيل من قِبل المستخدم: تم تجميده وتجاهله كما ذكرنا سابقًا، يتم تجميد المتصفحات حاليًا وتجاهلها من حين لآخر (حسب تقديرهم)، إلا أن المطورين لا يستطيعون معرفة وقت هذا يحدث.
في Chrome 68، يمكن للمطوّرين الآن ملاحظة متى يتم تجميد علامة تبويب مخفية
إلغاء التجميد من خلال الاستماع إلى freeze
وresume
من الأحداث في document
.
document.addEventListener('freeze', (event) => {
// The page is now frozen.
});
document.addEventListener('resume', (event) => {
// The page has been unfrozen.
});
من Chrome 68، يشمل الكائن document
الآن
wasDiscarded
على Chrome لأجهزة الكمبيوتر المكتبي (يتم تتبُّع دعم Android في هذه المشكلة). لتحديد ما إذا كان قد تم تجاهل صفحة أثناء إخفاء الصفحة
يمكنك فحص قيمة هذه السمة في وقت تحميل الصفحة (ملاحظة:
ويجب إعادة تحميل الصفحات التي تم تجاهلها لاستخدامها مرة أخرى).
if (document.wasDiscarded) {
// Page was previously discarded by the browser while in a hidden tab.
}
للحصول على نصائح بشأن النشاطات المهمة التي يتم تنفيذها في freeze
وresume
الأحداث، فضلاً عن كيفية التعامل مع الصفحات التي يتم تجاهلها والاستعداد لها، راجع
اقتراحات للمطوّرين في كل ولاية
تقدم الأقسام المتعددة التالية نظرة عامة على كيفية ملاءمة هذه الميزات الجديدة حالات وأحداث منصة الويب الحالية.
كيفية مراقبة حالات مراحل نشاط الصفحة في الرمز
في العناصر النشطة والسلبية والمخفية من الممكن تشغيل رمز JavaScript الذي يحدد حالة مراحل نشاط الصفحة من واجهات برمجة التطبيقات الحالية للنظام الأساسي على الويب
const getState = () => {
if (document.visibilityState === 'hidden') {
return 'hidden';
}
if (document.hasFocus()) {
return 'active';
}
return 'passive';
};
الحالة مجمّدة ومنتهية، في
من ناحية أخرى، لا يمكن رصدها إلا من خلال أداة معالجة الأحداث المعنية
(freeze
وpagehide
) حسب الولاية
المتغير.
كيفية مراقبة تغييرات الحالة
بناءً على الدالة getState()
المحددة سابقًا، يمكنك متابعة جميع الصفحات
تتغير حالة دورة الحياة مع الرمز التالي.
// Stores the initial state using the `getState()` function (defined above).
let state = getState();
// Accepts a next state and, if there's been a state change, logs the
// change to the console. It also updates the `state` value defined above.
const logStateChange = (nextState) => {
const prevState = state;
if (nextState !== prevState) {
console.log(`State change: ${prevState} >>> ${nextState}`);
state = nextState;
}
};
// Options used for all event listeners.
const opts = {capture: true};
// These lifecycle events can all use the same listener to observe state
// changes (they call the `getState()` function to determine the next state).
['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'].forEach((type) => {
window.addEventListener(type, () => logStateChange(getState()), opts);
});
// The next two listeners, on the other hand, can determine the next
// state from the event itself.
window.addEventListener('freeze', () => {
// In the freeze event, the next state is always frozen.
logStateChange('frozen');
}, opts);
window.addEventListener('pagehide', (event) => {
// If the event's persisted property is `true` the page is about
// to enter the back/forward cache, which is also in the frozen state.
// If the event's persisted property is not `true` the page is
// about to be unloaded.
logStateChange(event.persisted ? 'frozen' : 'terminated');
}, opts);
تقوم هذه التعليمة البرمجية بثلاثة أشياء:
- تحدد الحالة الأولية باستخدام الدالة
getState()
. - تحدد الدالة التي تقبل الحالة التالية، وإذا كان هناك تغيير، بتسجيل تغييرات الحالة في وحدة التحكم.
- إضافة
التقاط
أدوات معالجة الأحداث لجميع الأحداث الضرورية في مراحلها، والتي بدورها
logStateChange()
، مرورًا في الولاية التالية.
هناك شيء واحد يجب ملاحظته بشأن التعليمة البرمجية وهو أنه تتم إضافة جميع أدوات معالجة الأحداث
إلى window
ويمررون جميعًا
{capture: true}
وهناك بضعة أسباب لذلك:
- لا تتطابق جميع أحداث "مراحل نشاط الصفحة" مع الهدف نفسه.
pagehide
، يتم تنشيطpageshow
فيwindow
.visibilitychange
وfreeze
يتم إطلاقresume
فيdocument
، وfocus
وblur
على عناصر DOM المعنية. - معظم هذه الأحداث لا تظهر كفقاعات، مما يعني أنه من المستحيل إضافتها أدوات معالجة الأحداث التي لا يتم التقاطها لعنصر أصل مشترك ومراقبة جميع منها.
- يتم تنفيذ مرحلة الالتقاط قبل مرحلتي الهدف أو الفقاعة التفسيرية، وبالتالي المستمعين هناك يساعد في ضمان تشغيلها قبل أن تتمكن التعليمات البرمجية الأخرى من إلغائها.
اقتراحات المطوّرين في كل ولاية
من المهم، كمطوّرين، فهم حالات مراحل نشاط الصفحة و معرفة كيفية ملاحظتها في التعليمات البرمجية لأن نوع العمل الذي ينبغي عليك (ويجب لا) يعتمد على الحالة التي تكون فيها صفحتك.
على سبيل المثال، ليس من المنطقي عرض إشعار عابر. للمستخدم إذا كانت الصفحة في حالة مخفية. في حين أن هذا المثال رائع هناك توصيات أخرى ليست واضحة جدًا وتستحق للتعداد.
الحالة | اقتراحات المطوّرين |
---|---|
Active |
إنّ الحالة نشط هي الفترة الأكثر أهمية بالنسبة إلى المستخدم، وبالتالي الوقت الأهم بالنسبة إلى صفحتك الاستجابة لإدخال المستخدم. يجب عدم منح الأولوية لأي أعمال غير مرتبطة بواجهة المستخدم وقد تحظر سلسلة التعليمات الرئيسية. إلى فترات عدم النشاط أو إلى عامل على الويب. |
Passive |
في الحالة السلبية التي لا يتفاعل فيها المستخدم مع الصفحة: ولكن لا يزال بإمكانهم رؤيته. هذا يعني أن تحديثات واجهة المستخدم والرسوم المتحركة يجب أن تظل بسلاسة، ولكن توقيت حدوث هذه التحديثات أقل أهمية. عندما تتغير الصفحة من نشطة إلى سلبية، هو الوقت المناسب للحفاظ على حالة التطبيق غير المحفوظة. |
عندما تتغير الصفحة من سلبية إلى مخفية، من المحتمل ألا يتفاعل المستخدم معها مرة أخرى إلى أن تتم إعادة تحميلها. عند الانتقال إلى مخفي، يكون أيضًا في أغلب الأحيان آخر تغيير في الحالة.
وهو ما يمكن للمطورين ملاحظته بشكل موثوق (وهذا ينطبق بشكل خاص على
الجوّال، حيث يمكن للمستخدمين إغلاق علامات التبويب أو تطبيق المتصفح نفسه
وهذا يعني أنّه عليك التعامل مع الحالة مخفي على أنّها النهاية المحتمَلة لعلامة التبويب. جلسة المستخدم. بمعنى آخر، الاحتفاظ بأي حالات غير محفوظة للتطبيق وإرسال أيّ بيانات إحصاءات لم يتمّ إرسالها يجب عليك أيضًا إيقاف إجراء تحديثات واجهة المستخدم (بما أنه لن يتم رؤيتها) من قبل المستخدم)، ويجب عليك إيقاف أي مهام لا يريدها قيد التشغيل في الخلفية. |
|
Frozen |
في الحالة مجمّدة، المهام القابلة للتجميد في قوائم الانتظار الخاصة بالمهام يتم تعليقها إلى أن يتم إلغاء تجميد الصفحة، ما قد يؤدي إلى لا تحدث أبدًا (على سبيل المثال، إذا تم تجاهل الصفحة). يعني ذلك عندما تتغير الصفحة من مخفية إلى مجمّدة. عليك إيقاف أي مؤقتات أو قطع أي اتصالات إذا تم تجميدها، أو قد يؤثر على علامات التبويب المفتوحة الأخرى في نفس المصدر، أو يؤثر في قدرة المتصفح على وضع الصفحة في ميزة "التخزين المؤقت للصفحات" وعلى وجه الخصوص، من المهم أن:
عليك أيضًا الاحتفاظ بأي حالة عرض ديناميكي (مثل موضع التمرير).
في عرض قائمة لانهائي) إلى
إذا انتقلت الصفحة من مجمّدة إلى مخفية، يجب اتّباع الخطوات التالية: يمكنك إعادة فتح أي اتصالات مغلقة أو إعادة بدء أي استطلاع عندما تم تجميد الصفحة في البداية. |
Terminated |
لا تحتاج بشكل عام إلى اتخاذ أي إجراء عند انتقال صفحة إلى الحالة تم الإنهاء. بما أنّ الصفحات التي يتم إلغاء تحميلها نتيجة إجراء المستخدم يتم دائمًا من خلال الحالة مخفية قبل إدخال الحالة تم الإنهاء الحالة المخفية هي منطق إنهاء الجلسة (على سبيل المثال، استمرار حالة التطبيق وتقديم التقارير إلى التحليلات) تنفيذها. أيضًا (كما هو مذكور في توصيات
الحالة المخفية)، من المهم جدًا أن يدرك المطوّرون
أن الانتقال إلى الحالة تم إنهاؤه لا يمكن الوثوق به
يتم اكتشافها في العديد من الحالات (خاصةً على الأجهزة الجوّالة)، ولذا فإن المطورين الذين يعتمدون
عند حدوث أحداث إغلاق (مثل |
Discarded |
لا يمكن لمطوّري البرامج في الموقع الإلكتروني تتبّع الحالة تم تجاهلها. مرة يتم فيها تجاهل الصفحة. وذلك لأن الصفحات يتم عادةً يتم تجاهلها بموجب قيود الموارد، وإلغاء تجميد الصفحة فقط للسماح أن يتم تنفيذ نص برمجي استجابةً لحدث تجاهل في معظم الحالات. ونتيجة لذلك، يجب أن تستعد لاحتمال تجاهل
التغيير من مخفي إلى مجمّد، وبعد ذلك يمكنك
التفاعل مع استعادة الصفحة التي تم تجاهلها في وقت تحميل الصفحة من خلال
التحقق من |
مرة أخرى، بما أن موثوقية وترتيب أحداث مراحل الحياة ليست تطبيقها باستمرار في جميع المتصفحات، فهي أسهل طريقة لاتباع النصائح في الجدول وهي استخدام PageLifecycle.js.
واجهات برمجة التطبيقات القديمة التي يجب تجنُّبها لمراحل النشاط
يجب تجنب الأحداث التالية متى أمكن ذلك.
حدث "إلغاء التحميل"
يتعامل العديد من مطوّري البرامج مع حدث unload
على أنّه معاودة الاتصال مضمونة ويستخدمه على أنّه
إشارة نهاية الجلسة لحفظ الحالة وإرسال بيانات التحليلات، ولكن القيام بذلك
غير موثوق به للغاية، لا سيما على الأجهزة الجوّالة. الحدث unload
ليس
تنشيطها في العديد من حالات إلغاء التحميل المعتادة، بما في ذلك إغلاق علامة تبويب من علامة التبويب
على جهاز الجوّال، أو إغلاق تطبيق المتصفح من مبدل التطبيقات.
لهذا السبب، من الأفضل دائمًا الاعتماد على
visibilitychange
لتحديد وقت الجلسة
وتنتهي، ونأخذ في الاعتبار الحالة المخفية
آخر وقت موثوق فيه لحفظ بيانات التطبيقات والمستخدمين.
بالإضافة إلى ذلك، إنّ مجرد توفُّر معالج أحداث unload
مسجَّل (عبر
إما onunload
أو addEventListener()
) يمكن أن تمنع المتصفحات من
لوضع الصفحات في ميزة "التخزين المؤقت للصفحات" لإجراء عمليات شراء أسرع.
عمليات التحميل للخلف وللأمام.
يُوصى في جميع المتصفحات الحديثة باستخدام
حدث pagehide
لرصد عمليات التحميل المحتملة للصفحات (تُعرف أيضًا باسم
تم الإنهاء) بدلاً من حدث unload
. إذا كنت
إلى دعم الإصدار 10 والإصدارات الأقدم من Internet Explorer، فينبغي عليك عرض
رصد حدث pagehide
واستخدام unload
فقط في حال لم يكن المتصفّح متوافقًا
pagehide
:
const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
window.addEventListener(terminationEvent, (event) => {
// Note: if the browser is able to cache the page, `event.persisted`
// is `true`, and the state is frozen rather than terminated.
});
حدث beforeunload
يواجه الحدث beforeunload
مشكلة مشابهة للفعالية unload
، أي في ما يلي:
في السابق، قد يؤدي وجود حدث beforeunload
إلى منع الصفحات من
التأهُّل لاستخدام ميزة التخزين المؤقت للصفحات المتصفّحات الحديثة
لا تفرض هذا القيد. على الرغم من أنه لن يتم إطلاق بعض المتصفحات كإجراء احترازي
حدث "beforeunload
" عند محاولة وضع صفحة في ميزة الرجوع إلى الصفحة السابقة أو إعادة التوجيه
ذاكرة التخزين المؤقت، ما يعني أنّ الحدث لا يمكن الاعتماد عليه كإشارة لنهاية الجلسة.
بالإضافة إلى ذلك، هناك بعض المتصفحات (بما في ذلك Chrome)
تتطلّب إجراء تفاعل من المستخدم على الصفحة قبل السماح بحدث beforeunload
إطلاقها، مما يؤثر بشكل أكبر على موثوقيتها.
هناك فرق واحد بين beforeunload
وunload
هو
الاستخدامات المشروعة لـ beforeunload
. على سبيل المثال، عندما تريد تحذير المستخدم
بأن لديهم تغييرات لم يتم حفظها، فسيفقدون إذا تابعوا إلغاء تحميل الصفحة.
بما أنّ هناك أسبابًا وجيهة لاستخدام beforeunload
، ننصحك
يمكنك فقط إضافة مستمعي beforeunload
عندما يكون لدى المستخدم تغييرات لم يتم حفظها، ثم
وإزالتها فورًا بعد حفظها.
بمعنى آخر، لا تستخدم هذه الطريقة (لأنّها تضيف أداة استماع إلى beforeunload
بلا شروط):
addEventListener('beforeunload', (event) => {
// A function that returns `true` if the page has unsaved changes.
if (pageHasUnsavedChanges()) {
event.preventDefault();
// Legacy support for older browsers.
return (event.returnValue = true);
}
});
يمكنك بدلاً من ذلك استخدام هذه الطريقة (لأنّها تضيف أداة استماع beforeunload
فقط عندما تكون
وإزالة تلك البيانات في حال عدم توفّرها):
const beforeUnloadListener = (event) => {
event.preventDefault();
// Legacy support for older browsers.
return (event.returnValue = true);
};
// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
addEventListener('beforeunload', beforeUnloadListener);
});
// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
removeEventListener('beforeunload', beforeUnloadListener);
});
الأسئلة الشائعة
لماذا لا يتم تحميل المحتوى؟ أو الولاية؟
تحدد واجهة برمجة التطبيقات Page Lifecycle API الحالات التي تكون منفصلة وحصرية. ونظرًا لأنه يمكن تحميل إحدى الصفحات في حالة نشطة أو سلبية أو مخفية، ونظرًا لإمكانية تغيير الحالات - أو حتى إنهائها - قبل أن ينتهي التحميل، تصبح حالة التحميل المنفصلة ذات مغزى ضمن هذا النموذج.
تعمل صفحتي بشكل مهم عندما تكون مخفية، كيف يمكنني منع تجميدها أو تجاهلها؟
هناك الكثير من الأسباب المشروعة لعدم تجميد صفحات الويب أثناء تشغيلها في حالة الإخفاء. وخير مثال على ذلك هو التطبيق الذي يشغِّل الموسيقى.
هناك أيضًا مواقف قد يعرّض فيها Chrome الصفحة للخطر،
مثل ما إذا كان يحتوي على نموذج يحتوي على بيانات إدخال مستخدم لم يتم إرسالها، أو إذا كان يحتوي على
معالج beforeunload
الذي يحذّر عند إلغاء تحميل الصفحة
في الوقت الحالي، سيكون Chrome متحفظًا عند تجاهل الصفحات لا تفعل ذلك إلا عندما تكون واثقة من عدم تأثيرها على المستخدمين. على سبيل المثال، الصفحات التي إجراء أي مما يلي أثناء التواجد في الحالة المخفية تجاهلها ما لم تكن في ظل قيود شديدة على الموارد:
- يتم تشغيل الصوت
- استخدام WebRTC
- تعديل عنوان الجدول أو رمزه المفضّل
- عرض التنبيهات
- إرسال إشعارات فورية
بالنسبة إلى ميزات القائمة الحالية المستخدمة لتحديد ما إذا كان من الممكن أن تكون علامة التبويب آمنة تم تجميدها أو تجاهلها، راجع: إرشادات للتجميد جارٍ التجاهل في متصفح Chrome.
ما هي ميزة "التخزين المؤقت للصفحات"؟
التخزين المؤقت للصفحات عبارة عن مصطلح يستخدم لوصف تحسين التنقل الذي تنفذه بعض المتصفحات وهو ما يجعل استخدام الرجوع إعادة توجيه الأزرار بشكل أسرع
عندما ينتقل المستخدم بعيدًا عن الصفحة، تعمل هذه المتصفحات على تجميد نسخة من تلك الصفحة
بحيث يمكن استئنافها بسرعة في حالة عودة المستخدم مرة أخرى باستخدام
زر الرجوع أو للأمام. يُرجى العِلم أنّ إضافة unload
معالج الحدث يمنع هذا التحسين من الممكن.
بالنسبة لجميع الأهداف والأغراض، فإن هذا التجميد هو نفسه من الناحية الوظيفية أداء المتصفحات المتجمدة للحفاظ على وحدة المعالجة المركزية/البطارية؛ لهذا السبب من تعتبر جزءًا من حالة دورة الحياة المجمّدة.
إذا لم أتمكّن من تشغيل واجهات برمجة التطبيقات غير المتزامنة في الحالة المجمدة أو المكتملة، كيف يمكنني حفظ البيانات في IndexedDB؟
في الحالات المجمدة والمنتهية، مهام قابلة للتجميد في قوائم انتظار المهام الخاصة بالصفحة ما يعني أن واجهات برمجة التطبيقات غير المتزامنة والمستندة إلى معاودة الاتصال مثل IndexedDB لا يمكن الاعتماد عليها بشكل موثوق.
وفي المستقبل، سنضيف طريقة commit()
إلى عناصر IDBTransaction
، ما سيؤدي إلى
توفّر للمطورين وسيلة لتنفيذ ما يمكن اعتباره معاملات للكتابة فقط
التي لا تتطلب معاودة الاتصال. بعبارة أخرى، إذا كان المطور يكتب فقط
البيانات إلى IndexedDB ولا يتم إجراء معاملة معقدة تتكون من عمليات قراءة
وتكتب هذه الطريقة، ستتمكّن الطريقة commit()
من الإنهاء قبل إعداد قوائم الانتظار الخاصة بالمهام.
تم تعليقه (بافتراض أن قاعدة بيانات IndexedDB مفتوحة بالفعل).
بالنسبة إلى الرموز البرمجية التي يجب أن تعمل في الوقت الحالي، لدى المطوّرين خيارَين:
- استخدام مساحة تخزين الجلسة: مساحة تخزين الجلسة متزامن ويستمر عبر عمليات تجاهل الصفحات.
- استخدام IndexedDB من مشغّل الخدمات: يمكن لمشغِّل الخدمات تخزين البيانات في
IndexedDB بعد إنهاء الصفحة أو تجاهلها. في
freeze
أو أداة معالجة الأحداثpagehide
، يمكنك إرسال البيانات إلى مشغّل الخدمات من خلالpostMessage()
، ويمكن لعامل الخدمة التعامل مع حفظ البيانات.
اختبار تطبيقك في حالتَي التجميد أو التجاهُل
لاختبار أداء تطبيقك في حالتَي الحالة "مجمّدة" و"تم تجاهلها"، يمكنك الانتقال إلى
chrome://discards
لتجميد أو تجاهل أي من
علامات التبويب المفتوحة.
![يتجاهل Chrome واجهة المستخدم](https://developer.chrome.google.cn/static/docs/web-platform/page-lifecycle-api/image/chrome-discards-ui-4c0620d6f8619.png?authuser=5&hl=ar)
يتيح لك ذلك التأكّد من أنّ صفحتك تتعامل مع freeze
وresume
بشكل صحيح.
الأحداث بالإضافة إلى علامة document.wasDiscarded
عند إعادة تحميل الصفحات بعد
تجاهل.
ملخّص
المطوِّرون الذين يريدون احترام موارد النظام الخاصة بأجهزة المستخدمين إنشاء تطبيقاتهم مع وضع حالات دورة حياة الصفحة في الاعتبار. من الضروري أن أن صفحات الويب لا تستهلك موارد النظام بشكل مفرط في الحالات التي لا يتوقع المستخدم
كلما بدأ المزيد من المطورين في تنفيذ واجهات برمجة التطبيقات الجديدة لمراحل نشاط الصفحة، زادت الأمان السماح للمتصفحات بتجميد وتجاهل الصفحات التي لا يتم استخدامها. هذا النمط يعني أن المتصفحات ستستهلك موارد الشبكة ووحدة المعالجة المركزية (CPU) والبطارية والشبكة وهو مكسب للمستخدمين.