Published on

Highlighters

프로젝트 요약

  • 개발 기간 : 2022.12.23 ~ 2023.01.27
  • 기술 스택 : React, Recoil, React query,Tailwind CSS
  • 깃허브 : 바로가기
  • 크롬 익스텐션을 통해 텍스트, 이미지, 영상에 하이라이팅하고, 기록을 저장할 수 있습니다.
  • 동일한 웹사이트에 접속했을 때, 그룹원이 하이라이팅한 내용이 내 화면에도 실시간으로 반영됩니다.
  • 공유한 자료를 아카이빙하고, 북마크 및 태그 기능을 통해 쉽게 찾아볼 수 있습니다.
  • 그룹원에게 메시지 및 링크 알림을 보낼 수 있으며, 클릭시 해당 링크로 이동할 수 있습니다.
  • 검색 기능을 통해 공유된 피드를 쉽게 찾을 수 있습니다. (과금 문제로 현재는 일반 검색 기능만 작동합니다.)

프로젝트 개요

저희는 중요한 내용을 빠르고 간편하게 공유하고자 하는 3가지 고민에서 'Highlighters'라는 협업 툴을 개발하게 되었습니다.
이 협업 툴을 사용하면 웹페이지에서 한 눈에 중요한 내용을 파악할 수 있으며, 바로바로 그룹원들과 링크를 공유할 수 있습니다.
또한, 공유한 링크를 찾아보기 쉽게 모아둘 수 있어 편리합니다.'Highlighters'는 크롬 익스텐션을 활용하여 텍스트, 이미지, 유튜브 동영상 등 다양한 요소를 하이라이팅할 수 있습니다.그리고 이를 그룹 간에 공유하여 정보 공유를 간편하게 할 수 있습니다.
이러한 기능들을 통해 'Highlighters'는 메신저를 통한 정보 공유가 시간 낭비가 될 수 있는 경우, 중요한 부분을 빠르게 파악하고 공유하는 데 유용한 협업 툴이 되고자 합니다.


프로젝트 기여

1. 세차례 걸친 메인 페이지 렌더링 성능 개선

서비스 배포 이전에 저희 팀은 베타버전 출시 후 사용자 30명의 피드백을 분석해보았고,이 과정에서 메인 페이지의 로딩이 느리다는 피드백을 받았습니다.
이에 대응하기 위해 프로파일링을 실시하였고, LCP를 2.5초로 개선할 필요성을 인지하였습니다.

첫번째 개선

피드 컴포넌트 내부의 이미지 로딩 시간이 길다는 것을 파악하였고, 원본 이미지 대신 컴포넌트 크기에 맞게 리사이징한 이미지를 사용하면 성능 개선이 가능할 것으로 판단했습니다.sharp 라이브러리를 활용해 이미지를 리사이징하고, 리사이징된 이미지를 s3에 저장했습니다.
이를 통해 이미지 크기가 피드 5개 기준으로 1,008KB에서 472KB로 감소하여 LCP를 0.3초 가량 개선할 수 있었습니다.

두번째 개선

뷰포트 내에서 사용자가 볼 수 있는 피드는 3~4개 였기 때문에 모든 피드를 한꺼번에 로드하는 과정이 불필요하다고 판단하였습니다.
또한 불안정한 네트워크 환경까지 고려하여 한번에 로드하는 피드의 수를 12개로 셋팅하였고, 이 결과 LCP를 0.2초 가량 개선할 수 있었습니다.

세번째 개선

사용자에게 즉시 보이지 않는 피드를 렌더링하는 것은 불필요하다고 판단했습니다.
따라서 사용자가 피드를 로드할 때 모든 피드를 렌더링하는 대신, 스크롤을 내리며 보이는 피드만 렌더링하는 효율적인 방식을 선택하였습니다.
이를 구현하기 위해 Lazy Loading을 적용했고, 사용자가 스크롤을 내려 피드가 뷰포트에 들어올 때만 렌더링되는 방식으로 구현하였습니다.

결과

해당 개선사항을 통해 LCP를 1.6초로 크게 감소 시킬 수 있었습니다. 현재까지도 꾸준히 수정하고 있으며 최적화 훅이나 'virtual scroll'을 활용한 추가적인 개선도 고려하고 있습니다.

2. Suspense 기능을 활용하여 비동기처리 로직 개선

프로젝트가 커지면서 서버에서 데이터를 가져오는 비동기 로직이 많아지고, 이로 인해 코드의 가독성이 저하하는 문제가 발생했습니다.
특히, 로딩 중일 때 'isLoading' state를 사용하여 스켈레톤 UI를 렌더링하는 것이 코드 이해를 어렵게 만들었습니다.
이후 React v18에서 개선된 Susense 기능을 적용하여, 비동기 로직을 수행하는 컴포넌트에 Suspense 컴포넌트를 래핑한 것만으로 비동기 데이터 패칭이 가능했습니다.
이를 통해 비동기 로직을 간결하고 동기적으로 작성할 수 있었고, Error Boundary를 활용하여 유연한 에러 상황 처리까지 쉽게 처리해줄 수 있었습니다.

3. 로딩 시 스켈레톤 컴포넌트 활용 FCP 개선

사용자 정보, 피드, 알림 등 많은 데이터를 서버에서 가져와 페이지에 렌더링 해야 했고, 데이터를 로딩 할 때는 사용자가 빈페이지를 보고 있어야 했습니다.
사용자가 빈페이지를 보고 있으면 이게 로딩 중인 건지 에러인 건지 파악할 수 없다고 판단했습니다.
이를 해결하기 위해 스켈레톤 컴포넌트를 적용하여 웹사이트나 애플리케이션에서 비동기 데이터를 로드하는 동안 사용자에게 로딩 중임을 시각적으로 알려주었습니다.
스켈레톤 UI를 적용하면 사용자는 비동기 작업이 완료될 때까지 빈 화면이나 로딩 스피너만 보는 것이 아니라 예상되는 콘텐츠가 어떻게 보일지 미리 확인할 수 있어 불안감을 줄이고 더 나은 사용자 경험을 제공할 수 있었고, 프로파일링을 통해 측정한 FCP 1.1초에서 0.7초로 개선할 수 있었습니다.

4. 이미지 Lazy Loading 활용 LCP 개선

하이라이터즈의 ‘그리드 뷰' 기능을 사용하면 많은 피드들을 한번에 모아 볼 수 있습니다.
기존보다 많은 양의 피드가 뷰포트 내에 한번에 보여지는데 내부에 포함된 이미지가 많아서 로딩에 필요한 리소스가 많이 발생할 것 이라는 생각이 들어 프로파일링을 진행했고 LCP가 1.9초로 확인되었습니다.
이 후 뷰포트에 있는 이미지 즉, 당장 로드가 필요한 이미지만 로드하면 되겠다는 생각이 들었고,
이미지가 뷰포트에 들어왔을때만 로드하는 Lazy Loading을 적용하였고, 프로파일링 재측정 결과 LCP 1.9초에서 1.6초로 개선되었습니다.