ปฏิบัติจริงกับพอร์ทัล: ไปยังส่วนต่างๆ บนเว็บได้อย่างราบรื่น

ดูว่าพอร์ทัล API ที่เสนอจะช่วยปรับปรุง UX การนำทางได้อย่างไร

ยูสุเกะ อุสึโนมิยะ
ยูสุเกะ อุสึโนมิยะ

กุญแจสำคัญในการมอบประสบการณ์ที่ดีให้กับผู้ใช้คือการทำให้หน้าเว็บโหลดได้อย่างรวดเร็ว แต่สิ่งหนึ่งที่เรามักมองข้ามคือการเปลี่ยนหน้า ซึ่งก็คือสิ่งที่ผู้ใช้จะเห็นเมื่อย้ายไปมาระหว่างหน้าต่างๆ

ข้อเสนอ API สำหรับแพลตฟอร์มเว็บใหม่ชื่อ Portals มีวัตถุประสงค์เพื่อช่วยในเรื่องนี้โดยปรับปรุงประสบการณ์ขณะที่ผู้ใช้ไปยังส่วนต่างๆ ของทั่วทั้งเว็บไซต์ของคุณ

ดูการทำงานของพอร์ทัล:

การฝังและไปยังส่วนต่างๆ อย่างราบรื่นด้วยพอร์ทัล สร้างโดย Adam Argyle

สิ่งที่พอร์ทัลเปิดใช้

แอปพลิเคชันหน้าเว็บเดียว (SPA) ให้การเปลี่ยนฉากอย่างราบรื่น แต่ต้องสร้างความซับซ้อนที่สูงกว่า แอปพลิเคชันแบบหลายหน้าเว็บ (MPA) สร้างได้ง่ายกว่ามาก แต่กลับกลายเป็นหน้าจอว่างเปล่าระหว่างหน้าเว็บ

พอร์ทัลนำเสนอสิ่งที่ดีที่สุดของทั้ง 2 โลก นั่นคือ MPA มีความซับซ้อนต่ำพร้อมด้วยการเปลี่ยน SPA อย่างราบรื่น ให้คิดว่าโค้ดเหล่านี้เหมือน <iframe> ที่เปิดให้ฝังเนื้อหาได้ แต่ยังมาพร้อมกับฟีเจอร์สำหรับการไปยังเนื้อหา ซึ่งต่างจาก <iframe>

เชื่อเถอะว่า โปรดดูสิ่งที่เราจัดแสดงในงาน Chrome Dev Summit 2018 ก่อน

สำหรับการนำทางแบบคลาสสิก ผู้ใช้ต้องรอหน้าจอว่างเปล่าจนกว่าเบราว์เซอร์จะแสดงผลปลายทางเสร็จ พอร์ทัลช่วยให้ผู้ใช้ได้เห็นภาพเคลื่อนไหว ขณะที่ <portal> แสดงเนื้อหาล่วงหน้าและสร้างประสบการณ์การนําทางที่ราบรื่น

ก่อนพอร์ทัล เราน่าจะแสดงผลหน้าอื่นโดยใช้ <iframe> เรายังอาจเพิ่มภาพเคลื่อนไหวเพื่อย้ายเฟรมไปรอบหน้าได้ด้วย แต่ <iframe> จะให้คุณไปยังเนื้อหาไม่ได้ พอร์ทัลปิดช่องว่างนี้ได้ ทำให้เกิดกรณีการใช้งานที่น่าสนใจ

ลองใช้พอร์ทัล

การเปิดใช้ผ่าน about://flags

ลองใช้พอร์ทัลใน Chrome 85 และเวอร์ชันใหม่กว่าโดยพลิกค่าสถานะทดลอง ดังนี้

  • เปิดใช้แฟล็ก about://flags/#enable-portals สำหรับการนำทางต้นทางเดียวกัน
  • สำหรับการทดสอบการนำทางข้ามต้นทาง ให้เปิดใช้แฟล็ก about://flags/#enable-portals-cross-origin เพิ่มเติม

ในช่วงแรกของการทดสอบพอร์ทัล เราขอแนะนำให้ใช้ไดเรกทอรีข้อมูลผู้ใช้แยกต่างหากโดยสิ้นเชิงสำหรับการทดสอบโดยตั้งค่าแฟล็กบรรทัดคำสั่ง --user-data-dir เมื่อเปิดใช้พอร์ทัลแล้ว ให้ยืนยันในเครื่องมือสำหรับนักพัฒนาเว็บว่าคุณมี HTMLPortalElement ใหม่

ภาพหน้าจอของคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บที่แสดง HTMLPortalElement

ใช้งานพอร์ทัล

ลองดูตัวอย่างการใช้งานพื้นฐานกัน

// Create a portal with the wikipedia page, and embed it
// (like an iframe). You can also use the <portal> tag instead.
portal = document.createElement('portal');
portal.src = 'https://en.wikipedia.org/wiki/World_Wide_Web';
portal.style = '...';
document.body.appendChild(portal);

