이번에 제가 작업하고 있던 프로젝트에서는 스크롤 이벤트를 적용해야하는 경우가 있었습니다.
저는 React에서 scroll이벤트를 적용하기 위해서 아래와 같은 코드를 사용했었는데요.
(React 기준)
함수형 컴포넌트의 경우
useEffect(() => {
window.addEventListener("scroll", animationCallbackFunction);
return () => {
window.removeEventListenr("scroll", animationCallbackFunction);
}
}, []);
class형 컴포넌트의 경우
componentDidMount = () => {
window.addEventListener('scroll', this.animationCallbackFunction);
}
componentWillUnmount = () => {
window.removeEventListener('scroll', this.animationCallbackFunction);
}
그리고 스크롤 영역을 계산하기위해서 아래와 같은 코드를 작성했습니다.
// 실제 대표사이트의 연혁 부분 애니메이션 시작 부분
const sectionHistory = document.querySelectorAll('.history');
const tabHeight = document.querySelector('.tab-boxed-fix').offsetHeight;
sectionHistory.forEach((section, index) => {
const sectionTop = section.getBoundingClientRect().top;
const eventStandard = Math.floor(sectionTop - tabHeight - 10);
...
})
getBoundingClientRect().top
과 같이 client가 보는 view내에서 상대적인 y값을 구하기위해 해당 API를 사용해야 했습니다. 그런데, 최근에 발견한 한 문장
모든 코드가 🌼️메인 스레드에서🌼️ 실행되기 때문에, 이 중 하나라도 성능 문제를 일으킬 수 있습니다. 사이트가 이러한 테스트들과 함께 로드되면 상황이 더욱 나빠질 수 있습니다.
scroll
이벤트와 getBound..
를 사용하지 않아도 브라우저에서 DOM(컴포넌트로 생각하시면 됩니다 !) 영역을 잡을 수 있습니다.
MDN Document - Intersection Observer API
Intersection Observer API는 타겟 요소와 상위 요소 또는 최상위 document 의 viewport 사이의 intersection 내의 변화를 🌼️비동기적으로 관찰🌼️하는 방법입니다.
-> 핵심은 메인스레드에서 했던 일들을 비동기적으로 수행하면서 성능 이슈를 줄이는 것입니다.
직역하면 교차 관찰자? 정도 되겠네요. 뭘 교차해서 관찰하는 지 지금부터 알아보겠습니다.
공식 문서에서는 아래와 같은 경우 해당 API를 사용할 수 있다고 이야기하고 있습니다.
options
callback
new IntersectionObserver(options, callback
element
observer.observe(target)
타겟 관찰 시작 observer.unobserve(target)
타겟 관찰 종료.options
let options = {
root: null,
rootMargin: '0px',
🦝 threshold: [0.2, 0.3, 0.4, 0.5, 1.0]
}
결정적으로 이벤트는 언제 발생하냐
scroll
=> 스크롤 할 때마다,observe
=> options
에서 제시한 영역에 올 때마다,이렇게 두 경우만 봐도 확실히 observe
가 이벤트를 덜, 그리고 정확하게 발생시킵니다.
또한, observe
는 이 이벤트 마저도 비동기적으로 수행하기 때문에 전체 성능도 좋아지는 것이죠 !
///
작성 - 정수진C
🦘햇병아리sinri0809였습니다.
피드백은 환영입니다.