تاريخ النشر: 28 أغسطس 2025
يصل "بحث Google" إلى عدد كبير من المستخدمين حول العالم، لذا يمكن أن تؤثر التغييرات التي نجريها على تجربة المستخدم في مليارات الأشخاص. لطالما حلمنا بتجربة ويب أكثر حداثة وتشبه تجربة التطبيقات. عندما بدأنا تطوير وضع البحث بالذكاء الاصطناعي، أردنا أن نقدّم للمستخدمين تجربة سلسة ومتكاملة عند الانتقال من البحث العادي إلى "وضع البحث بالذكاء الاصطناعي". عندما سمعنا عن عمليات الانتقال بين طرق العرض في المستندات، عرفنا أنّها ستكون إضافة مثالية للميزة. توضّح دراسة الحالة هذه ما تعلّمناه عند إضافة ميزة الانتقال إلى جانب إطلاق "وضع AI".
تُحدث عمليات الانتقال بين طرق العرض في المستندات تغييرًا جذريًا عندما يتعلّق الأمر بأدوات المتصفّح الأصلية، ونتطلّع إلى معرفة كيف ستؤثر في الويب في المستقبل.
تغيير الوضع الراهن
يفرض "بحث Google" متطلبات صارمة ومحافظة بشأن توافقه مع المتصفحات. بشكل عام، كان استخدام ميزة تتوفّر بشكل محدود غير مسموح به. بالنسبة إلى انتقالات العرض بين المستندات، تبيّن لنا أنّ استخدام polyfill غير ممكن، والسبب الرئيسي هو عدم توفّر واجهة برمجة تطبيقات لالتقاط لقطات البكسل، كما أنّ استنساخ إطار العرض بالكامل يؤدي إلى حدوث مشاكل كبيرة في الأداء. لذلك، كان استخدام الميزة كتحسين تدريجي هو أفضل طريقة لإطلاقها إلى جانب "وضع AI". بما أنّ الرسوم المتحركة التي تنشئها عمليات الانتقال بين طرق العرض لا تؤثّر بشكل مباشر في وظائف الموقع الإلكتروني، سيتم ببساطة إيقافها للزيارات غير المتوافقة، وهو ما كان يحدث في الإصدار الحالي بدون رسوم متحركة للانتقال.
اختبرنا أولاً استراتيجية التحسين التدريجي هذه مع المستخدمين الداخليين. وقد قدّمت لنا هذه التجربة ملاحظات مبكرة كانت إيجابية بشكل كبير. كشفت الملاحظات التي تلقّيناها أيضًا عن أخطاء، بما في ذلك مشاكل في الأداء وتفاعلات غير مقصودة مع ميزات أخرى، مثل سياقات التراص المتداخلة.
لقد تبيّن لنا أنّ هذه الاستراتيجية ناجحة، وأعتقد أنّنا سنطبّقها على ميزات جديدة أخرى في المتصفّح في المستقبل.
الصعوبات التي واجهناها وكيفية حلّها
وقت الاستجابة وحظر العرض وموقّتات المراقبة
بشكل عام، يكون وقت الاستجابة الإضافي الناتج عن عمليات انتقال العرض في صفحات متعددة ضئيلاً بالنسبة إلى% 99 من حالات الاستخدام، لا سيما على الأجهزة الحديثة. ومع ذلك، يضع "بحث Google" معايير عالية جدًا عندما يتعلّق الأمر بوقت الاستجابة، ونسعى جاهدين إلى توفير تجارب مستخدم تعمل بشكل جيد على جميع الأجهزة. بالنسبة إلينا، حتى بضع أجزاء من الثانية الإضافية مهمة، لذا كان علينا الاستثمار في كيفية تنفيذ عمليات الانتقال بين طرق العرض في المستندات المختلفة بشكلٍ صحيح بدون التأثير سلبًا في تجربة أي مستخدم.
حظر العرض هو أسلوب يتوافق بشكل جيد مع انتقالات العرض بين المستندات. لا يمكن لعناصر اللقطات الزائفة للمستند الوارد عرض المحتوى الذي تم عرضه من قبل. لذلك، لتحريك المحتوى من المستند الوارد، عليك عرض الحظر إلى أن يتم عرض العنصر المستهدف الذي تريد تحريكه. لإجراء ذلك، استخدِم السمة blocking
في HTMLLinkElement
. للحظر أثناء العرض عيوبه، إذ إنّ انتظار عنصر يقع في نهاية شجرة نموذج المستند (DOM) الوارد قد يؤدي إلى حدوث تأخير كبير. كان علينا تحقيق التوازن بين هذه الميزة وعيوبها، لذا لم نعرض الحظر إلا على العناصر التي يتم عرضها في وقت مبكر جدًا من دورة حياة الصفحة.
<!-- Link tag in the <head> of the incoming document -->
<link blocking="render" href="#target-id" rel="expect">
<!-- Element you want to animate in the <body> of the incoming document -->
<div id="target-id">
some content
</div>
في بعض الحالات، لم يكن تحديد العنصر الذي تريد حظر عرض الإعلان عليه بدقة كافيًا. ستظل بعض الأجهزة أو الاتصالات تشهد زيادة في وقت الاستجابة حتى عند حظر العرض على عنصر قريب من بداية شجرة DOM. للتعامل مع هذه الحالات، كتبنا نصًا برمجيًا لموقّت مراقبة لإزالة HTMLLinkElement
بعد انقضاء فترة زمنية معيّنة من أجل فرض إلغاء حظر عرض المستند الوارد.
يمكن إجراء ذلك ببساطة باتّباع الخطوات التالية:
function unblockRendering() {
const renderBlockingElements = document.querySelectorAll(
'link[blocking=render]',
);
for (const element of renderBlockingElements) {
element.remove();
}
}
const timeToUnblockRendering = t - performance.now();
if (timeToUnblockRendering > 0) {
setTimeout(unblockRendering, timeToUnblockRendering);
} else {
unblockRendering();
}
حدود التغطية
المشكلة الأخرى التي واجهناها هي أنّ قاعدة navigation: auto
الخاصة بانتقالات العرض على مستوى المستندات تحدث على مستوى عام داخل المستند. لا تتوفّر طريقة مضمّنة لتحديد نطاق تفعيل انتقالات العرض بين المستندات ليشمل أهداف نقر معيّنة فقط. بما أنّ هذا التغيير كبير جدًا، لم نتمكّن من تفعيل انتقالات العرض بين المستندات على% 100 من عمليات التنقّل على "بحث Google". كان علينا إيجاد طريقة لتفعيل أو إيقاف عمليات الانتقال بين طرق العرض في المستندات بشكل ديناميكي استنادًا إلى الميزة التي يتفاعل معها المستخدم. في حالتنا، فعّلنا هذه الإشعارات فقط عند التبديل من "وضع AI" وإليه. وقد أجرينا ذلك من خلال تعديل قاعدة at-rule الخاصة بالتنقّل آليًا استنادًا إلى العنصر المستهدف الذي تم النقر عليه.
في ما يلي طريقة لتبديل قاعدة @view-transition:
let viewTransitionAtRule: HTMLElement | undefined;
const DISABLED_VIEW_TRANSITION = '@view-transition{navigation:none;}';
const ENABLED_VIEW_TRANSITION = '@view-transition{navigation:auto;}';
function getVtAtRule(): HTMLElement {
if (!viewTransitionAtRule) {
viewTransitionAtRule = document.createElement('style');
document.head.append(viewTransitionAtRule);
}
return viewTransitionAtRule;
}
function disableVt() {
getVtAtRule().textContent = DISABLED_VIEW_TRANSITION;
}
function enableVt() {
getVtAtRule().textContent = ENABLED_VIEW_TRANSITION;
}
الصور المتحركة غير السلسة والمركّبة
تسبّبت بعض الرسوم المتحركة التي يتم إنشاؤها تلقائيًا على العناصر الزائفة لانتقال العرض في حدوث انخفاض في عدد اللقطات على الأجهزة القديمة، ما أضرّ بالتجربة السلسة والنظيفة التي نريد تقديمها للمستخدمين. لتحسين أداء الرسوم المتحركة، أعدنا كتابتها باستخدام تقنيات رسوم متحركة يمكن تشغيلها على برنامج التركيب. وقد تمكّنا من إجراء ذلك من خلال فحص إطارات المفاتيح للحصول على أبعاد العناصر الزائفة للقطات قبل وبعد، واستخدام رياضيات المصفوفات لإعادة كتابة إطارات المفاتيح وفقًا لذلك. يوضّح المثال التالي كيفية الحصول على الصورة المتحركة لكل عنصر زائف من عناصر انتقالات العرض:
const pseudoElement = `::view-transition-group(${name})`;
const animation = document
.getAnimations()
.find(
(animation) =>
(animation.effect as KeyframeEffect)?.pseudoElement === pseudoElement,
);
يمكنك الاطّلاع على مزيد من المعلومات حول كتابة إطارات مفتاحية عالية الأداء لانتقالات العرض في View Transitions Applied: Dealing with the Snapshot Containing Block.
أمور أخرى يجب الانتباه إليها
إحدى المشاكل الأكثر شيوعًا هي أنّ وضع علامات على العناصر باستخدام السمة view-transition-name
في CSS يؤثّر في سياق التراص (مواصفات عمليات الانتقال بين طرق العرض: القسم 2.1.1). كان هذا هو مصدر العديد من الأخطاء التي تطلّبت تعديل z-index
لعناصر الحاوية.
يجب أيضًا الانتباه إلى أنّه قد لا يكون من المناسب إضافة قيم view-transition-name
إلى العناصر تلقائيًا. يعمل عدد كبير من الأشخاص على "بحث Google". لمنع القيم view-transition-name
التي يضبطها فريقنا على العناصر من التعارض مع القيم التي قد يستخدمها أشخاص من فِرق أخرى، استفدنا من أنواع انتقالات العرض لإضافة السمة view-transition-name
بشكلٍ مشروط فقط أثناء نشاط نوع معيّن من انتقالات العرض.
مثال على رمز CSS لإضافة view-transition-name
من the-element
إلى عنصر فقط عندما يكون نوع انتقال العرض ai-mode
نشطًا:
html:active-view-transition-type(ai-mode) {
#target {
view-transition-name: the-element;
}
}
بعد تطبيق قواعد CSS هذه على جميع انتقالات العرض، يمكنك بعد ذلك تغيير نوع انتقال العرض الحالي بشكلٍ ديناميكي لأي عملية تنقّل خلال الحدثَين pageswap
وpagereveal
.
مثال على تعديل نوع انتقال العرض إلى ai-mode
أثناء الحدث pageswap
function updateViewTransitionTypes(
event: ViewTransitionEvent,
types: string[],
): void {
event.viewTransition.types.clear();
for (const type of types) {
event.viewTransition.types.add(type);
}
}
window.addEventListener(
'pageswap',
(e) => {
updateViewTransitionTypes(
e as ViewTransitionEvent,
['ai-mode'],
);
}
);
بهذه الطريقة، نتجنّب تعارض الأسماء ولا نلتقط لقطات غير ضرورية للعناصر التي لا تحتاج إلى لقطات كجزء من الانتقال من "وضع الذكاء الاصطناعي" وإليه.
أخيرًا، لن تظهر أي مشاكل في سياق التراص إلا أثناء انتقال العرض. لحلّ هذه المشاكل، يمكننا بعد ذلك استهداف قيم z-index للعناصر الزائفة التي تم إنشاؤها، بدلاً من تعديل قيم z-index للعناصر الأصلية بشكلٍ عشوائي لغرض وحيد هو حلّ هذه المشكلة عند استخدام عمليات انتقال العرض.
::view-transition-group(the-element) {
z-index: 100;
}
الخطوات التالية
نخطّط لاستخدام عمليات الانتقال بين المشاهد في المستندات في "بحث Google"، بما في ذلك الدمج مع Navigation API بعد أن تصبح متاحة على جميع المتصفّحات. يُرجى متابعة أخبارنا لمعرفة ما سنطرحه في المستقبل.