Skip to content

Releases: boostcampwm-2024/refactor-web31-BooLock

1.1.0

28 Jan 08:30
43ce570
Compare
Choose a tag to compare

REFACTORING

🛠 CICD 개선 (#16)

문제

  • 기존 Github Actions workflow 코드는 3가지의 문제점이 있었다.
    1. build 과정에서 올린 docker hub image를 deploy에서 쓰고 있지 않는다는 점
    2. docker hub 사용 자체를 못하고 있었다는 점
    3. pr올릴때도 deploy가 동작한다는 점
  • workflow 코드 작성법을 제대로 학습하지 않고, 코드를 짜집기 하여 배포가 자동으로 되게끔만 작성했던 것이 cicd 속도를 느리게 하고, 불필요한 스크립트를 동작시키게 한 원인이었다.
  • 아래 두가지 목표를 이루어 cicd 스크립트를 개선하고자 한다.
    1. cicd 소요시간 1분대로 줄이기 (기존 - 약 2분 30초 ~ 3분 소요)
    2. pr / push 별, 브랜치 별 시나리오를 분리하여 불필요한 스크립트 실행 없애기

개선

  • 3가지 빌드 및 배포 시나리오를 짜 속도를 비교하였다.
  • DockerHub를 사용하지 않고 로컬(서버)로 ssh접속해서 docker 빌드 및 배포하기 => 총 44초 소요 (build step: 33s / deploy step: 11s)
  • DockerHub 사용하여 빌드 및 배포(캐싱x) => 총 1분 50초 소요 (build step: 1m 28s / deploy step: 22s)
  • DockerHub 사용하여 빌드 및 배포(캐싱o) => 총 54초 소요 (build step: 39s / deploy step: 15s) (해당 시나리오는 어느 레이어가 캐싱되었느냐에 따라 다르기에 build step의 소요 시간이 일관되지는 않음)
  • 3가지 버전 중 3번째 방식이 이후 버전관리나 확장성에 대비하여 docker hub를 사용하고, 캐싱기능도 있어 빌드 시간은 적기에 3번째 방식을 선택하였다.
  • dev/main 브랜치에 따른 스크립트 파일을 분리하였고, pr/push 에 따라 실행되는 스텝도 분리해두어 pr 작성 시 빌드 테스트 시간을 감축하였다.

결과

  • build 단계 약 40초 / deploy 단계 약 20초로 빌드 및 배포까지 약 1분대로 소요시간 감축

🛠 리렌더링 개선 (워크스페이스 페이지) (#35)

문제

  • CSS 툴팁 컴포넌트 렌러딩 시 모든 CSS 속성 선택 컴포넌트가 리렌더링되는 문제 발생
  • CSS 속성 편집 시 워크스페이스 헤더, 워크스페이스 캔버스 및 관련 없는 컴포넌트들이 리렌더링되는 문제 발생

개선

  • CSS 툴팁 위치 계산 시 활용하던 전역 상태 대신 물음표 아이콘의 위치를 local 상태로 관리하고, 해당 상태를 활용함
  • CSS 속성 관련 상태를 활용할 때 구조분해할당을 통해 상태를 구독하는 방식에서 useStore((state) => state.props) 와 같은 방식으로 필요한 상태만 구독하도록 변경

결과

  • CSS 툴팁 렌더링 시 모든 CSS 속성 선택 컴포넌트의 리렌더링이 일어나지 않음
  • CSS 속성 편집 시 모든 컴포넌트에서 리렌더링이 발생하는 문제를 해결함

BEFORE

Before1

BEFORE

Before2

AFTER

After1

AFTER

After2

🛠 HTTP 1.1 → 2.0 → 3.0 개선 (#27)

문제

  • 우리가 만든 서비스는 http/1.1을 사용하는걸 볼 수 있었다.
  • Lighthouse에서도 2.0을 사용하라고 권장했다.
  • 목표: HTTP에 대한 전반적인 이해와 서비스를 프로토콜을 2.0, 3.0으로 순차적으로 개선해 나가면서 수치를 비교

개선

  • HTTP에 관한 전반적인 역사와 네트워킹 개념 학습
  • Nginx 설정에 HTTP 2 적용
  • QUIC를 기반으로 한 HTTP 3 설정 코드 추가

결과

  • HTTP의 흐름을 순차적으로 공부해나가면서 어떤 방법으로 개선되어 나갔는지 학습.
  • 2.0과 3.0으로 개선하면서 최신 웹 표준 프로토콜을 적용하며 보안을 높임.
  • 성능면으로는 기존에도 좋았기 때문에 큰 차이는 없었음.
    image

🛠 “Code 하이라이팅” 코드 품질 개선 (#36)

문제

  • 코드 하이라이팅 관련 코드가 복잡하고 가독성이 떨어져, 코드의 의도를 파악하기 어려웠습니다.
  • 명확한 코드 품질 기준을 정립하고, 이를 점수로 수치화 후 개선하여 유지보수성을 높이고자 했습니다.
  • 목표: 코드 품질 기준을 확립하고 이를 통한 점수화 후 개선하여 100점 만들기.

개선

  • 여러가지 SonarCloud, Code Climate, DeepSource 등등 측정 도구를 사용하지 않고, 직접 품질 기준을 확립함.
  • “중복 및 불필요한 코드”, “파일 구조 및 명명”, “유지보수성”, “가독성”, “성능 및 안정성” 이 5가지를 품질 기준으로 잡고 점수를 배분함.
  • AI에게 해당 기준을 기반으로 점수 측정을 요청 -> 87/100점
  • customHook, 유틸 함수로 분리하여 단일책임 원칙 준수 , 매직넘버 상수화 등의 개선 작업.

결과

  • 추상화, 중복 코드 제거, 파일 구조 정리, 유지보수성 향상, 가독성 개선
  • 코드 품질 점수 100점으로 향상
  • 유지보수성, 가독성 향상으로 “변경하기 쉬운 코드”로 개선.
    image

🛠 리렌더링 개선 (사용자 가이드) (#37)

문제

  • 사용자 액션에 따라 관련없는 컴포넌트 대부분이 리렌더링되고 있다.
  • 렌더링 성능은 서비스 규모가 커지고 사용자가 많아질수록 직접적인 영향을 미치는 중요한 요소이다.

  • 목표: 불필요한 렌더링을 줄이고, 효율적인 컴포넌트 업데이트 방식을 학습하며 전반적인 성능 개선

개선

  • 렌더링 빈번한 컴포넌트 위주로 해결하려고 하였지만, 리렌더링이 만연해 담당했던 파트인 사용자가이드부터 개선하였다.
  • 리렌더링되는 컴포넌트들의 공통점이 zustand를 활용한 전역상태를 활용한다는 점이었다.
    useShallow를 활용하여 저장된 모든 전역상태가 아닌 사용되는 특정 상태만 가져오도록 개선하였다.
  • 개별 컴포넌트들은 메모이제이션을 적용시 리렌더링이 필요한 경우에만 적용되도록 메모이제이션 커스텀 콜백을 설정하여 제어하였다.

결과

  • 사용자가이드 단계 이동시 더이상 헤더 리렌더링되지 않는다.
  • 헤더 내 버튼들을 하이라이팅해야 하는 4단계만 리렌더링한다.

🛠 자동저장 도입 및 저장 시간 감소 (#38)

문제

  • MixPanel을 활용한 사용자 행동 분석 결과, 34.78%의 사용자가 저장하지 않고 이탈
  • 일부 사용자로부터 작업 손실에 대한 피드백 접수
  • 저장 시간은 약 1.5~1.7초가 소요되며, 블록 수가 증가할수록 저장 시간이 기하급수적으로 증가하고, 저장 진행 중 UI 멈춤 현상 발생
  • 목표:
    (a) 자동 저장을 통해 의도하지 않은 데이터 유실 및 사용자의 실수 방지 + 작업 흐름을 개선

    (b) UI 멈춤으로 인해 사용자가 저장 과정에서 불편을 겪고 이탈하는 것을 방지

개선

  • 자동 저장 기능 도입
    - 사용자의 작업 변화를 감지해 자동 저장을 수행하도록 결정.
    - zustand 상태 관리 라이브러리를 활용하여 작업 변경 여부를 전역 상태에서 Boolean 값으로 관리, 변경이 감지되면 저장 로직 수행.
  • 성능 문제 분석 및 개선
    - 자동 저장 적용 후에도 UI 멈춤 현상 지속.(평균 1.51.7초 소요, 최대 69초 이상 발생)
    - 원인 분석을 위해 크롬 브라우저 아키텍처 및 렌더링 프로세스 학습 및 main thread의 역할 이해
    - 개발자 도구의 Performance 탭을 활용해 JS 작업이 main thread를 블로킹하는 것을 확인
    - 어떤 JS 작업이 블로킹하는지 파악하기 위해 performance.now()로 저장 과정의 각 단계별 소요 시간 분석
    1. 저장 과정 중 썸네일 생성을 위해 html2canvas를 활용한 웹페이지 캡처가 가장 큰 성능 저하 요인(평균 1.5초 소요)
    2. 캡쳐 이미지 만들기 위해 canvas -> blob으로 변환 과정이 두 번째로 많은 시간 소모(평균 0.3초 소요)
  • 성능 최적화 조치
    - html2canvas 최적화: 라이브러리 옵션을 사용해 불필요한 DOM 요소의 스타일 계산 제외
    - Web Worker 및 OffscreenCanvas 도입, blob 변환 및 이미지 생성 작업을 별도 스레드에서 처리

결과

  • 최적화 적용 후 전체 저장 시간 69초 → 0.20.3초로 단축
  • 자동 저장 기능 도입으로 수동 저장 버튼 클릭 단계 제거, 사용자 인터랙션 간소화

1.0.1

17 Jan 07:35
f2d576c
Compare
Choose a tag to compare

REFACTORING

🛠 Docker 이미지 최적화 (#12)

문제

  • 백엔드 Docker 이미지 크기는 631MB이고, 프론트엔드 이미지 크기는 59.4MB이다.
  • 백엔드는 프론트엔드처럼 정적파일을 만들어 배포할 수 없고, 동작하기 위해선 라이브러리가 필요하기에 사이즈가 큰 것은 어쩔 수 없다.
  • 허나 비교적 종속성이 복잡하지 않고 단순한 서버 라이브러리인 node.js+express로 개발하였고, 백엔드 규모 자체도 크지 않은 프로젝트이기에 적정 사이즈는 200~400MB 사이라고 생각하였기에 줄일 필요가 있다고 생각했다.
  • 목표: 백엔드 이미지 사이즈를 400MB대로 줄이는 것

개선

  • 멀티 스테이지 빌드 방법을 적용하여 빌드 파일 생성용 이미지와 배포용 이미지를 분리
  • 명령어 체이닝을 적용하여 레이어 수를 감소
  • 레이어 캐싱 기능을 효율적으로 활용하고자 변경사항이 적은 레이어는 상단에 배치

결과

  • backend이미지는 631MB -> 266MB로 줄었고, frontend이미지는 59.4MB -> 51.6MB로 감소

🛠 홈페이지 가상스크롤 적용 (#14)

문제

  • 기존 무한스크롤은 데이터를 렌더링할 때 모든 데이터를 DOM에 추가하여 렌더링하였습니다.
  • 이는 적은 양의 데이터를 불러왔을 때는 문제가 없었지만 약 1,000개 이상의 데이터를 렌더링하면 브라우저의 성능 저하되는 문제가 있었습니다.

개선

  • 현재 ViewPort를 고려하여 꼭 렌더링해야할 데이터만 렌더링하는 가상스크롤을 적용하였습니다.

결과

  • 아래는 데이터 5,000개를 불러온 결과입니다.
    가상스크롤 적용 전
    C4756900-23ED-4284-9F4C-2146E3655AB7

가상스크롤 적용 후
CE41A147-9497-4C35-880B-7625E36DB1AC


🛠 Google Analytics 적용 (#15)

문제

  • 이전에 SEO와 Open Graph를 활용하여 사용자 유입률을 높이고 접근성을 개선한 경험이 있다.
  • 하지만, 이를 실제 지인들을 대상으로 테스트했기 때문에 정확한 데이터를 기록하거나 분석하지 못했다.
  • 이에 따라 유입 경로, 이탈률, 사용 빈도가 높은 페이지 등 사용자 행동 데이터를 기반으로 정확한 수치를 분석할 필요가 있다는 점을 느낌.

개선

  • Google Analytics를 활용
  • gtag.js 스크립트를 index.html의 에 삽입하여 설정
  • 각 이벤트 발생 시 dataLayer에 이벤트가 저장되고, GA로 전송되어 보고서가 작성됨

결과

  • 실시간으로 최근 30분간 사용자 수, 지역, 페이지 방문, 동작 기록 확인 가능.
  • 보고서를 통해 사용자 수, 평균 사용 시간, 유입 경로, 브라우저, 국가 분포, 신규·재방문 비율 등을 확인 가능.
  • 주요 이벤트(page_view, scroll, session_start 등)와 활성 사용자 수를 1일, 7일, 30일 단위로 분석 가능.
    image

🛠 이벤트 트레이싱 (#17)

문제

  • 수치화된 사용자의 행동을 토대로 개선하고 싶은 문제를 정의하고자 함

개선

  • 사용자의 행동을 수치화할 수 있게 됨

결과

  • 저장 과정이 사용자의 행동 플로우에서 빈번하게 발생하며 워크스페이스에서 작업하는 과정을 끊는 것을 발견. 수동 저장을 자동 저장으로 변경하기로 결정함
    image

image


🛠 useQuery, useInfiniteQuery -> useSuspenseQuery, useSuspenseInfiniteQuery 교체 (#19)

문제

  • 기존 비동기 데이터를 불러오는 컴포넌트에서는 로딩 여부에 따라 로딩 UI 렌더링을 결정했습니다.
  • 이는 명령형 프로그래밍 방식으로 React의 철학과 맞지 않았습니다.

개선

  • React 철학인 선언적 프로그래밍에 맞게 useQuery, useInfinityQueryuseSuspenseQuery, useSuspenseInfinityQuery로 변경하고 기존 로딩 여부를 판단하기 위한 if문을 삭제하고 Suspense의 fallback을 통해 로딩 UI를 렌더링하도록 변경하였습니다.

🛠 HTTP/1.1 -> HTTP/2.0 개선

문제

  • 네트워킹의 흐름을 학습하며, HTTP/2.0이 제공하는 더 많은 기능을 통해 속도, 보안, 효율성을 향상시키는 개선 작업을 진행하고, HTTP/1.1과 2.0의 차이를 수치로 직접 비교해보기 위해서.
  • Lighthouse 결과도 HTTP/2.0 적용을 권장

개선

  • Nginx 설정 파일(default.conf)에 http2 on; 옵션 추가.

결과

  • HTTP/2.0 적용 완료.
  • 눈에 띄는 성능 변화는 없었지만, 멀티플렉싱과 효율적 데이터 전송으로 향후 확장성 및 최적화 기반 마련.
    image

1.0.0

17 Jan 07:04
dcd92f6
Compare
Choose a tag to compare
🙀 chore: 수정