[웹 성능 최적화] 실습1: 블로그 사이트 최적화

April·2023년 1월 1일
0

React🚀

목록 보기
37/43
post-thumbnail
post-custom-banner

목표

  • 로딩 성능 최적화
    • 이미지 사이즈 최적화: 적절한 이미지 사이즈 찾기
    • code split: 효율적인 코드 분할. 언제 코드 분할
    • 텍스트 압축: 리소스 다운받기 전 압축 ➔ 다운받기 전 리소스 줄여서 로딩 성능 최적화
  • 렌더링 성능 최적화
    • bottleneck 코드 최적화: 병목현상 코드 찾아서 최적화 시키기

실습툴

  • 크롬 Network 탭: 네트워크 리소스 정보
  • 크롬 Performance 탭: 웹 페이지가 동작할 때 실행되는 모든 작업 표시
  • 크롬 Audit 탭 (Light house): 서비스 성능 수준 파악
  • webpack-bundle-analyzer: 웹팩 라이브러리


성능 최적화

실습할 사이트의 크롭 dev tool을 열고 Lighthouse 탭에서 성능 측정하기

Light house 체크

  • 실습할 사이트의 어느 부분에서 점수가 낮은지 확인 후 해당 부분을 집중적으로 개선하기!
    • Performance 에서 점수가 낮을 것을 확인할 수 있다

  • 스크롤을 아래로 내려보면 OPPORTUNITIES 영역과 DIAGNOSTICS 영역으로 구분해서 개선하면 좋겠다 하는 부분을 알려주는데
    • OPPORTUNITIES 영역은 로딩 부분에 해당하고
    • DIAGNOSTICS 영역은 렌더링 부분에 해당한다
  • 각 항목을 클릭해보면 항목에 대한 설명과 그 하단에는 상세 설명이 있다


개선 사항 적용해보기

1. 이미지 최적화

방법1: Image CDN

🤔 (서버에서 받아 온 이미지를 프론트엔드에서) 어떻게 하면 이미지 사이즈를 줄여볼 수 있을까?

  • 이미지 CDN을 이용해보자!

💡 CDN(Contents Delivery Network) 이란?

  • 물리적 거리의 한계를 극복하기 위해 소비자(사용자)와 가까운 곳에 컨텐츠 서버를 두는 기술

    • 예시)

      • 한국 사용자가 미국 서버의 이미지를 다운받고자 할 때, 물리적인 거리가 있어 다운 속도에 영향을 미칠 수 있는데
      • 한국에 이미지 서버를 두고 한국 사용자가 바로 다운로드 할 수 있다면 다운 속도가 개선될 수 있다


💡 Image Processing CDN 이란?

  • CDN과는 개념이 다른데, 사용자에게 보내기 전 필요사항(이미지 사이즈 변경, 포맷 변경 등)에 대해 미리 가공해서 보내는 기술

    • 예시)
  • 사례) 실제 사용 사이트


방법2: unsplash의 이미지를 사용할 경우

https://unsplash.com/documentation#supported-parameters

function Article(props) {
    /* 파라미터 참고: https://unsplash.com/documentation#supported-parameters */
  const getParametersForUnsplash = ({width, height, quality, format}) => {
    return `?w=${width}&h=${height}&q=${quality}&fm=${format}&fit=crop`
  }
  
  return (
    <div className={'Article'}>
      // ... 생략
      <div className={'Article__thumbnail'}>
        <img src={props.image + getParametersForUnsplash({width: 240, height: 240, quality: 80, format: 'jpg'})} alt="thumbnail" />
      </div>
    </div>
  )
}

2. 코드 최적화: Performance

Bottleneck 코드 탐색: Performance

Performance 탭 설명

(1) 어떤 타입의 작업들이 어느 정도의 비율로 진행이 되었는지, 페이지 전체의 타임라인 확인

  • 선택해서 보거나, 더블클릭해서 해당 영역만 볼 수 있다

(2) 위에서 선택한 내용에 대해 프레임 (3)차트 형태로 상세하게 확인 가능

(4) (클릭하면) 네트워크 타임라인

(5) JS 실행 관련 내용


Performance 탭 분석

(1) html 다운 후 파싱

(2) js 다운 후 실행

