Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

페이지 노출 여부를 판별하는 Page Visibility API 살펴보기 본문

🎨 프론트엔드

페이지 노출 여부를 판별하는 Page Visibility API 살펴보기

Chamming2 2024. 6. 2. 02:08

컨텐츠로 수익을 창출할 수 있는 시대가 되면서 미디어에 광고를 부착하는 것이 흔한 광경이 되었는데요,

여러 광고 유형들 중에서도 제 3의 페이지를 방문하도록 유도하는 형태가 점점 많이 보이는 것 같아요.

예시 : “쿠팡 방문하고 계속 읽기”

 

그런데 갑자기 광고팀에서 우리의 플랫폼에도 방문형 광고 기능을 추가해달라고 요청하면 어떻게 해야 할까요? (안된다고 누워야겠죠?)

이런 불상사를 대비하기 위해 오늘은 간단한 형태의 방문형 광고를 만들어 보겠습니다.

🔔 필요한 코드는 아래 링크에 미리 준비해 두었어요!
https://github.com/C17AN/page-visibility-demo
 

GitHub - C17AN/page-visibility-demo

Contribute to C17AN/page-visibility-demo development by creating an account on GitHub.

github.com

방문형 광고 기능 만들기

“광고를 시청하고 복귀했을 때” 컨텐츠가 노출되는 로직은 어떤 형태로 구성해야 할까요?

실제로는 더 복잡한 과정들을 거치겠지만, 아마 대략적으로는 이런 흐름이 될 것 같아요.

여기서 빨갛게 표시한 부분을 주목해야 하는데요, 사용자가 다른 페이지에 진입했다가 복귀했을 때 콜백을 실행하도록 하는 것 이 중요한 요건 중 하나입니다.

 

이를 구현하려면 어떤 장치를 활용해야 할까요?

페이지에 초점을 맞출 때 콜백 실행하기

아무래도 제일 먼저 떠오르는 것은 페이지에 포커스를 맞출 때마다 콜백을 실행하는 방법이에요.

코드로 표현하면 이런 모습이 될 텐데요, 이 코드는 “어느 정도는” 훌륭하게 동작해요.

const [adWatched, setAdWatched] = useState(false);

useEffect(() => {
  fetchAdStatus();
}, []);

useEffect(() => {
  window.addEventListener("focus", fetchAdStatus);
  return () => {
    document.removeEventListener("focus", fetchAdStatus);
  };
}, []);

const fetchAdStatus = async () => {
  if (adWatched) return;
  const res = await getAdStatusFromServer();

  if (res.watched) {
    setAdWatched(() => true);
  }
};

광고 페이지에 들어갔다 나오면 컨텐츠가 잘 노출되지만, 사용자가 뷰포트 바깥(Ex. 개발자 도구, URL 입력 창 등) 에 포커스를 맞췄다가 창을 누를 때마다 요청이 전송되고 있는 모습이에요.

 

지금은 단순히 광고 시청 여부만을 검사하기 때문에 focus 이벤트를 사용해도 문제가 없지만 마케팅 데이터 분석 등을 위해 페이지 복귀, 이탈 이벤트를 정밀하게 수집해야 하는 경우에는 적합하지 않을 수 있는데요, 바로 이런 상황에서 오늘 소개할 Page Visibility API를 고려해볼 수 있습니다.

Page Visibility API

브라우저는 focus, blur 이벤트 외에도 “페이지가 유저에게 보여지고 있는지” 를 직관적으로 판별할 수 있는 API를 제공합니다.

아마 이런 로직이 필요할 때 유용하게 사용될 수 있겠죠?

  • 다른 탭으로 전환할 때 비디오나 배경음악을 정지하는 로직
  • 페이지로의 복귀, 이탈 시점을 감지하는 로직
  • MDN에 기고된 글 에 따르면 특히 페이지를 이탈할 때의 로직을 작성할 때 유용하다고 해요.
    (아마 unload 이벤트가 deprecate 되었고, beforeunload 역시 큰 신뢰를 얻지 못하고 있기 때문일 것 같아요)

사용법

document의 visibilitychange 이벤트를 사용하면 페이지가 유저에게 노출되거나 숨겨질 때 실행될 동작을 지정할 수 있습니다.

