데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      OpenLab 2기 - 웹 프론트엔드 성능 최적화 : 5번째 스터디 (4장 홈페이지 최적화 - 이미지 지연로딩, 리덕스 렌더링 최적화, 병목코드 최적화)

      insunok9507 24.11.16
      268 2 0
      DEVOTEE 요약
      OpenLab 2기 웹 프론트엔드 성능 최적화 스터디에서 이미지 갤러리 최적화에 대해 발표했습니다. 주요 내용은 이미지 지연 로딩, Redux 렌더링 최적화, 병목 코드 최적화로, React-lazyload 라이브러리를 이용한 이미지 지연 로딩 적용, Redux 상태 관리 최적화 방법, 그리고 메모이제이션 기법 및 로직 개선을 통한 실행 시간 단축 등이 포함되었습니다. 이번 스터디를 통해 기술의 실제 영향력을 실감하게 되었고, 앞으로도 계속해서 웹 성능 최적화에 대한 학습을 이어가고 싶다는 의욕을 얻었습니다.
      DEVOTEE 추천 블로그

      안녕하세요 OpenLab 2기 웹 프론트엔드 성능 최적화 스터디원 정진범 입니다.


      [프론트엔드 성능 최적화] 서적을 가지고 스터디를 진행 중 인데요.

      이번에 4장 이미지 갤러리 최적화에서 이미지 지연 로딩, Redux 렌더링 최적화, 병목코드 최적화에 대해 발표한 내용을 글로 작성 해보려고 합니다.

      이미지 지연 로딩

      문제

      현재 문제는 썸네일 리스트 화면에 보이는 이미지는 18장 이지만 네트워크 Tab에 호출된 이미지 목록을 확인하면 총 295장의 이미지가 호출 된 것을 확인 할 수 있습니다.

      무제.jpg 무제 2.jpg

      한번에 많은 이미지들을 로드하면 브라우저에서 성능저하 문제가 발생하는데 이러한 문제를 이미지 지연 로딩 기법을 사용하여 개선하려고 합니다.


      이미지 지연 로딩 기법에 대해 간단하게 설명하면 이미지가 화면 안에 들어올 때까지 로딩을 미루고 초기 로딩 시간을 줄이고, 페이지 성능을 개선하는데 유용합니다.

      Intersection Observer API, img 태그의 loading 속성 설정 등으로 이미지 지연 로딩 기법을 구현할 수 있는데

      이번에는 react-lazyload 라이브러리를 사용하여 문제를 해결 해보겠습니다.

      최적화

      우선 터미널에 아래의 명령어를 입력하여 react-lazyload 라이브러리 설치 합니다.

      npm i react-lazyload

      설치 후 아래와 같이 LazyLoad 컴포넌트를 Img 컴포넌트에 래핑 해줍니다.

      무제.jpg


      LazyLoad 컴포넌트 추가 후 확인한 결과를 확인하면 화면에만 보이는 이미지는 21장이고 네트워크 탭을 통해 21개의 이미지가 로드된 것을 볼 수 있습니다.

      무제.jpgimage.png

      react-lazyload 라이브러리 활용하여 이미지 로딩 기법을 적용 하기전과 이미지가 로드되는 수가 상당히 줄어든것을 볼 수 있습니다.

      react-lazyload 라이브러리 LazyLoad컴포넌트는 이미지 로딩 기법뿐만이 아니 사용자 경험을 고려한 기능들도 제공합니다.

      Redux 렌더링 최적화

      문제

      현재 Redux 스토어에 썸네일 리스트, header의 카테고리 정보, Modal의 상태들을 구독하고 사용하는데

      썸네일을 클릭하여 이미지 모달이 띄어질 때 썸네일 리스트에서 불필요한 리렌더링이 발생 합니다.

      이러한 문제를 해결하기 위해 아래 3가지 방법으로 불필요한 리렌더링을 줄여 렌더링을 최적화 해보려고 합니다.

      • 객체를 새로 만들지 않고 반환 값을 나누기

      • Equality Funcion 사용하기

      최적화

      1. 객체를 새로 만들지 않고 반환 값을 나누기

      현재 useSelector 훅을 사용하여 상태를 구독하고 객체를 새로 만들어서 새로운 참조 값을 반환하는 형태인데

      문제는 객체를 묶어서 반환하는데 하나의 상태가 변하면 새로운 참조 값의 생성되어 반환되기 때문에 상태가 변하지 않은 부분도 영향을 받아 리렌더링이 발생하는 것 입니다.


      이러한 문제점을 해결하기 위해 기존의 코드를 아래와 같이 객체를 반환하지 않고 단일 값으로 반환 하도록 수정하였습니다.

      무제.jpg 단일 값으로 변경하면 참조 값이 바뀌는 것이 아니므로 useSelector가 반환하는 값은 다른 상태 변화에 영향을 받지 않고 불필요한 리렌더링을 발생 시키지 않습니다.

      2. Equality Function 사용하기

      Equality Function는 이전 값과 현재 값을 비교하는 함수를 말하는데 useSelector 훅 두번째 인자는 Equality Function 받습니다.

      그렇다면 리렌더링 Reudx에서 제공하는 ShallowEqual를 사용하여 리렌더링을 최적화 해보겠습니다.


      아래와 같이 useSelector 훅 두번째 인자에 ShallowEqual를 선언해줍니다.

      무제.jpg

      ShallowEqual에서 값을 비교해서 변화가 없는 상태는 구독하는 컴포넌트는 리렌더링을 일으키지 않는 것을 알 수 있습니다.

      photos 값 filter 메소드를 통해 새로운 배열 값을 반환하여 리렌더링을 일으켜 getPhotos함수로 분리 하였습니다.

      ShallowEqual은 얕은 비교를 하는 함수로 참조값을 비교하지 않습니다.

      useSelector 훅의 Equality Function을 통해 코드를 크게 수정하지 않고 불필요한 리렌더링을 최적화 시킬 수 있습니다.



      병목코드 최적화

      문제

      썸네일을 클릭하여 이미지 모달을 띄울때 상당히 느린 것을 알 수 있는데 개발자 도구의 Performance 패널을 통해 이러한 원인을 파악해봤습니다.

      무제.jpg

      이미지 모달을 띄우는 과정에서 네트워크에서 이미지를 로드 후 getAverageColorOfImage 함수를 진행하는 과정에서 상당히 느리다는 것을 확인 가능합니다.

      이러한 문제를 2가지 방법을 통해 해결 해보았습니다.

      • 메모이제이션으로 코드 최적화하기

      • 함수의 로직 개선

      최적화

      1.메모이제이션 기법

      우선 메모이제이션 기법을 통해 getAverageColorOfImage 함수를 최적화를 해보겠습니다.


      메모이제이션은 한번 실행된 함수에 대해 해당 반환 값을 기억해 두고 있다가 똑같은 조건으로 실행되었을 때 함수의 코드를 실행하지 않고 바로 전에 기억해 둔 값을 반환하는 기법 입니다.

      그러면 아래의 코드와 같이 getAverageColorOfImage에 메모이제이션으로 코드를 최적화 하였습니다.

      무제.jpg

      이전 값을 보관할 변수, 캐싱 데이터 여부 및 값 반환, cache 변수에 데이터 캐싱 로직을 추가 하여 메모이제이션 기법을 추가하였고 최적화가 되었는지 확인해보겠습니다.


      Performance 패널로 확인한 결과 동일한 이미지에 대해 첫 번째 실행했을 때보다 두 번째 실행 했을때 getAverageOfImage 함수가 빠르게 실행된 것을 확인 할 수 있습니다.

      무제.jpg

      하지만 메모이제이션 기법을 사용하여 첫 번째 실행 시간이 단축되지 않아 근본적인 문제가 해결되지 않았는데 코드를 분석하고 로직을 개선하여 최적화를 해보았습니다.

      2. 함수의 로직 개선

      함수의 로직을 개선하여 첫 번째 실행 시간을 단축 해보려고 합니다 그러기 위해서는 우선 문제들을 알아보겠습니다.

      • getAverageColorOfImage 함수를 보면 캔버스에 올린 이미지의 픽셀 정보를 불러오는 drawImage와 getImageData 함수, 모든 픽셀에 대해 실행되는 반복문 작업하는데

        큰 이미지 일수록 픽셀 정보가 많아져 느려지는 문제입니다.

      • 직렬적인 코드 동작인데 modal 오픈 -> modal에 띄어줄 원본 이미지 로드 -> 이미지 로드 뒤 getAverageColorOfImage 함수 실행으로 생기는 문제입니다.

      두가지의 문제를 해결하기 위해 함수 로직을 개선해보겠습니다.


      아래의 코드를 보면 코드의 동작은 modal 오픈 -> modal에 띄어줄 원본 이미지 로드 -> 이미지 로드 뒤 getAverageColorOfImage 함수 실행순 입니다.

      그 과정에서 직렬적인 코드 동작, 이미지 로드 후 큰 이미지를 getAverageColorOfImage 함수 파라미터로 넘겨줘 발생하는 성능 문제 발생합니다.

      무제.jpg. 무제.jpg

      그렇다면 코드가 병렬적으로 동작하게 로직 개선, 로드된 큰 이미지 정보가 아닌 썸네일 리스트의 작은 이미지를 getAverageColorOfImage 함수 파라미터 넘겨 코드를 개선 해보겠습니다.


      아래와 같이 함수 로직을 개선 하였습니다.

      무제.jpg

      썸네일을 클릭할 때 openModal 함수에 썸네일의 작은 이미지 요소를 넘겨 getAverageColorOfImage 함수 파라미터로 넘겨서 실행 시켜주었고

      Modal 오픈 함수와 병렬적으로 동작하게 로직을 개선하였습니다.


      그러면 함수 로직을 개선하였을 때의 결과를 확인해보도록 하겠습니다.

      무제.jpg

      검사 결과 이전과 달리 첫 번째 실행 시 작업시간이 매우 길었던 것과 달리 작업이 매우 빠르게 완료된 것을 볼 수 있습니다.

      참고

      마치면서

      평소 프론트엔드 개발을 하면서도 성능 관련 부분에 대해 신경을 쓰긴 했지만, 이렇게 깊이 있게 분석하고 발표할 기회를 가지는 것은 새로운 도전이었습니다.

      발표를 준비하면서 다양한 자료를 조사하고, 직접 테스트도 해보면서 정말 많은 것을 배웠습니다.


      특히, 페이지 로딩 속도나 이미지 최적화 등 우리가 흔히 사용하는 기술들이 실제로 얼마나 큰 영향을 미치는지 다시 한번 체감할 수 있었습니다.

      발표를 위해 개념을 이해하는 것에서 그치지 않고, 이를 실제 프로젝트에 적용해보면서 '작은 차이가 사용자 경험에 얼마나 큰 영향을 미치는가'를 실감하게 되었죠.


      이번 발표 준비는 저에게 좋은 자극이 되었고, 앞으로도 계속 웹 성능 최적화에 대해 공부하고 개선해나가고 싶다는 의욕이 생겼습니다.

      개발자로서의 역량을 한층 더 높일 수 있는 좋은 경험이었습니다! 😊

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      insunok9507 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기