কিভাবে Google তার নতুন এআই মোডের জন্য ভিউ ট্রানজিশন ব্যবহার করে একটি সংযুক্ত অভিজ্ঞতা তৈরি করেছে

প্রকাশিত: ২৮ আগস্ট, ২০২৫

গুগল সার্চের ব্যবহারকারীর সংখ্যা বিশ্বে অন্যতম বৃহত্তম, তাই আমাদের ব্যবহারকারীর অভিজ্ঞতায় কোনো পরিবর্তন আনলে তা কোটি কোটি ব্যবহারকারীর উপর প্রভাব ফেলতে পারে। আমরা দীর্ঘদিন ধরে এমন একটি ওয়েব অভিজ্ঞতার স্বপ্ন দেখে আসছি যা আরও আধুনিক এবং অ্যাপের মতো অনুভূতি দেবে। যখন এআই মোড (AI Mode)-এর কাজ শুরু হয়, আমরা আমাদের ব্যবহারকারীদের জন্য এমন একটি অভিজ্ঞতা তৈরি করতে চেয়েছিলাম যেখানে সাধারণ সার্চ থেকে এআই মোডে প্রবেশ করাটা হবে নির্বিঘ্ন এবং সংযুক্ত। যখন আমরা ক্রস-ডকুমেন্ট ভিউ ট্রানজিশন সম্পর্কে শুনলাম, আমরা বুঝতে পারলাম যে এই ফিচারটির জন্য এটি একটি নিখুঁত সংযোজন। এই কেস স্টাডিতে তুলে ধরা হয়েছে, এআই মোড চালুর পাশাপাশি এই ট্রানজিশন ফিচারটি যুক্ত করে আমরা কী শিখেছি।

গুগল সার্চের মাধ্যমে করা একটি অনুসন্ধানের রেকর্ডিং, যেখানে অনুসন্ধানের ফলাফল থেকে এআই মোডে পরিবর্তন করা হচ্ছে। এই রূপান্তরটি ভিউ ট্রানজিশন ব্যবহার করে করা হচ্ছে।

নেটিভ ব্রাউজার টুলিংয়ের ক্ষেত্রে ক্রস-ডকুমেন্ট ভিউ ট্রানজিশন একটি যুগান্তকারী পরিবর্তন এবং এটি ভবিষ্যতে ওয়েবকে কীভাবে রূপ দেবে তা দেখার জন্য আমরা অধীর আগ্রহে অপেক্ষা করছি।

Browser Support

  • ক্রোম: ১২৬।
  • প্রান্ত: ১২৬।
  • ফায়ারফক্স সমর্থিত নয়।
  • সাফারি: ১৮.২।

Source

স্থিতাবস্থা পরিবর্তন করা

গুগল সার্চের ব্রাউজার সাপোর্টের জন্য কঠোর এবং রক্ষণশীল শর্তাবলী রয়েছে। সাধারণত, সীমিত প্রাপ্যতার কোনো ফিচার ব্যবহার করা নিষিদ্ধ ছিল। ক্রস-ডকুমেন্ট ভিউ ট্রানজিশনের ক্ষেত্রে আমরা দেখেছি যে একটি পলিফিল টেকসই ছিল না, যার প্রধান প্রতিবন্ধকতা ছিল কোনো পিক্সেল স্ন্যাপশটিং এপিআই না থাকা এবং পুরো ভিউপোর্ট ক্লোন করার ফলে পারফরম্যান্সে বড় ধরনের সমস্যা তৈরি হওয়া। তাই, এআই মোডের পাশাপাশি ফিচারটিকে একটি প্রগ্রেসিভ এনহ্যান্সমেন্ট হিসেবে চালু করাই ছিল সর্বোত্তম উপায়। যেহেতু ভিউ ট্রানজিশনের মাধ্যমে তৈরি অ্যানিমেশনগুলো ওয়েবসাইটের কার্যকারিতাকে সরাসরি প্রভাবিত করে না, তাই অসমর্থিত ট্র্যাফিকের জন্য এগুলো নিষ্ক্রিয় করে দেওয়া হতো, যা ট্রানজিশন অ্যানিমেশন ছাড়াই বর্তমান প্রোডাকশন স্টেট ছিল।

