티스토리 뷰

🚀 개요

 야놀자 X 패스트캠퍼스 프론트엔드 개발 부트캠프에서 이전 토스 클론 코딩하여 배포한 것을 멘토님과 피어리뷰를 통하여피드백을 받고 이를 리팩토링 할 시간과 기회를 얻게 됐다. 성능개선을 통한 최적화와 코드 가독성 측면으로 항상 관심이 있어서, PR과 주석을 통하여 웹 브라우저 렌더링 성능과 Indent가 중첩되어 사용한 것을 가독성이 보기 좋은 방법이 있는지에 대해 현직 FE개발자신 멘토님께 여쭤봤다. 

 

 아래에 멘토님과 동료님들의 피드백을 확인할 수 있다. 성능 측면에선 크게 두가지 피드백을 받았다. 

 

1. 기존 scroll 이벤트들이 등록되다보니 메모리 누수가 발생할 가능성이 높고 성능 저하가 일어난다. => CSS나 JS 내장 애니메이션을 통하여 개선하는 것이 좋아보인다.
2. Opacity가 0 <=> 1로 바뀌는 부분에서 Reflow가 발생할 수 있다. Repaint와 Reflow 에 대해서 고민할 필요가 있다 => 브라우저의 렌더링 원리와 Opacity 와 관련된 링크 첨부

 스스로 공부할 기회를 마련해 주셔서, 이와 관련되어 공부한 결과를 적고자 합니다. 우선 첫번째 피드백 부터 받아들여  JS의 내장 클래스인 Intersection Observer를 통하여 이벤트 핸들러를 제거하기로 합니다.

 

야놀자X패스트캠퍼스 클론코딩 피드백

 

KDT0_ChoiWuHyeok 토스 홈페이지 클론 코딩 제출 by TaePoong719 · Pull Request #10 · KDT1-FE/Y_FE_HTML_CSS

🎃토스 홈페이지 클론 코딩 🐶개요 간결하면서 전달력이 좋고 예쁜 UI를 가지고 있고 레거시가 적어보이는 웹사이트를 골랐습니다. 타 웹사이트보다 요소와 이벤트의 양이 훨씬 많음에도, 도

github.com

이전 게시물에서 이어집니다, 이전 게시물

 

[HTML/CSS/Vanilla JS] 스크롤 애니메이션

🚀 개요 토스 홈페이지 클론 코딩 중, Javascript만을 이용하여 스크롤 이벤트를 구현했다. 토스 홈페이지에서의 대부분의 애니메이션은 특정 요소가 화면에 보이기 시작하는 순간에 애니메이션

koeyhhh.tistory.com

 

😵 이전 코드 및 설명

 우선 기존의 코드는 스크롤을 할 때마다, 10개 정도의 스크롤 이벤트 핸들러의 콜백함수가 호출 됐으며, 각 콜백함수마다 요소의 getBoundingClientRect()(Reflow가 발생) 을 호출하였고, 이 값을 window.innerHeight 값과 비교하는 로직을 수행하였다. 이 상태에서 빠른 스크롤을 내리면, 수 백, 수 천번의 이벤트 콜백 함수들이 동기적으로 실행 되어 큰 성능 저하를 겪을 수 있다. 수 많은 스크롤 이벤트핸들러의 선언들은 성능저하를 불러 올 수 있다는 것이다.

 

 또한 getBoundingClientRect() 실행 시 Reflow를 발생한다. Reflow는 렌더링 트리가 변경되어 레이아웃을 다시 잡고, 리페인트를 하는 과정을 뜻한다. Reflow는 Repaint에 비해 자원을 더 사용하므로, Reflow는 되도록 피하는 것이 좋다.

 

const homeText = document.querySelector('.home_text')
const homeIphone1 = document.querySelector('.home_image_container .iphone_wrap:first-of-type')
const homeIphone2 = document.querySelector('.home_image_container .iphone_wrap:last-of-type')
const homeText2 = document.querySelector('.home_text2')

// 스크롤 이벤트 등록
window.addEventListener('scroll', homeEventHandler)