// When the user touches the preview (embedded portal):
// do fancy animation, e.g. expand …
// and finish by doing the actual transition.
// For the sake of simplicity, this snippet will navigate
// on the `onload` event of the Portals element.
portal.addEventListener('load', (evt) => {
   portal.activate();
});

ง่ายๆ เท่านี้เลย ลองใช้โค้ดนี้ในคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บ หน้าวิกิพีเดียควรเปิดขึ้นมา

GIF การสาธิตรูปแบบพอร์ทัลตัวอย่าง

หากคุณต้องการสร้างผลิตภัณฑ์อย่างที่เราแสดงไว้ในงาน Chrome Dev Summit ซึ่งทำงานเหมือนกับตัวอย่างด้านบน ตัวอย่างต่อไปนี้จะน่าสนใจ

// Adding some styles with transitions
const style = document.createElement('style');
style.innerHTML = `
  portal {
    position:fixed;
    width: 100%;
    height: 100%;
    opacity: 0;
    box-shadow: 0 0 20px 10px #999;
    transform: scale(0.4);
    transform-origin: bottom left;
    bottom: 20px;
    left: 20px;
    animation-name: fade-in;
    animation-duration: 1s;
    animation-delay: 2s;
    animation-fill-mode: forwards;
  }
  .portal-transition {
    transition: transform 0.4s;
  }
  @media (prefers-reduced-motion: reduce) {
    .portal-transition {
      transition: transform 0.001s;
    }
  }
  .portal-reveal {
    transform: scale(1.0) translateX(-20px) translateY(20px);
  }
  @keyframes fade-in {
    0%   { opacity: 0; }
    100% { opacity: 1; }
  }
`;
const portal = document.createElement('portal');
// Let's navigate into the WICG Portals spec page
portal.src = 'https://wicg.github.io/portals/';
// Add a class that defines the transition. Consider using
// `prefers-reduced-motion` media query to control the animation.
// https://developers.google.com/web/updates/2019/03/prefers-reduced-motion
portal.classList.add('portal-transition');
portal.addEventListener('click', (evt) => {
  // Animate the portal once user interacts
  portal.classList.add('portal-reveal');
});
portal.addEventListener('transitionend', (evt) => {
  if (evt.propertyName == 'transform') {
    // Activate the portal once the transition has completed
    portal.activate();
  }
});
document.body.append(style, portal);

การตรวจหาฟีเจอร์เป็นไปอย่างง่ายดายเพื่อเพิ่มประสิทธิภาพเว็บไซต์อย่างต่อเนื่องโดยใช้พอร์ทัล

if ('HTMLPortalElement' in window) {
  // If this is a platform that have Portals...
  const portal = document.createElement('portal');
  ...
}

หากต้องการดูได้อย่างรวดเร็วว่าพอร์ทัลมีลักษณะอย่างไร ให้ลองใช้ uskay-portals-demo.glitch.me โปรดตรวจสอบว่าคุณเข้าถึงด้วย Chrome 85 เวอร์ชันขึ้นไปและเปิดสถานะการทดสอบ

  1. ป้อน URL ที่คุณต้องการดูตัวอย่าง
  2. จากนั้นระบบจะฝังหน้าเว็บเป็นองค์ประกอบ <portal>
  3. คลิกตัวอย่าง
  4. การแสดงตัวอย่างจะเปิดใช้งานหลังภาพเคลื่อนไหว

GIF การใช้การสาธิตข้อบกพร่องของการใช้พอร์ทัล

ดูข้อกำหนด

เรากำลังพูดคุยเรื่องข้อกำหนดของพอร์ทัลในกลุ่ม Web Incubation Community Group (WICG) อย่างจริงจัง มาดูสถานการณ์สำคัญบางส่วนเพื่อตามให้ทันอย่างรวดเร็ว ต่อไปนี้คือฟีเจอร์สำคัญ 3 อย่างที่คุณควรทำความคุ้นเคยกับ

  • องค์ประกอบ <portal>: องค์ประกอบ HTML เอง API นี้ใช้งานง่ายมาก ซึ่งประกอบด้วยแอตทริบิวต์ src ฟังก์ชัน activate และอินเทอร์เฟซสำหรับการรับส่งข้อความ (postMessage) activate จะใช้อาร์กิวเมนต์ที่ไม่บังคับเพื่อส่งข้อมูลไปยัง <portal> เมื่อเปิดใช้งาน
  • อินเทอร์เฟซ portalHost: เพิ่มออบเจ็กต์ portalHost ในออบเจ็กต์ window วิธีนี้ช่วยให้คุณตรวจสอบได้ว่าหน้าเว็บฝังเป็นองค์ประกอบ <portal> หรือไม่ และยังมีอินเทอร์เฟซสำหรับการรับส่งข้อความ (postMessage) กลับไปยังโฮสต์ด้วย
  • อินเทอร์เฟซ PortalActivateEvent: เหตุการณ์ที่จะเริ่มทำงานเมื่อเปิดใช้งาน <portal> มีฟังก์ชันที่น่าสนใจที่เรียกว่า adoptPredecessor ซึ่งคุณสามารถใช้เพื่อดึงหน้าก่อนหน้าเป็นองค์ประกอบ <portal> ซึ่งช่วยให้คุณสามารถสร้างการนำทางที่ราบรื่นและประสบการณ์การใช้งานที่เขียนขึ้นมาระหว่าง 2 หน้าได้