আমরা প্রথমে আমাদের অভ্যন্তরীণ ব্যবহারকারীদের সাথে এই প্রগতিশীল উন্নয়ন কৌশলটি পরীক্ষা করেছিলাম। এর মাধ্যমে আমরা প্রাথমিক প্রতিক্রিয়া পাই, যা ছিল অত্যন্ত ইতিবাচক। প্রাপ্ত প্রতিক্রিয়ার মধ্যে কিছু বাগও উঠে আসে, যার মধ্যে ছিল পারফরম্যান্স সংক্রান্ত সমস্যা এবং অন্যান্য ফিচারের সাথে অনাকাঙ্ক্ষিত মিথস্ক্রিয়া, যেমন—ওভারল্যাপিং স্ট্যাকিং কনটেক্সট।

আমরা এই কৌশলটিকে সফল বলে মনে করেছি এবং আমার বিশ্বাস, ভবিষ্যতে আমরা ব্রাউজারের অন্যান্য নতুন ফিচারের ক্ষেত্রেও এটি প্রয়োগ করে দেখব।

আমরা যে অসুবিধাগুলোর সম্মুখীন হয়েছিলাম এবং সেগুলোর সমাধান।

লেটেন্সি, রেন্ডার ব্লকিং, এবং ওয়াচডগ টাইমার

সামগ্রিকভাবে, ৯৯% ব্যবহারের ক্ষেত্রে, বিশেষ করে আধুনিক হার্ডওয়্যারে, এমপিএ ভিউ ট্রানজিশনের কারণে যে অতিরিক্ত ল্যাটেন্সি হয় তা নগণ্য। তবে, ল্যাটেন্সির ক্ষেত্রে গুগল সার্চের মানদণ্ড অত্যন্ত উঁচু এবং আমরা এমন ইউজার এক্সপেরিয়েন্স তৈরি করার চেষ্টা করি যা সব ডিভাইসে ভালোভাবে কাজ করে। আমাদের জন্য, এমনকি কয়েক মিলিসেকেন্ড অতিরিক্ত সময়ও গুরুত্বপূর্ণ, তাই কারও ইউজার এক্সপেরিয়েন্সের ক্ষতি না করে কীভাবে ক্রস-ডকুমেন্ট ভিউ ট্রানজিশন সঠিকভাবে প্রয়োগ করা যায়, সে বিষয়ে আমাদের বিনিয়োগ করতে হয়েছে।

রেন্ডার ব্লকিং এমন একটি কৌশল যা ক্রস-ডকুমেন্ট ভিউ ট্রানজিশনের সাথে ভালোভাবে কাজ করে। আগত ডকুমেন্টের সিউডো-এলিমেন্ট স্ন্যাপশটগুলো শুধুমাত্র সেইসব কন্টেন্টই প্রদর্শন করতে পারে যা ইতিমধ্যে রেন্ডার করা হয়েছে। তাই, আগত ডকুমেন্ট থেকে কন্টেন্ট অ্যানিমেট করার জন্য, আপনি যে টার্গেট এলিমেন্টটি অ্যানিমেট করতে চান সেটি রেন্ডার না হওয়া পর্যন্ত আপনাকে রেন্ডার ব্লক করে রাখতে হবে। এটি করার জন্য একটি HTMLLinkElement এ blocking অ্যাট্রিবিউট ব্যবহার করুন। রেন্ডার ব্লকিংয়ের কিছু অসুবিধাও রয়েছে, যেমন আগত ডকুমেন্টের 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();
}

কভারেজের সীমাবদ্ধতা

আমরা আরেকটি সমস্যার সম্মুখীন হয়েছিলাম, তা হলো ক্রস-ডকুমেন্ট ভিউ ট্রানজিশনের 'at-rule navigation: auto ডকুমেন্টের মধ্যে একটি গ্লোবাল লেভেলে ঘটে। শুধুমাত্র নির্দিষ্ট ক্লিক টার্গেটের জন্য ক্রস-ডকুমেন্ট ভিউ ট্রানজিশন চালু করার কোনো বিল্ট-ইন উপায় নেই। যেহেতু এটি একটি অনেক বড় পরিবর্তন, তাই আমরা গুগল সার্চের ১০০% নেভিগেশনে ক্রস-ডকুমেন্ট ভিউ ট্রানজিশন চালু করতে পারিনি। ব্যবহারকারী কোন ফিচারের সাথে ইন্টারঅ্যাক্ট করছেন তার উপর নির্ভর করে ক্রস-ডকুমেন্ট ভিউ ট্রানজিশন ডাইনামিকভাবে চালু বা বন্ধ করার একটি উপায় আমাদের প্রয়োজন ছিল। আমাদের ক্ষেত্রে, আমরা শুধুমাত্র এআই মোডে যাওয়া-আসার সময় এগুলো চালু করেছিলাম। কোন টার্গেটে ক্লিক বা ট্যাপ করা হয়েছে তার উপর ভিত্তি করে প্রোগ্রাম্যাটিকভাবে 'navigation 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;
}

