เผยแพร่: 28 ส.ค. 2025
Google Search มีการเข้าถึงที่ใหญ่ที่สุดแห่งหนึ่งของโลก ดังนั้นการเปลี่ยนแปลงประสบการณ์ของผู้ใช้จึงอาจส่งผลกระทบต่อผู้ใช้หลายพันล้านคน เราใฝ่ฝันถึงประสบการณ์การใช้งานเว็บที่ดูทันสมัยและเหมือนแอปมากขึ้นมานานแล้ว เมื่อเริ่มพัฒนาโหมด AI เราต้องการสร้างประสบการณ์การใช้งานสำหรับผู้ใช้ที่เปลี่ยนจาก Search มาตรฐานไปเป็นโหมด AI ได้อย่างราบรื่นและเชื่อมต่อกัน เมื่อได้ยินเรื่องการเปลี่ยนฉากมุมมองข้ามเอกสาร เราก็รู้ว่าฟีเจอร์นี้เหมาะกับฟีเจอร์ดังกล่าวเป็นอย่างยิ่ง กรณีศึกษานี้จะแชร์สิ่งที่เราได้เรียนรู้จากการเพิ่มฟีเจอร์การเปลี่ยนฉากควบคู่ไปกับการเปิดตัวโหมด AI
การเปลี่ยนฉากระหว่างเอกสารเป็นเครื่องมือที่สำคัญเมื่อพูดถึงเครื่องมือของเบราว์เซอร์แบบเนทีฟ และเราตื่นเต้นที่จะได้เห็นว่าฟีเจอร์นี้จะช่วยกำหนดรูปแบบของเว็บในอนาคตอย่างไร
การเปลี่ยนแปลงสถานะที่เป็นอยู่
Google Search มีข้อกำหนดในการรองรับเบราว์เซอร์ที่เข้มงวดและระมัดระวัง โดยปกติแล้ว การใช้ฟีเจอร์ที่มีจำนวนจำกัดจะถูกจำกัด สำหรับการเปลี่ยนฉากระหว่างเอกสาร เราพบว่าการใช้ Polyfill ไม่สามารถทำได้ เนื่องจากข้อจำกัดหลักคือไม่มี API สำหรับการถ่ายภาพพิกเซล และการโคลนทั้งวิวพอร์ตทำให้เกิดปัญหาด้านประสิทธิภาพอย่างมาก ดังนั้น การใช้ฟีเจอร์นี้เป็นการเพิ่มประสิทธิภาพแบบต่อเนื่องจึงเป็นวิธีที่ดีที่สุดในการเปิดตัวพร้อมกับโหมด AI เนื่องจากภาพเคลื่อนไหวที่สร้างขึ้นโดยการเปลี่ยนมุมมองไม่ได้ส่งผลต่อฟังก์ชันการทำงานของเว็บไซต์โดยตรง เราจึงจะปิดใช้การเข้าชมที่ไม่รองรับ ซึ่งเป็นสถานะการใช้งานปัจจุบันอยู่แล้วโดยไม่มีภาพเคลื่อนไหวของการเปลี่ยน
เราได้ทดสอบกลยุทธ์การเพิ่มประสิทธิภาพแบบต่อเนื่องนี้กับผู้ใช้ภายในก่อน ซึ่งทำให้เราได้รับความคิดเห็นในช่วงแรกๆ ซึ่งส่วนใหญ่เป็นไปในเชิงบวก นอกจากนี้ ความคิดเห็นที่ได้รับยังช่วยให้เราพบข้อบกพร่องต่างๆ ซึ่งรวมถึงปัญหาด้านประสิทธิภาพและการโต้ตอบกับฟีเจอร์อื่นๆ โดยไม่ตั้งใจ เช่น บริบทการซ้อนทับ
เราพบว่ากลยุทธ์นี้ประสบความสำเร็จ และเชื่อว่าเราจะลองใช้กลยุทธ์นี้กับฟีเจอร์ใหม่ๆ ของเบราว์เซอร์อื่นๆ ต่อไป
ความยากลำบากที่เราพบและวิธีแก้ไข
เวลาในการตอบสนอง การบล็อกการแสดงผล และตัวจับเวลาตรวจสอบ
โดยรวมแล้ว เวลาในการตอบสนองที่เพิ่มขึ้นซึ่งมาพร้อมกับการเปลี่ยนมุมมอง MPA นั้นแทบไม่มีผลต่อกรณีการใช้งาน 99% โดยเฉพาะในฮาร์ดแวร์รุ่นใหม่ อย่างไรก็ตาม Google Search มีเกณฑ์ที่สูงมากในเรื่องเวลาในการตอบสนอง และเรามุ่งมั่นที่จะสร้างประสบการณ์ของผู้ใช้ที่ทำงานได้ดีในอุปกรณ์ทุกเครื่อง สำหรับเราแล้ว แม้แต่เวลาเพียงไม่กี่มิลลิวินาทีก็มีความสำคัญ ดังนั้นเราจึงต้องลงทุนในวิธีใช้การเปลี่ยนฉากมุมมองแบบข้ามเอกสารอย่างเหมาะสมโดยไม่ส่งผลเสียต่อประสบการณ์ของผู้ใช้
การบล็อกการแสดงผลเป็นเทคนิคที่ทำงานได้ดีกับการเปลี่ยนฉากมุมมองแบบข้ามเอกสาร ภาพรวมขององค์ประกอบเสมือนของเอกสารขาเข้าจะแสดงได้เฉพาะเนื้อหาที่แสดงผลแล้วเท่านั้น ดังนั้น หากต้องการเคลื่อนไหวเนื้อหาจากเอกสารที่เข้ามา คุณต้องบล็อกการแสดงผลจนกว่าจะมีการแสดงผลองค์ประกอบเป้าหมายที่ต้องการเคลื่อนไหว โดยใช้แอตทริบิวต์ 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 ในกรณีดังกล่าว เราได้เขียนสคริปต์ตัวจับเวลา Watchdog เพื่อนำ 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();
}
ข้อจำกัดของความครอบคลุม
อีกปัญหาที่เราพบคือการเปลี่ยนมุมมองข้ามเอกสารที่กฎ @transition navigation: auto เกิดขึ้นที่ระดับส่วนกลางภายในเอกสาร ไม่มีวิธีในตัวที่จะกำหนดขอบเขตการเปิดใช้การเปลี่ยนมุมมองระหว่างเอกสารให้เฉพาะเป้าหมายการคลิกที่เฉพาะเจาะจงเท่านั้น เนื่องจากการเปลี่ยนแปลงนี้มีขนาดใหญ่มาก เราจึงไม่สามารถเปิดใช้การเปลี่ยนฉากการดูแบบข้ามเอกสารในการไปยังส่วนต่างๆ ใน Google Search ได้ 100% เราต้องการวิธีเปิดหรือปิดใช้การเปลี่ยนฉากมุมมองแบบข้ามเอกสารแบบไดนามิกโดยขึ้นอยู่กับฟีเจอร์ที่ผู้ใช้โต้ตอบด้วย ในกรณีของเรา เราเปิดใช้เฉพาะการเปลี่ยนโหมดเป็นและจากโหมด AI เท่านั้น เราทำเช่นนี้โดยการอัปเดตกฎ @navigation โดยอัตโนมัติ ทั้งนี้ขึ้นอยู่กับเป้าหมายที่คลิกหรือแตะ
วิธีเปิด/ปิดการเปลี่ยนมุมมองที่กฎ @ มีดังนี้
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;
}
ภาพเคลื่อนไหวที่กระตุกและภาพเคลื่อนไหวที่ทำการ Composite
ภาพเคลื่อนไหวบางรายการที่สร้างขึ้นโดยอัตโนมัติในองค์ประกอบเสมือนของการเปลี่ยนมุมมองทำให้เกิดเฟรมหลุดในอุปกรณ์รุ่นเก่า ซึ่งส่งผลต่อประสบการณ์การใช้งานที่ราบรื่นและไร้รอยต่อที่เราต้องการมอบให้แก่ผู้ใช้ เราได้เขียนภาพเคลื่อนไหวใหม่โดยใช้เทคนิคภาพเคลื่อนไหวที่ทำงานบน Compositor ได้ เพื่อปรับปรุงประสิทธิภาพของภาพเคลื่อนไหว เราทำได้โดยการตรวจสอบคีย์เฟรมเพื่อดูขนาดขององค์ประกอบเสมือนของสแนปชอตก่อนและหลัง รวมถึงใช้คณิตศาสตร์เมทริกซ์เพื่อเขียนคีย์เฟรมใหม่ตามนั้น ตัวอย่างต่อไปนี้แสดงวิธีดึงภาพเคลื่อนไหวสำหรับองค์ประกอบเสมือนของการเปลี่ยนมุมมองแต่ละรายการ
const pseudoElement = `::view-transition-group(${name})`;
const animation = document
.getAnimations()
.find(
(animation) =>
(animation.effect as KeyframeEffect)?.pseudoElement === pseudoElement,
);
อ่านเพิ่มเติมเกี่ยวกับการเขียนคีย์เฟรมการเปลี่ยนมุมมองที่มีประสิทธิภาพได้ในการใช้การเปลี่ยนมุมมอง: การจัดการกับบล็อกที่มีภาพรวม
สิ่งอื่นๆ ที่ต้องระวัง
ปัญหาที่โดดเด่นอย่างหนึ่งคือการติดแท็กองค์ประกอบด้วยพร็อพเพอร์ตี้ CSS ของ view-transition-name จะส่งผลต่อบริบทการซ้อน (ข้อกําหนดการเปลี่ยนมุมมอง: ส่วนที่ 2.1.1) ซึ่งเป็นแหล่งที่มาของข้อบกพร่องหลายอย่างที่ต้องมีการแก้ไข z-index ขององค์ประกอบคอนเทนเนอร์
อีกสิ่งหนึ่งที่ควรทราบคือคุณอาจไม่ต้องการเพิ่มค่า view-transition-name ให้กับองค์ประกอบโดยค่าเริ่มต้น มีผู้คนจำนวนมากที่ทำงานใน Google Search เพื่อป้องกันไม่ให้ค่า 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'],
);
}
);
วิธีนี้จะช่วยป้องกันการตั้งชื่อที่ซ้ำกัน และไม่ให้เราถ่ายภาพองค์ประกอบที่ไม่จำเป็นโดยไม่จำเป็นซึ่งเป็นส่วนหนึ่งของการเข้าและออกจากโหมด AI
สุดท้าย ปัญหาบริบทการซ้อนจะเกิดขึ้นระหว่างการเปลี่ยนมุมมองเท่านั้น หากต้องการแก้ไขปัญหาเหล่านั้น เราจึงกำหนดเป้าหมายดัชนี z ขององค์ประกอบเสมือนที่สร้างขึ้นแทนที่จะแก้ไขดัชนี z ขององค์ประกอบเดิมโดยพลการเพียงเพื่อแก้ไขปัญหานี้เมื่อใช้การเปลี่ยนมุมมอง
::view-transition-group(the-element) {
z-index: 100;
}
ขั้นตอนถัดไป
เรามีแผนที่จะใช้การเปลี่ยนมุมมองข้ามเอกสารสำหรับ Google Search รวมถึงการผสานรวมกับ Navigation API เมื่อพร้อมใช้งานในเบราว์เซอร์ต่างๆ โปรดติดตามเพื่อดูว่าเราจะสร้างอะไรต่อไป