프론트엔드 성능최적화 (2)

KyungminLee·2021년 6월 28일
3

😃 블로그 사이트 최적화 part1

👉 Lighthouse로 성능측정

크롬에서 제공하는 웹사이트의 성능을 측정하는 도구이다. 모바일, 데스크탑 모두 지원하며, 카테고리에는 Perfomance, Progressive web app, seo 등 다양한 지표가 있다.

위 지표를 보면 100점 만점에 44점의 성능이 나왔다. 다음 사진을 보게되면 어느 부분에서 성능이 저하 되었는지 확인할 수 있다.

👉 로딩 성능 최적화

1. 이미지 사이즈 최적화

웹 서비스에서 다양한 이미지를 사용한다. 하지만 이러한 이미지의 사이즈가 너무크면 서비스가 무거워 질 것이다. 또한 사이즈가 너무 작으면 저화질이여서 불편함을 느낄 수 있다. 어떤 사이즈가 적당한지 체크해야 한다.

위 사진에서 보여지는건 120 x 120이지만 실제 사진 사이즈는 1200 x 1200 이다. 이때 사진 사이즈를 240 x 240으로 주는게 적당하다.(2배)

프론트에서 사진 사이즈를 직접 줄여도 되지만.. 백엔드에서 받아오는 경우 직접 줄이기 힘들다.
이럴때 CDN(Contents Delivery Network)을 이용한다. 다음은 서버에서 받아오는 API 데이터이다.

(1) CDN이란?

  • 지리,물리적으로 떨어져 있는 사용자에게 컨텐츠를 더 빠르게 제공할 수 있는 기술
  • 느린 응답속도 / 다운로딩 타임 을 극복하기 위한 기술

ex) 홈페이지가 한국에 있고 내가 사용하던 카페24의 서버에 호스팅되어 있다고 하면.
그 호스팅된 공간에 내 홈페이지 이미지가 있고 미국에 거주하는 이용자가 사이트를 접속했을 때 서버는 미국 이용자의 요청을 받아서 이미지를 한국에 있는 서버에서 호출하고 보여주게 된다.

하지만 물리적 거리가 멀기 때문에 어느정도의 시간 지연이 발생한다. 이를 보완하기 위해 CDN 서비스는 서버 자체를 여러곳에 두고 이용자가 요청했을때 제일 근접한 서버에서 처리함으로써 지연되는 시간을 줄여 준다.

(2) Image CDN

이미지를 사용자에게 보내기 전에 가공을해서 사용자에게 전달한다. (이미지 포맷 변경 및 사이즈 변경) http://cdn.image.com?src=[img src]&width=200&height=100 형태이다.

2. Code Split

어떻게 해야 코드를 효율적으로 분할 할 수 있는지, 언제 코드를 분할해야 하는지 확인해야 한다.

(1) bundle 과 chunk

  • bundle : Webpack에서는 자바스크립트를 포함하여 여러 리소스들을 연결한(Concentarte) 결과물이다. bundle은 여러 개의 Chunk로 구성된다.

  • chunk : 모든 코드를 하나의 거대한 파일(bundle)로 만들지 않기 위해서 여러개의 chunk라는 단위로 나눈다. 코드가 어떻게 나뉘는지에 대한 방법도 임의로 구성할 수 있다.

(2) bundle 파일분석(bundle-analyzer)

초기 로딩시 하나의 chunk.js 리소스 파일만 다운로드 시간이 엄청 긴 걸 확인할 수 있다. 자바스크립트가 다운로드 된 시간부터 코드가 실행되기 때문에 초기 로딩속도가 엄청 느려지게 된다.

chunk 파일의 상세 내용을 보기위해 webpackbundle-analyzer 을 사용한다. webpack을 통해 번들링 된 파일들이 어떻게 구성되어 있는지 확인할 수 있다.

위의 사진을 보면 npm을 통해 설치한 node_modules 안에있는 라이브러리 들이다.

많은 js 라이브러리가 있는데 이러한 목록 출처을 package.lock.json 에서 확인할 수 있다. 우리가 사용하고 있는 모듈들의 하위 dependency 목록을 보여준다.

여기서 우리가 화면마다 필요한 모듈만 불러오게 된다면 초기 로딩속도를 더 빠르게 할 수 있을 것이다.

(3) Code Splitting & Lazy Loading

Code Splitting : 불필요한 코드 또는 중복되는 코드가 없이 적절한 사이즈의 코드가 적절한 타이밍에 로드될 수 있도록 하는 것

< 최적화 되지 않은 코드 >

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

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

< 최적화 된 코드 >

import React, { Suspense, lazy } from "react";
import { Switch, Route } from "react-router-dom";
import "./App.css";
const ListPage = lazy(() => import("./pages/ListPage/index"));
const ViewPage = lazy(() => import("./pages/ViewPage/index"));

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

최적화 된 코드를 적용 했을 시 번들링 된 파일들이 아래와 같이 구성된다.

Network에서 확인해보면 아래와 같이 여러개의 chunk.js 파일이 생성된 것을 확인할 수 있다.

3. 텍스트 압축


페이지에 접속하게 되면 다양한 리소스를 받는다. Javascript, CSS, HTML 들이 있는데, 미리 이러한 파일들을 서버에서 압축 해가지고 받게된다. 그러면 작은사이즈가 되고, 더 빠르게 로드가 될 것이다.

chunk 리소스 파일을 확인해 보면 gzip 형태로 압축해서 넘어오는 것을 확인할 수 있다.

👉 렌더링 성능 최적화

1. Bottleneck 코드 최적화

내가 어떤 서비스를 개발 했는데 특정 자바스크립트 코드 때문에 느리게 실행될 수 있다. 어떤 코드 때문에 느리게 작동하는지 그 코드를 찾고, 해결할 수 있는 방법을 찾을 줄 알아야 한다.

크롬 개발자도구의 Performance 탭에서 어느 부분이 시간이 오래걸리고, 병목이 생기는지 확인할 수 있다.

위 사진을 보게 되면 Article 이라는 컴포넌트에서 오랫동안 실행되고 있는 것을 확인할 수 있다.

위와 같이 어떤 함수에서 오래 걸렸는지 더 자세히 확인 할 수 있다. 세 가지 방안으로 최적화를 할 예정이다

  • replace 함수와 정규식 사용
  • 마크다운의 특수문자를 지워주는 라이브러리 사용(remove-markdown)
  • 작업하는 양 줄이기(실제 보이는 데이터 수만 작업하기)

다음은 removeSpecialCharactor 함수 내 최적화 되지 않은 코드와 최적화 된 코드이다.

< 최적화 되지 않은 코드 >

/*
 * 파라미터로 넘어온 문자열에서 일부 특수문자를 제거하는 함수
 * (Markdown으로 된 문자열의 특수문자를 제거하기 위함)
 * */
  let _str = str;
  let i = 0,
    j = 0;

  for (i = 0; i < removeCharacters.length; i++) {
    j = 0;
    while (j < _str.length) {
      if (_str[j] === removeCharacters[i]) {
        _str = _str.substring(0, j).concat(_str.substring(j + 1));
        continue;
      }
      j++;
    }
  }

< 최적화 코드 >

  let _str = str.substring(0, 300);
  _str = _str.replace(/[\#\_\*\~\&\;\!\[\]\`\>\=\-\n]/g, "");

  return _str;

최적화 코드로 작성 했을 시 아래와 같이 Frame Chart 폭이 엄청 줄어들었다.

😄 블로그 사이트 최적화 part2

추후 작성..

profile
끊임없이 발전해가는 개발자.

0개의 댓글