Portallar ile uygulamalı: web'de sorunsuz gezinme

Önerilen Portals API'nin gezinme kullanıcı deneyiminizi nasıl iyileştirebileceğini öğrenin.

Yusuke Utsunomiya
Yusuke Utsunomiya

Sayfalarınızın hızlı yüklendiğinden emin olmak, iyi bir kullanıcı deneyimi sunmanın anahtarıdır. Ancak sıklıkla göz ardı ettiğimiz alanlardan biri sayfa geçişleridir. Sayfa geçişleri, kullanıcıların sayfalar arasında gezinirken gördükleri şeydir.

Portals adlı yeni bir web platformu API teklifi, kullanıcılar sitenizde gezinirken deneyimini kolaylaştırarak bu konuda yardımcı olmayı amaçlar.

Portal'ların nasıl çalıştığını görün:

Portallar ile sorunsuz yerleştirme ve gezinme. Adam Argyle tarafından oluşturuldu.

Portallar hangi özelliği etkinleştirir?

Tek Sayfalı Uygulamalar (SPA'lar) güzel geçişler sunar, ancak oluşturma işlemi daha karmaşıktır. Çok Sayfalı Uygulamaları (MPA) oluşturmak çok daha kolay olsa da sayfalar arasında boş ekranlarla karşılaşıyorsunuz.

Portallar hem MPA'nın düşük karmaşıklık düzeyine sahip hem de SPA'nın sorunsuz geçişleriyle iki dünyanın da en iyi yönlerini sunar. Bunları, yerleştirmeye olanak tanımaları açısından bir <iframe> gibi düşünebilirsiniz, ancak <iframe> öğesinin aksine, içeriklerine gitmeyi sağlayan özelliklere de sahiptirler.

Görmek inanmaktır: lütfen önce Chrome Dev Summit 2018'de neler sergilediğimize bir göz atın:

Klasik gezinmelerde kullanıcılar, tarayıcı hedefi oluşturmayı bitirene kadar boş bir ekran görmek zorunda kalır. Portallar sayesinde kullanıcılar bir animasyon deneyimi yaşar. <portal> ise içeriği önceden oluşturup sorunsuz bir gezinme deneyimi oluşturur.

Portallar'dan önce, <iframe> kullanarak başka bir sayfa oluşturabilirdik. Kareyi sayfa etrafında hareket ettirmek için animasyonlar da ekleyebiliriz. Ancak <iframe>, içeriklerine erişmenize izin vermez. Portallar bu açığı kapatarak ilginç kullanım alanlarını mümkün kılar.

Portalları deneyin

about://flags aracılığıyla etkinleştirme

Deneysel işaretini kaldırarak Chrome 85 ve sonraki sürümlerde Portal'ları deneyebilirsiniz:

  • Aynı kaynak gezinmeleri için about://flags/#enable-portals işaretini etkinleştirin.
  • Kaynaklar arası gezinmeleri test etmek için about://flags/#enable-portals-cross-origin işaretini de etkinleştirin.

Portallar denemesinin bu ilk aşamasında, --user-data-dir komut satırı işaretini ayarlayarak testleriniz için tamamen ayrı bir kullanıcı verileri dizini kullanmanızı öneririz. Portallar etkinleştirildikten sonra Geliştirici Araçları'nda yeni ve parlak HTMLPortalElement uygulamasına sahip olduğunuzu onaylayın.

DevTools konsolunun HTMLPortalElement öğesini gösteren ekran görüntüsü

Portalları Uygula

Temel bir uygulama örneğine göz atalım.

// 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();
});

Bu yöntem son derece basittir. Bu kodu DevTools konsolunda deneyin. Vikipedi sayfası açılacaktır.

Portal stili önizleme demosunu gösteren GIF

Chrome Geliştirici Zirvesi'nde gösterdiğimiz gibi çalışan ve yukarıdaki demo gibi bir uygulama derlemek isterseniz aşağıdaki snippet ilginizi çekebilir.

// 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);

Portal'ları kullanarak bir web sitesini kademeli olarak geliştirmek için özellik algılama yöntemini kullanmak da kolaydır.

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

