مطالعه موردی: چگونه گوگل با استفاده از انتقال دید، یک تجربه متصل برای حالت هوش مصنوعی جدید خود ایجاد کرد

تاریخ انتشار: 28 اوت 2025

جستجوی گوگل یکی از بزرگترین دسترسی ها را در جهان دارد، بنابراین تغییرات در تجربه کاربری ما می تواند روی میلیاردها کاربر تأثیر بگذارد. ما مدت‌هاست رویای تجربه‌ای از وب را در سر می‌پرورانیم که مدرن‌تر و شبیه به اپلیکیشن‌ها باشد. زمانی که توسعه در حالت هوش مصنوعی شروع شد، می‌خواستیم تجربه‌ای برای کاربران خود ایجاد کنیم که در آن انتقال به حالت هوش مصنوعی از جستجوی استاندارد یکپارچه و متصل بود. هنگامی که ما در مورد انتقال نمای بین اسناد شنیدیم، متوجه شدیم که یک جفت عالی برای این ویژگی است. این مطالعه موردی آنچه را که از افزودن ویژگی انتقال در کنار راه‌اندازی حالت هوش مصنوعی یاد گرفتیم، به اشتراک می‌گذارد.

ضبط جستجو در جستجوی Google، تغییر از نتایج جستجو به حالت هوش مصنوعی. انتقال از انتقال های مشاهده استفاده می کند.

انتقال‌های نمای متقابل اسناد، وقتی نوبت به ابزار مرورگر بومی می‌شود، بازی را تغییر می‌دهد و ما هیجان‌زده هستیم که ببینیم چگونه وب را در آینده شکل می‌دهد.

Browser Support

  • کروم: 126.
  • لبه: 126.
  • فایرفاکس: پشتیبانی نمی شود.
  • سافاری: 18.2.

Source

تغییر وضعیت موجود

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

ما ابتدا این استراتژی بهبود پیشرونده را با کاربران داخلی خود آزمایش کردیم. این بازخورد اولیه را به ما داد که بسیار مثبت بود. بازخوردهای دریافتی همچنین دارای اشکالاتی بودند، از جمله مشکلات عملکرد و تعاملات ناخواسته با سایر ویژگی‌ها مانند همپوشانی زمینه‌های انباشته.

ما متوجه شدیم که این استراتژی موفق بوده است و من معتقدم که در آینده آن را با سایر ویژگی های مرورگر جدید امتحان خواهیم کرد.

مشکلاتی که با آن مواجه شدیم و حل آنها

تأخیر، مسدود کردن رندر و تایمرهای نگهبان

به طور کلی، تأخیر اضافه شده با انتقال نمای MPA برای 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 فعال کنیم. ما به راهی برای فعال یا غیرفعال کردن پویا انتقال نمای متقابل اسناد بسته به این که کاربر با چه ویژگی تعامل داشت نیاز داشتیم. در مورد ما، ما فقط آنها را برای تغییر حالت به و از حالت هوش مصنوعی فعال کردیم. ما این کار را با به‌روزرسانی برنامه‌ریزی ناوبری at-rule بسته به هدفی که روی آن کلیک یا ضربه زده است انجام دادیم.

روشی برای جابجایی view transition at-rule به شرح زیر است:

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;
}

جانک و انیمیشن های ترکیبی

برخی از انیمیشن‌های تولید شده به‌طور خودکار در عناصر شبه انتقال view باعث افت فریم در دستگاه‌های قدیمی‌تر شده و به تجربه تمیز و بدون درز ما آسیب می‌زند. برای بهبود عملکرد انیمیشن‌ها، آنها را با استفاده از تکنیک‌های انیمیشنی که می‌توانند روی کامپوزیتور اجرا شوند، بازنویسی کردیم. ما توانستیم این کار را با بررسی فریم‌های کلیدی انجام دهیم تا ابعاد شبه عناصر قبل و بعد عکس فوری را بدست آوریم و با استفاده از ریاضیات ماتریسی، فریم‌های کلیدی را بر اساس آن بازنویسی کنیم. مثال زیر نحوه گرفتن انیمیشن برای هر شبه عنصر انتقال نمایش را نشان می دهد:

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 به طور پیش فرض به عناصر اضافه کنید. افراد زیادی در جستجوی گوگل کار می کنند. برای جلوگیری از مقادیر view-transition-name تیم ما روی عناصر مغایر با مقادیری که افراد تیم‌های دیگر ممکن است استفاده کنند تنظیم می‌کند، ما از انواع انتقال view استفاده کردیم تا خصوصیت view-transition-name را به صورت مشروط فقط در زمانی که یک نوع انتقال view خاص فعال است اضافه کنیم.

CSS مثال برای افزودن view-transition-name the-element به یک عنصر تنها زمانی که نوع انتقال view از ai-mode فعال است:

html:active-view-transition-type(ai-mode) {
  #target {
    view-transition-name: the-element;
  }
}

هنگامی که این قوانین CSS را برای همه جابجایی های مشاهده خود در نظر گرفتید، سپس می توانید به صورت پویا نوع انتقال نمای فعلی را برای هر مسیریابی در طول رویدادهای pageswap و pagereveal تغییر دهید.

نمونه ای از به روز رسانی نوع انتقال view به 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'],
    );
  }
);

به این ترتیب از تصادم نام‌گذاری جلوگیری می‌کنیم و غیرضروری از عناصری که نیازی به گرفتن عکس فوری به عنوان بخشی از رفتن و برگشتن به حالت هوش مصنوعی ندارند، عکس فوری نمی‌گیریم.

در نهایت، هرگونه مشکل زمینه انباشتگی فقط در طول انتقال view وجود دارد. برای حل این مشکلات، می‌توانیم به جای اینکه خودسرانه شاخص‌های z عناصر اصلی را به دلیل تنها دلیل حل این مشکل در هنگام استفاده از انتقال‌های view، اصلاح کنیم، شاخص‌های z عناصر شبه تولید شده را هدف قرار دهیم.

::view-transition-group(the-element) {
  z-index: 100;
}

بعدش چی

ما برنامه‌هایی برای استفاده از انتقال‌های نمای متقابل اسناد برای جستجوی Google، از جمله ادغام با Navigation API زمانی که در بین مرورگر در دسترس قرار گرفت، داریم. با ما همراه باشید تا ببینیم در نهایت چه چیزی را می سازیم!