জ্যাঙ্ক এবং কম্পোজিটেড অ্যানিমেশন

ভিউ ট্রানজিশন সিউডো-এলিমেন্টগুলিতে স্বয়ংক্রিয়ভাবে তৈরি হওয়া কিছু অ্যানিমেশন পুরোনো ডিভাইসগুলিতে ফ্রেম ড্রপের কারণ হচ্ছিল, যা ব্যবহারকারীদের আমরা যে পরিচ্ছন্ন ও নির্বিঘ্ন অভিজ্ঞতা দিতে চাই তা ব্যাহত করছিল। অ্যানিমেশনগুলির পারফরম্যান্স উন্নত করার জন্য, আমরা কম্পোজিটরে চলতে পারে এমন অ্যানিমেশন কৌশল ব্যবহার করে সেগুলিকে নতুন করে লিখেছি। আমরা কীফ্রেমগুলি পরীক্ষা করে আগের ও পরের স্ন্যাপশট সিউডো-এলিমেন্টগুলির ডাইমেনশন বের করে এবং সেই অনুযায়ী কীফ্রেমগুলি নতুন করে লেখার জন্য ম্যাট্রিক্স ম্যাথ ব্যবহার করে এটি করতে সক্ষম হয়েছি। নিম্নলিখিত উদাহরণটি দেখায় কিভাবে প্রতিটি ভিউ ট্রানজিশন সিউডো-এলিমেন্টের জন্য অ্যানিমেশনটি সংগ্রহ করতে হয়:

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 প্রপার্টি দিয়ে এলিমেন্ট ট্যাগ করলে তা স্ট্যাকিং কনটেক্সটকে প্রভাবিত করে ( ভিউ ট্রানজিশন স্পেসিফিকেশন: সেকশন ২.১.১ )। এর ফলেই একাধিক বাগ দেখা দেয়, যার জন্য কন্টেইনার এলিমেন্টগুলোর z-index পরিবর্তন করার প্রয়োজন হয়েছিল।

আরেকটি বিষয় মনে রাখতে হবে যে, আপনি হয়তো ডিফল্টভাবে এলিমেন্টগুলোতে view-transition-name ভ্যালু যোগ করতে চাইবেন না। গুগল সার্চে অনেক লোক কাজ করে। আমাদের টিম এলিমেন্টগুলোতে যে view-transition-name ভ্যালু সেট করে, তা যেন অন্য টিমের সদস্যদের ব্যবহৃত ভ্যালুর সাথে সাংঘর্ষিক না হয়, সেজন্য আমরা ভিউ ট্রানজিশন টাইপ ব্যবহার করেছি। এর মাধ্যমে শুধুমাত্র একটি নির্দিষ্ট ভিউ ট্রানজিশন টাইপ সক্রিয় থাকাকালীন শর্তসাপেক্ষে view-transition-name প্রপার্টিটি যোগ করা হয়।

শুধুমাত্র যখন ai-mode ভিউ ট্রানজিশন টাইপটি সক্রিয় থাকে, তখন কোনো এলিমেন্টে the-element এর view-transition-name যোগ করার জন্য CSS-এর উদাহরণ:

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

আপনার সমস্ত ভিউ ট্রানজিশনের জন্য এই CSS নিয়মগুলো একবার সেট করে ফেললে, আপনি তখন pageswap এবং pagereveal ইভেন্ট চলাকালীন যেকোনো নেভিগেশনের জন্য বর্তমান ভিউ ট্রানজিশন টাইপটি ডাইনামিকভাবে পরিবর্তন করতে পারবেন।

pageswap ইভেন্টের সময় ভিউ ট্রানজিশন টাইপকে ai-mode আপডেট করার একটি উদাহরণ।

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-ইনডেক্স যথেচ্ছভাবে পরিবর্তন করার পরিবর্তে, আমরা তখন তৈরি হওয়া সিউডো এলিমেন্টগুলোর z-ইনডেক্সকে টার্গেট করতে পারি।

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

এরপর কী?

গুগল সার্চের জন্য আমরা ক্রস-ডকুমেন্ট ভিউ ট্রানজিশন ব্যবহার করার পরিকল্পনা করছি, যার মধ্যে নেভিগেশন এপিআই-এর সাথে ইন্টিগ্রেশনও অন্তর্ভুক্ত থাকবে, যখন এটি ক্রস-ব্রাউজারে উপলব্ধ হবে। আমরা পরবর্তীতে কী তৈরি করি তা দেখতে সাথে থাকুন!