มาดูมากกว่ารูปแบบการใช้งานพื้นฐานกัน ต่อไปนี้เป็นรายการโดยสังเขปของสิ่งที่คุณจะได้รับเมื่อใช้พอร์ทัลพร้อมโค้ดตัวอย่าง

ปรับแต่งรูปแบบเมื่อฝังเป็นองค์ประกอบ <portal>

// Detect whether this page is hosted in a portal
if (window.portalHost) {
  // Customize the UI when being embedded as a portal
}

การรับส่งข้อความระหว่างองค์ประกอบ <portal> กับ portalHost

// Send message to the portal element
const portal = document.querySelector('portal');
portal.postMessage({someKey: someValue}, ORIGIN);

// Receive message via window.portalHost
window.portalHost.addEventListener('message', (evt) => {
  const data = evt.data.someKey;
  // handle the event
});

กำลังเปิดใช้งานองค์ประกอบ <portal> และรับเหตุการณ์ portalactivate

// You can optionally add data to the argument of the activate function
portal.activate({data: {somekey: 'somevalue'}});

// The portal content will receive the portalactivate event
// when the activate happens
window.addEventListener('portalactivate', (evt) => {
  // Data available as evt.data
  const data = evt.data;
});

กำลังดึงข้อมูลจากเวอร์ชันก่อนหน้า

// Listen to the portalactivate event
window.addEventListener('portalactivate', (evt) => {
  // ... and creatively use the predecessor
  const portal = evt.adoptPredecessor();
  document.querySelector('someElm').appendChild(portal);
});

การทราบว่าหน้าเว็บได้รับการนำไปใช้เป็นรุ่นก่อนหน้า

// The activate function returns a Promise.
// When the promise resolves, it means that the portal has been activated.
// If this document was adopted by it, then window.portalHost will exist.
portal.activate().then(() => {
  // Check if this document was adopted into a portal element.
  if (window.portalHost) {
    // You can start communicating with the portal element
    // i.e. listen to messages
    window.portalHost.addEventListener('message', (evt) => {
      // handle the event
    });
  }
});

ด้วยการรวมฟีเจอร์ทั้งหมดที่พอร์ทัลรองรับ ช่วยให้คุณสร้างประสบการณ์ของผู้ใช้ที่ยอดเยี่ยมได้ ตัวอย่างเช่น การสาธิตด้านล่างแสดงให้เห็นวิธีที่พอร์ทัลช่วยให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ราบรื่นระหว่างเว็บไซต์และเนื้อหาที่ฝังของบุคคลที่สาม

Use Case และแพ็กเกจ

เราหวังว่าคุณจะชอบทัวร์ชมพอร์ทัลสั้นๆ นี้ เรารอดูความสำเร็จจากคุณอยู่ ตัวอย่างเช่น คุณอาจต้องการเริ่มใช้พอร์ทัลสำหรับการนำทางที่ไม่สำคัญ เช่น การแสดงผลหน้าเว็บล่วงหน้าสำหรับผลิตภัณฑ์ขายดีของคุณจากหน้ารายการหมวดหมู่ผลิตภัณฑ์

สิ่งสำคัญอีกอย่างที่ต้องทราบคือ พอร์ทัลใช้ในการนำทางแบบข้ามต้นทางได้ เช่นเดียวกับ <iframe> ดังนั้น หากคุณมีหลายเว็บไซต์ที่อ้างอิงกันและกัน คุณก็สามารถใช้พอร์ทัลเพื่อสร้างการนำทางที่ราบรื่นระหว่างเว็บไซต์สองเว็บที่แตกต่างกันได้ กรณีการใช้งานแบบข้ามต้นทางนี้มีความเฉพาะตัวสำหรับพอร์ทัลเป็นอย่างมาก ทั้งยังช่วยปรับปรุงประสบการณ์ของผู้ใช้ SPA อีกด้วย

ยินดีรับฟังความคิดเห็นจากคุณ

พอร์ทัลพร้อมสำหรับการทดสอบใน Chrome เวอร์ชัน 85 ขึ้นไป ความคิดเห็นจากชุมชนมีความสำคัญต่อการออกแบบ API ใหม่ ดังนั้นโปรดทดลองใช้และบอกเราว่าคุณคิดอย่างไร หากมีคำขอหรือความคิดเห็นเกี่ยวกับฟีเจอร์ โปรดไปที่ที่เก็บ WICG GitHub