const homeEventHandler = ()=>{
	// homeTetxt요소의 맨 위로부터 뷰포트 상단까지의 길이 측정 및 화면에 나타났는지 감지
    if(homeText.getBoundingClientRect().top < windowHeight-200){
    	// 애니메이션이 순차적으로 동작
         setTimeout(()=>{
            homeIphone1.style.opacity = 1
            homeIphone1.style.animation = `appear_from_bottom ease 1.5s`
              setTimeout(()=>{
                  homeIphone2.style.opacity = 1
                  homeIphone2.style.animation = `appear_from_bottom ease 1.5s`
                    setTimeout(()=>{
                        homeText2.style.opacity = 1
                        homeText2.style.animation = `appear_from_bottom ease 1.5s`
                    },600)
              },600)
        },600)   
        window.removeEventListener('scroll',homeEventHandler)
    }
}

 

🧐 Intersection Observer 사용

 Intersection Observer를 사용하면, 이 이벤트 핸들러의 콜백함수를 매 스크롤마다 동작하는 것이 아니라, 비동기식으로 관찰을 하여, Reflow를 발생시키지 않습니다

기존의 getBoundingClientRect() 메소드를 쓰면 메인 스레드에 안좋은 영향을 끼친다.

new IntersectionObserver를 지정하여, 관찰을 하며, threshold 값을 통하여, 내가 원하는 요소가 화면에 등장했는지를 판단할 수 있습니다. (교차성,가시성을 계산) 

 

😛 리팩토링 코드 및 설명

const homeText = document.querySelector('.home_text')
const homeIphone1 = document.querySelector('.home_image_container .iphone_wrap:first-of-type')
const homeIphone2 = document.querySelector('.home_image_container .iphone_wrap:last-of-type')
const homeText2 = document.querySelector('.home_text2')

// homeText가 50% 정도 뷰포트에 나왔을 경우 아래 콜백함수 실행
let observer1 = new IntersectionObserver(entries=>{
  observer1cb(entries[0])
},{root: null,threshold:0.5})

// observer 콜백함수
const observer1cb = entry=>{
  if(entry.isIntersecting){
    homeText.style.opacity = 1
    homeText.style.animation = `appear_from_bottom ease 1.5s`
    // 애니메이션이 순차적으로 동작
    setTimeout(()=>{
        homeIphone1.style.opacity = 1
        homeIphone1.style.animation = `appear_from_bottom ease 1.5s`
      setTimeout(()=>{
          homeIphone2.style.opacity = 1
          homeIphone2.style.animation = `appear_from_bottom ease 1.5s`
        setTimeout(()=>{
            homeText2.style.opacity = 1
            homeText2.style.animation = `appear_from_bottom ease 1.5s`
            observer1.unobserve(homeText)
        },600)
      },600)
    },600)
  }
}
observer1.observe(homeText)

위와 같은 방법으로, Observer 객체에 IntersectionObserver 인스턴스를 할당하여, threshold 값을 지정한다. 특정 threshold값(화면에 나타나는 비율)에 도달할 경우 아래 observer 콜백 함수가 실행된다. 자세한 사용방법과 옵션에 대한 자료는 아래 참조란에 공식문서를 참조 바란다.

💡결론

 ObserverIntersection JS 내장 클래스를 통하여, 동기적이며 초당 수천번씩 실행되어 메인 스레드에 악영향을 끼칠 수 있는 스크롤 이벤트를 비동기적이며, Reflow 또한 발생시키지 않아 효율적인 방식으로 리팩토링 할 수 있었다.

 

다음 게시물로 이어집니다.

 

참조

https://velog.io/@elrion018/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%8A%90%EB%82%80-%EC%A0%90%EC%9D%84-%EA%B3%81%EB%93%A4%EC%9D%B8-Intersection-Observer-API-%EC%A0%95%EB%A6%AC

 

실무에서 느낀 점을 곁들인 Intersection Observer API 정리

실무에서 Intersection Observer API를 사용해보고 느낀 생각정리

velog.io

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

#패스트캠퍼스 #부트캠프 #프론트엔드개발자 #국비지원취업 #국비지원

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함