Portal'ların tarzını hemen keşfetmek istiyorsanız uskay-portals-demo.glitch.me kullanmayı deneyin. Bu özelliğe Chrome 85 veya sonraki sürümleriyle eriştiğinizden ve deney işaretini etkinleştirdiğinizden emin olun.

  1. Önizlemek istediğiniz bir URL girin.
  2. Sayfa, daha sonra bir <portal> öğesi olarak yerleştirilir.
  3. Önizlemeyi tıklayın.
  4. Önizleme, bir animasyondan sonra etkinleştirilir.

Portalları kullanmaya ilişkin hatalı demoyu gösteren bir GIF

Teknik özelliklere bakın

Web Incubation Community Group'ta (WICG) Portallar spesifikasyonunu şu anda tartışmaktayız. Arayı hızla kapatmak için bazı temel senaryolara göz atın. Aşağıda, öğrenmeniz gereken üç önemli özellik belirtilmiştir:

  • <portal> öğesi: HTML öğesinin kendisi. API çok basit. src özelliği, activate işlevi ve mesajlaşma arayüzünden (postMessage) oluşur. activate, etkinleştirme sonrasında <portal> öğesine veri iletmek için isteğe bağlı bir bağımsız değişken alır.
  • portalHost arayüzü: window nesnesine bir portalHost nesnesi ekler. Bu şekilde, sayfanın bir <portal> öğesi olarak yerleştirilip yerleştirilmediğini kontrol edebilirsiniz. Ayrıca, ana makineye mesajlaşma (postMessage) için bir arayüz sağlar.
  • PortalActivateEvent arayüzü: <portal> etkinleştirildiğinde tetiklenen bir etkinlik. Önceki sayfayı <portal> öğesi olarak almak için kullanabileceğiniz adoptPredecessor adlı düzgün bir işlev vardır. Bu sayede, iki sayfa arasında sorunsuz gezinme ve oluşturulmuş deneyimler oluşturabilirsiniz.

Temel kullanım modelinin ötesine bakalım. Aşağıda, örnek kodla birlikte Portal'larla yapabileceklerinizin tam kapsamlı olmayan bir listesi verilmiştir.

<portal> öğesi olarak yerleştirildiğinde stili özelleştirin

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

<portal> öğesi ve portalHost arasındaki mesajlaşma

// 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> öğesi etkinleştiriliyor ve portalactivate etkinliği alınıyor

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

Öncekini alma

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

Sayfanızın önceki nesil olarak benimsendiğini bilme

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

Portallar tarafından desteklenen tüm özellikleri birleştirerek etkileyici kullanıcı deneyimleri oluşturabilirsiniz. Örneğin aşağıdaki demo, Portalların bir web sitesi ve üçüncü taraf yerleştirilmiş içerik arasında nasıl sorunsuz bir kullanıcı deneyimi sunabileceğini göstermektedir.

Kullanım alanları ve planlar

Bu kısa Portallar turunu beğendiğinizi umuyoruz! Nasıl bir proje hazırlayacağınızı görmek için sabırsızlanıyoruz. Örneğin, bir ürün kategorisi listeleme sayfasından en çok satan ürününüzün sayfasını önceden oluşturma gibi önemsiz gezinme işlemleri için Portalları kullanmaya başlamak isteyebilirsiniz.

Bilinmesi gereken bir diğer önemli nokta, Portal'ların kaynaklar arası gezinmede tıpkı <iframe> gibi kullanılabileceğidir. Birbirine çapraz referans veren birden çok web siteniz varsa, iki farklı web sitesi arasında sorunsuz gezinme oluşturmak için Portalları da kullanabilirsiniz. Kaynaklar arası kullanım alanı, Portallar için oldukça özeldir ve SPA'ların kullanıcı deneyimini bile iyileştirebilir.

Geri bildirimlerinize önem veriyoruz

Portallar, Chrome 85 ve sonraki sürümlerde deneme amaçlı kullanıma hazırdır. Topluluktan aldığımız geri bildirimler, yeni API'lerin tasarımı için çok önemlidir. Lütfen yeni API'leri deneyerek düşüncelerinizi bizimle paylaşın. Herhangi bir özellik isteğiniz veya geri bildiriminiz varsa lütfen WICG GitHub deposuna gidin.