(3) FP: First Paint

Box: JS 코드가 끝난 시점

(1) Onload Event 발생 시점

  • 가비지컬렉터 시점도 알 수 있다

  • 리액트 사이트일 경우 Timings에서 컴포넌트 이름도 확인할 수 있다
    • 위의 그림을 보면 Article 컴포넌트가 오래 실행되고 있음을 알 수 있다

  • 더 자세히 살며보면 removeSpecialCharacter 가 여러번 쪼개서 실행되고 있는데
  • 여러번 실행된 것이 아니라 한 번 실행되는 중에 메모리가 부족해서 가비지컬렉터에 의해 끊긴 것..🥲

🤓 아하!!

이 과정을 통해 Article 컴포넌트의 removeSpecialCharacter 찾아 개선하면 되겠다!라고 생각해 볼 수 있다!


3. Code Splitting

bundle 파일 분석 (bundle analyzer)

설치

// webpack을 별도 커스텀하지 않고 사용하기
npm i --save-dev cra-bundle-analyzer
yarn add -d cra-bundle-analyzer
npx cra-bundle-analyzer

파일 위치 보여주는 곳에서 확인하면 아래와 같이 열린다

위에서 보면 refractor가 크게 차지 하고 있음을 알 수 있는데 package-lock.json에서 검색해보면 react-syntax-highlighter에서 사용됨을 확인할 수 있다

🤓 아하!!

이 과정을 통해 react-syntax-highlighter라는 모듈을 초반에 로딩시키지 말고 필요한 페이지에서 로딩시키면 해결되지 않을까?

Code Splitting & Lazy Loading 적용

코드 적용

import React, { Suspense, lazy } from 'react';
import { Switch, Route } from 'react-router-dom';
import './App.css';
// import ListPage from './pages/ListPage/index';
// import ViewPage from './pages/ViewPage/index';

const ListPage = lazy(() => import(`./pages/ListPage/index`));
const ViewPage = lazy(() => import(`./pages/ViewPage/index`));

function App() {
  return (
    <div className='App'>
      <Suspense fallback={<div>Loading...</div>}>
        <Switch>
          <Route path='/' component={ListPage} exact />
          <Route path='/view/:id' component={ViewPage} exact />
        </Switch>
      </Suspense>
    </div>
  );
}

export default App;

코드 수정 후 다시 적용해보면 chunk 파일이 분리가 된 것을 확인해 볼 수 있다

npx cra-bundle-analyzer


4. 텍스트 압축

CRA는 Dev 환경과 Prod 환경의 성능 차이점이 발생할 수 있으므로 Prod 환경에서도 Light house 체크를 해보자! 즉, 성능 향상을 위해서는 Prod 환경에서도 체크해보자!

웹 페이지를 로드할 때에는 Html, CSS, JSText로 이루어진 리소스를 다운받게 되는데 파일 사이즈가 클 수록 로딩 속도가 오래 걸리기 때문에 압축 방법을 적용하면 다운 로드 성능에서 최적화를 경험할 수 있다

Prod 환경에서 실행 후 Light house 체크를 해보면 Enable text compression 항목이 나타난다.
하단 파일이 압축이 안 되어있다는 소리..

실제 코드에서 압축이 되어있는지 확인은 네트워크 탭에서 확인할 수 있고,
현재 Article 컴포넌트는 Content-Encoding 항목에서 gzip 형식으로 압축됨을 확인할 수 있는데
main 파일이나 다른 번들 파일에서는 Content-Encoding 항목을 찾아볼 수 없다. 즉 압축되지 않았다..

압축은 클라이언트가 아닌 서버에서 보내줄 때 압축해서 보내야 하므로 서버 코드를 살펴보자.

확인해보니 압축하지 말라는 옵션이 추가되어 있었음..
-u 옵션을 삭제해보고 다시 서버를 실행해보면 Content-Encoding 항목에서 gzip 을 찾아볼 수 있다

단, 주의해야 할 점은 압축 해제하는 시간도 고려하여 모든 파일을 압축하기 보다 2KB 이상되는 파일만 압축하는 것도 방법!



profile
🚀 내가 보려고 쓰는 기술블로그
post-custom-banner

0개의 댓글