ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [이미지/웹 성능 최적화] 3년 뒤에 다시 만난 나의 코드, 친구의 회사 사이트를 좋은 부품으로 교체하다.
    나의 개발 기록과 회고록 2025. 2. 18. 15:08

    개발 배경

    1년차때, 디자인 에이전시를 운영하는 친구의 부탁으로 회사 사이트를 빠르게 만들어서 배포했다. 컴포넌트 나누는 기준이나 로직의 추상화, 레이어 설계 등 고려하지 못한 신입 시절이라서 다시 보기 어려웠다. 연락이 닿아서 이런 저런 얘기하다가 이미지 변경 요청을 받고 오랜만에 코드를 열어봤다.

     

    너무 심각했고, 나에게 이런 시절도 있었구나 생각이 들었다. 사용도 안하던 라이브러리들, 페이지마다 반복되던 로직들, 이미지 최적화가 안되어서 2~3초 기다려야 로딩되는 메인 페이지 등 얼마 보지 못하고 새로운 레포지토리를 세팅하게 되었다.

     

    사실 이미지만 공유하고 호스팅 연결하면 되는 스펙이고 이직을 준비하면서 남는 시간에 마이그레이션 하는 상황이라서 많은 리소스를 투여하지 못했다. 몇가지 기준과 목표를 잡고 작업을 시작했다.

    개발 목표 및 스택 선정

    1. 개발 목표

    • SEO 최적화 작업
    • 이미지가 늦게 렌더링되는 이슈 해결
    • 무거운 앱을 가볍게 다이어트하자.
    • 욕심으로 리소스가 과하게 투자되는 것을 경계하며 작업하자.

    2. 개발 스택

    • Vite
    • React
    • Styled-components
    • Netlify

    작업 내용

    1. CRA -> Vite(EsBuild) 마이그레이션

    CRA는 리액트를 처음 접하는 개발자 혹은 보일러플레이트 세팅 경험이 없는 개발자에게 좋은 선택이다. 하지만 실제로 사용하지 않는 방대한 양의 코드가 함께 설치된다. 당연히 번들 사이즈가 기대 이상으로 커지며, 유지보수 관점에서도 좋지 않다. 사이트 자체가 규모가 크지 않고 API 통신 없이 Static한 컨텐츠와 로직으로 구성되어있어서 최대한 빠르고 가볍게 마이그레이션을 진행하고 싶었다.

     

    Vite는 이런 고민들을 해결해준다. webpack, rollup 등 번들링 도구보다 속도 측면에서 압도적으로 빠르다. Vite의 개념이나 장단점은 꼭 검색해서 스터디하면 좋을 것 같다. 선택한 이유는 간단하다. 가볍고, 파일 크기가 작아지고, 빠르고, 보일러플레이트 세팅이 편하다.

    Vite의 엄청난 속도

     

    2. 이미지 최적화 및 유저 경험 개선

    타이핑 -> 메인 페이지 과정

    타이핑 효과가 끝나고 메인 페이지로 라우팅 되는 과정에서 메인 이미지가 준비되기 직전에 깜빡거리는 이슈가 있었다. vite로 마이그레이션 전, 네트워크 상태가 좋지 않은 경우 더욱 심각하게 발생했다. 메인 페이지에서는 이미지를 하나씩 넘기는 슬라이드 기능에서도 마찬가지로 로딩이 되기 전의 이미지 노출이 되는 문제가 있었다. 이를 해결하기 위해 아래의 방법을 사용했다.

    • 페이지의 상단이나 대표하는 이미지를 WebP 파일로 변환
      • WebP는 PNG나 JPEG 등 다른 확장자보다 파일 크기가 작아 로딩이 압도적으로 빠르다.
      • 파일 크기가 작아지지만 품질도 유지한다.
    • 이미지 PreLoading 로직 추가
      • App이 마운트 되는 과정에 대표되는 이미지들을 미리 로드하는 작업을 추가
      • 유저 접속 후, 타이핑 되는 화면에서 대표 이미지가 캐싱
    const preLoadImages = (images: string[]) => {
      const loadImg = images.map((url) => {
        return new Promise<void>((resolve) => {
          const img = new Image()
          img.onload = () => resolve()
          img.src = url
        })
      })
    
      return Promise.all(loadImg)
    }
    
    export default preLoadImages

     

     

    이미지 최적화와 PreLoading 적용 후, 해당 이슈는 해결되었다. 타이핑 페이지에서 미리 이미지를 캐싱하고, 메인 페이지에서 필요한 이미지를 새롭게 로딩하지 않는다. 

     

    이미지 최적화 이후

     

    WebP 적용, PreLoad 적용

    3. SEO 최적화(robots.txt, sitemap, meta tag 등)

    이제 우리의 무적 사이트는 가볍고 빠르게 유능한 디자이너들의 작품을 클라이언트에게 전달할 수 있다. 하지만 이전에는 회사명을 구글에 적어도 노출이 맨 위에 되지 않았다. 당시 SEO는 필요하지 않았고 단순히 영업하는 과정에서 포트폴리오 사이트를 보여주면 된다는 친구 아니 고객님의 요구에 다음을 기약하며 마무리했었다. 

     

    하지만 이제는 빠릿빠릿하게 새로 태어났으니 SEO 최적화도 진행해보자. 먼저 Lighthouse 검색엔진 최적화 점수부터 확인해보자.

     

    그렇다 아직 좀 아프다. 진단이 끝났으니 하나씩 해결해보자.

    • Meta tag 추가
      • 메타 태그를 추가하는 이유는 웹페이지에 대한 정보를 검색엔진과 크롤러에 제공해서 검색결과를 노출시키기 위함이다.
      • 브라우저가 훑어보는 요약본이라고 표현할 수 있다.

    메타태그

    • public에 robots.txt 파일 추가
      • 웹사이트의 크롤러가 접근했을 때, 제어해주는 역할을 한다.
      • 마찬가지로 검색엔진 최적화를 위해 설정하는 것이 좋다.

    public 위치에 robots.txt를 추가

    • sitemap.xml 파일 추가
      • 사이트맵을 추가하면 검색 엔진이 사이트 구조를 미리 파악할 수 있다. 
      • 해당 사이트의 최근 변경 사항을 빠르게 인덱싱하는 역할

    해당 작업으로 검색엔진 최적화를 진행하고 Lighthouse 검사를 다시 진행했다. 

    적용 전
    적용 후
    검색 상단

    회고

    가장 충격적인 부분은 3년전 코드를 마주한 현재이다. 내가 이런 시절도 있었구나, 어떠한 생각을 이런 무지막지한 코드를 작성했는지 당혹스러웠다. 지금 마이그레이션 하는 과정에서 리소스 절감을 위해서 전체적인 구조는 크게 건드리지 않았다. 

     

    이미지 최적화나 웹앱 최적화에 대한 개념이나 방법은 알지만 현업에서 직접 개선할 기회는 많지 않았다. 특히 CDN을 사용해서 이미지 캐싱하는 부분도 혼자서는 해봤지만 현업에서는 경험하지 못했다. 이미 완성되어있는 경우가 대다수였고, 크게 이슈가 없었다. 

     

    그밖에도 Lazy loading과 Code Splitting 작업도 최적화를 위한 방법이지만, 이번 작업에서는 오버스펙일 것으로 판단되어 제거했다. 다음으로 Next.js를 사용해서 포트폴리오 사이트와 블로그를 개발하면서 시도해봐야곘다. 

Designed by Tistory.