제안된 Portals API를 통해 어떻게 내비게이션 UX를 개선할 수 있는지 알아봅니다.
우수한 사용자 환경을 제공하려면 페이지가 빠르게 로드되어야 합니다. 하지만 사용자가 페이지 사이를 이동할 때 표시되는 페이지 전환이라는 것을 간과하는 경우가 많습니다.
Portals라는 새로운 웹 플랫폼 API 제안서는 사용자가 사이트 전반을 탐색할 때 환경을 간소화하여 이를 지원하는 것을 목표로 합니다.
실제 포탈 보기:
포털을 통해 제공되는 기능
단일 페이지 애플리케이션 (SPA)은 멋진 전환을 제공하지만 빌드 복잡성이 높아진 비용이 발생합니다. 다중 페이지 애플리케이션 (MPA)은 빌드가 훨씬 더 쉽지만 페이지 사이에 빈 화면이 표시됩니다.
포털은 MPA의 복잡성이 낮고 SPA가 원활하게 전환된다는 점에서 두 가지 장점을 제공합니다.
임베딩을 사용할 수 있다는 점에서 <iframe>
처럼 생각하세요. 하지만 <iframe>
와 달리 콘텐츠로 이동할 수 있는 기능도 있습니다.
믿음을 가지세요. 먼저 Chrome Dev Summit 2018에서 선보인 내용을 확인해 보세요.
기존 탐색을 사용하면 브라우저가 대상 렌더링을 완료할 때까지 사용자가 빈 화면을 보고 기다려야 합니다.
포털을 통해 사용자는 애니메이션을 경험할 수 있으며 <portal>
는 콘텐츠를 사전 렌더링하고 원활한 탐색 환경을 만듭니다.
포탈 이전에는 <iframe>
를 사용하여 다른 페이지를 렌더링할 수 있습니다. 페이지에서 프레임을 이동하는 애니메이션도 추가할 수 있었습니다. 하지만 <iframe>
를 사용하면 콘텐츠로 이동할 수 없습니다. 포털은 이러한 간극을 메우므로 흥미로운 사용 사례를 만들 수 있습니다.
Portal 사용해 보기
about://flags를 통해 사용 설정 중입니다.
실험용 플래그를 전환하여 Chrome 85 이상 버전에서 포털을 사용해 보세요.
- 동일 출처 탐색에
about://flags/#enable-portals
플래그를 사용 설정합니다. - 교차 출처 탐색을 테스트하려면
about://flags/#enable-portals-cross-origin
플래그도 사용 설정합니다.
또한 포털 실험 초기 단계에서는 --user-data-dir
명령줄 플래그를 설정하여 완전히 별개의 사용자 데이터 디렉터리를 테스트에 사용하는 것이 좋습니다.
포털이 사용 설정되면 DevTools에서 새로운 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();
});
간단한 작업입니다. DevTools 콘솔에서 다음 코드를 사용하면 위키백과 페이지가 열립니다.
위의 데모와 같이 작동하는 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');
...
}
Portal이 어떤 모습인지 빠르게 확인하고 싶다면 uskay-portals-demo.glitch.me를 사용해 보세요. Chrome 85 이상 버전에서 액세스하고 실험용 플래그를 사용 설정해야 합니다.
- 미리 보려는 URL을 입력합니다.
- 그러면 페이지가
<portal>
요소로 삽입됩니다. - 미리보기를 클릭합니다.
- 애니메이션이 끝난 후 미리보기가 활성화됩니다.
사양 확인
Web Incubation Community Group (WICG)에서 포털 사양에 대해 활발하게 논의하고 있습니다. 빠르게 알아보려면 몇 가지 주요 시나리오를 살펴보세요. 다음은 숙지해야 할 중요한 세 가지 기능입니다.
<portal>
요소: HTML 요소 자체입니다. API는 매우 간단합니다.src
속성,activate
함수, 메시지 인터페이스 (postMessage
)로 구성됩니다.activate
는 선택적 인수를 사용하여 활성화 시<portal>
에 데이터를 전달합니다.portalHost
인터페이스:portalHost
객체를window
객체에 추가합니다. 이를 통해 페이지가<portal>
요소로 삽입되었는지 확인할 수 있습니다. 또한 호스트에 다시 메시지 (postMessage
)를 보내기 위한 인터페이스도 제공합니다.- PortalActivateEvent 인터페이스:
<portal>
가 활성화될 때 실행되는 이벤트입니다. 이전 페이지를<portal>
요소로 검색하는 데 사용할 수 있는adoptPredecessor
라는 멋진 함수가 있습니다. 이를 통해 두 페이지 간에 원활한 탐색과 구성된 환경을 만들 수 있습니다.
기본 사용 패턴 너머를 살펴보겠습니다. 다음은 샘플 코드와 함께 포탈을 사용하여 달성할 수 있는 이점의 일부 목록입니다.
<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
});
}
});
Portal에서 지원하는 모든 기능을 결합하여 멋진 사용자 환경을 구축할 수 있습니다. 예를 들어 아래 데모는 포털이 웹사이트와 서드 파티 삽입 콘텐츠 간에 원활한 사용자 환경을 지원하는 방법을 보여줍니다.
사용 사례 및 계획
이 짧은 Portal 둘러보기가 도움이 되었기를 바랍니다. 어떤 프로젝트를 제출하실지 기대되네요. 예를 들어 제품 카테고리 등록정보 페이지에서 베스트셀러 제품 페이지를 사전 렌더링하는 것과 같은 간단한 탐색을 위해 포털을 사용하기 시작할 수 있습니다.
또 다른 중요한 점은 <iframe>
와 마찬가지로 교차 출처 탐색에서 Portal을 사용할 수 있다는 것입니다. 따라서 서로 참조하는 웹사이트가 여러 개 있는 경우 포털을 사용하여 서로 다른 두 웹사이트 간에 원활한 탐색을 만들 수도 있습니다. 이러한 교차 출처 사용 사례는 포털에만 적용할 수 있으며 SPA의 사용자 환경을 개선할 수도 있습니다.
의견 보내기
포털은 Chrome 85 이상 버전에서 실험할 수 있습니다. 커뮤니티의 의견은 새로운 API를 설계하는 데 중요한 역할을 합니다. 사용해 보고 의견을 들려주세요. 기능 요청 또는 의견이 있는 경우 WICG GitHub 저장소를 방문하세요.