// 1. visibilitychange 이벤트로 페이지 노출 여부를 감지할 수 있다.
document.addEventListener("visibilitychange", () => {
  if (document.hidden) {
    // 페이지가 유저에게 보이지 않을 때 수행할 동작
  } else {
    // 페이지가 유저에게 나타날 때 수행할 동작
  }
});

// ------------------------------------------------------------------- //

// 2. document.visibilityState 속성으로 페이지 노출 여부를 감지할 수 있다.
if(document.visibilityState === "hidden") {
    // 페이지가 유저에게 보이지 않을 때 수행할 동작
}

else if(document.visibilityState === "visible") {
    // 페이지가 유저에게 나타날 때 수행할 동작
}

위에서 focus 이벤트로 작성했던 로직을 visibilitychange 이벤트를 사용하도록 다시 작성해 보겠습니다.

페이지를 보게 될 때 콜백 실행하기

focus 이벤트를 사용할 때와 거의 유사하지만, visibilitychange 이벤트를 사용하면 다음 상황에서 콜백이 실행됩니다.

  • 다른 탭으로 이동했다가 돌아올 때
  • 다른 페이지로 이동했다가 돌아왔을 때
  • 브라우저를 최소화했다가 복구했을 때

const [adWatched, setAdWatched] = useState(false);

useEffect(() => {
  fetchAdStatus();
}, []);

useEffect(() => {
  document.addEventListener("visibilitychange", fetchAdStatus);
  return () => {
    document.removeEventListener("visibilitychange", fetchAdStatus);
  };
  fetchAdStatus;
}, []);

const fetchAdStatus = async () => {
  // 이미 광고를 봤거나, 광고를 보는 중이라면 실행하지 않는다
  if (adWatched || document.hidden) return;
  const res = await getAdStatusFromServer();

  if (res.watched) {
    setAdWatched(() => true);
  }
};

코드만 봤을 때는 이전과 달라진 점이 크게 없지만 실행 결과에는 차이가 생겼는데요, 더이상 콘솔과 URL 입력창에 포커스를 맞췄을 때 로그가 찍히지 않고 페이지에 복귀했을 때만 이벤트가 호출됩니다.

정리

  • 페이지에 복귀, 이탈했음을 인식하기 위해 focus, blur 이벤트를 사용할 수도 있지만, visibilitychange 이벤트를 활용하면 보다 직관적이고 정확하게 페이지 노출 여부를 판별해낼 수 있습니다.
  • visibilitychange 이벤트는 특히 페이지를 이탈하는 경우 (Ex. 탭 전환, 브라우저 최소화, 홈 버튼 눌러서 모바일 앱 최소화 등) 를 판별할 때 유용하게 사용될 수 있습니다.

간단하지만 유용한 이번 인터페이스가 도움이 될 수 있길 기대하겠습니다.

그럼, 오늘도 즐거운 코딩 하세요!

참고 및 함께 보면 좋을 링크

https://developer.mozilla.org/en-US/blog/using-the-page-visibility-api/

 

Using the Page Visibility API | MDN Blog

This post takes a look at what page visibility is, how you can use the Page Visibility API in your applications, and describes pitfalls to avoid if you build features around this functionality.

developer.mozilla.org

https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event

 

Document: visibilitychange event - Web APIs | MDN

The visibilitychange event is fired at the document when the contents of its tab have become visible or have been hidden.

developer.mozilla.org

https://developer.chrome.com/docs/web-platform/page-lifecycle-api

 

페이지 수명 주기 API  |  Web Platform  |  Chrome for Developers

Page Lifecycle API는 모바일 운영체제에서 흔히 볼 수 있는 앱 수명 주기 기능을 웹에 제공합니다. 이제 브라우저에서 백그라운드 페이지를 안전하게 정지하고 삭제하여 리소스를 절약할 수 있으며,

developer.chrome.com

https://tanstack.com/query/latest/docs/framework/react/guides/window-focus-refetching

 

Window Focus Refetching | TanStack Query React Docs

Launch week sale Up to 30% off through June 5th Join now

tanstack.com

 

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