티스토리 뷰

WEB

LightHouse

수박수박좋다 2021. 10. 4. 18:55
반응형

LightHouse


과제를 수행하며 해결해나간 항목들을 정리해둔 것

웹 페이지 품질 개선할 수 있는 자동화도구

Chrome의 개발자도구 탭에서 사용가능

npm으로 설치해서 사용가능

Lighthouse에서 측정하는 지표는 실제 사용자의 사이트 경험을 이해하고 개선하는데에 중요하다.

스크린샷 2021-10-04 오후 2 51 07

  • Lighthouse으로 미리 측정하여 확인하면 이런 해프닝을 방지할 수 있다.

다음은 Lighthouse에서 측정해주는 UX를 높이는데에 필요한 지표들을 알아보자.

성능측정 지표

Lighthouse는 Mertics(척도)로 다음 6가지를 측정한다.

이 성능값들은 절대적인 수치가 아니다. 컴퓨터의 퍼포먼스나 익스텐션들로 인한 네트워크 요청들, 바이러스 소프트웨어 등등에 의해 영향을 미칠 수 있다.

각 지표는 가중치를 매겨 전체 점수를 계산하게 된다.

이름(-)가중치

1. First Contentful Paint

페이지가 로드되기 시작한 시점부터 컨텐츠 일부가 화면에 렌더링 될 때까지의 시간

1.8초 이하여야 좋은 UX를 제공할 수 있다.

스크린샷 2021-10-04 오후 3 08 17

  • FCP는 전체 콘텐츠가 아닌 일부의 콘텐츠만 랜더링되는 프레임인, 오른쪽에서 두번째 프레임에서 발생하는 것

1. FCP 개선방법

FCP 시간을 줄이기 위한 방법들이다.

lighthouse를 측정해보면 제안을 해주므로 해당하는 항목을 개선시키면된다.

프로젝트에서 해당하는 문제점은 다음과 같았다.

스크린샷 2021-10-04 오후 3 15 00

웹 폰트를 적용시키고 있었는데 웹폰트가 가지는 문제점이 있었다.

바로 브라우저가 렌더링하는 과정에서 웹 폰트가 다운로드되지 않았다면 해당 텍스트 랜더링을 차단한다는 것이었다.참고

이런 이슈때문에 초기 컨텐츠 로딩속도가 웹폰트 다운까지 늦춰지게 되었다.

font-display 속성을 추가하여 웹폰트 다운로드 전 텍스트를 출력해 이를 해결할 수 있었다.

스크린샷 2021-10-04 오후 3 20 41

  • 통과한 사항들

2. Largest Contentful Paint

FCP는 최초 컨텐츠가 보여질 때까지의 시간이었다.

LCP는 viewPort내의 가장 큰 이미지 또는 텍스트의 렌더링시간을 뜻한다.

2.5초 이하여야 좋은 UX를 가진 사이트

  • img, video, 블록레벨요소(display: block)들이 LCP에 대해 고려되는 대상이다.

LCP는 다음 4가지 요인에 의해 영향을 받게 된다.

  • 느린 서버 응답 시간
  • 렌더링 차단 JavaScript 및 CSS
  • 리소스 로드 시간
  • 클라이언트 측 렌더링

LCP개선 을 참고해 각 요인에 대해 대응해볼 수 있다.

프로젝트에선 사용하지 않은 JS를 로드하는데에 드는 시간때문에 LCP가 지연되었다고 한다.

CSR을 수행하고 있으므로 화면구성에 필요한 모든 JS를 로드할 때까지 렌더링이 블락되기에 발생하는 문제라고 인식했다.

사용하지 않는 JS, CSS파일를 찾는 방법 은 개발자도구를 활용하는 것이었다.

프로젝트에서 사용되지 않는 JS파일은 다음과 같았다.

스크린샷 2021-10-04 오후 3 37 34

코드 스플리팅이 적용되지 않아 화면에 불필요한 JS(한번에 번들링된 파일)을 로드하는 것이 문제였다.

현재 CRA로 프로젝트를 구성했으므로 웹팩설정은 따로 건들지 않는 것이 좋다고 생각했다.참고사이트

  • CRA의 webpack설정을 변경하기 위해 eject라는 키워드로 webpack설정파일을 수정할 수 있도록 변경되는데 모든 설정파일을 직접 유지보수해야한다는 것과 다른 패키지들과의 의존성을 항상 체크해주어야하는 단점이 존재한다.

웹팩을 건들지 않고 코드스플리팅을 할 수 있는데 React.lazy, Suspend을 사용하는 방법이다.

2. LCP 개선 - 코드스플리팅

bundle analyzer 로 번들된 파일들을 볼 수 있다.

웹팩 설정없이 필요할 때 js를 로드하는 방식인 lazy를 사용했다.

lazy는 컴포넌트 렌더링시점에 비동기적으로 로딩해주는 함수다.

const Home = lazy(() => import("Pages/Home"));
  • Home 컴포넌트가 렌더링될 때 import해올 수 있다.

suspense는 로딩이 될 때 까지 보여줄 UI를 설정해줄 수 있다.

  • 원래라면 초기에 앱에 필요한 모든 JS를 다운로드받아야 랜더링되어야하는데 이를 사용하면 필요한 컴포넌트들의 JS만 받기 때문에 load되기전에 보여줄 UI를 suspense로 지정해주어야한다.(안하면 에러발생)

적용 코드는 다음과 같다.

const Home = lazy(() => import("Pages/Home"));
const BeerList = lazy(() => import("Pages/BeerList"));
const CartView = lazy(() => import("Pages/CartView"));
const Page404 = lazy(() => import("Pages/Page404"));

const Routes = () => {
  return (
    <Router>
      <Header />
      <Suspense
        fallback={
          <Portal>
            <Spinner />
          </Portal>
        }
      >
        <Switch>
          <Route exact path="/">
            <Redirect to="/home" />
          </Route>
          <Route exact path="/home" component={Home} />
          <Route exact path="/beerlist" component={BeerList} />
          <Route exact path="/cartview" component={CartView} />
          <Route component={Page404} />
        </Switch>
      </Suspense>
    </Router>
  • 원래는 import문을 줄이기 위해서 하나의 index파일을 두고 비구조화 할당을 하여 받아왔는데 작성된 lazy함수의 코드는 비구조화할당으로 작동하지 않는다. (다른 방법을 사용하면 가능하긴 함)관련 이슈
  • 하나의 index파일에서 관련 컴포넌트들을 관리하는 것 보다 코드스플리팅을 고려하여 사이즈가 큰 컴포넌트(페이지 단위)는 하나의 import문으로 받아올 수 있도록 생각하고 작성하자.

코드스플리팅 결과

전

  • 적용 전
  • 페이지 전환이 이루어져도 JS를 Load하지 않는다.

후

  • 적용 후
  • 페이지 전환시마다 JS를 요청하는 것을 확인할 수 있다.

3. First Input Delay

인터렉션을 할 수 있기 까지의 시간 - 링크, 버튼클릭 등을 할 때 브라우저가 이를 처리를 시작하기까지의 시간

FID가 낮아야 페이지를 사용할 수 있는 것을 의미함

Lighthouse에선 해당 메트릭측정을지원하지 않음 - TBT를 대체제로 사용

100ms이하여야 좋음

3. FID 개선 방법

FID 최적화

4. Time to Interactive

상호작용하기까지의 시간

사용자 입력에 대해 응답할 수 있는 시점까지의 시간

FID는 입력에 대한 처리 준비시간이고 TTI는 응답을 할 수 있는 시점까지임

4. TTI 개선방법

5. Total Blocking Time

50ms이상 실행되는 작업이 있을 때마다 메인쓰레드는 차단된 것으로 간주되는데 작업단위당 50ms이상인 것이 있으면 유저는 페이지가 버벅이는 것으로 인지하게 됨

TBT 계산- 참고그림

300ms미만인 것이 좋음

5. TBT 개선방법

6. Cumulative Layout Shift

누적레이아웃 이동

유저가 예상치못한 레이아웃 이동을 경험하는 빈도를 수치화

낮을수록 좋음

예상치못한 레이아웃 이동으로 인한 영향

6. CLS 개선방법

  • image나 video의 크기 속성을 지정해준다
    • 프로젝트에서 이미지태그에 크기를 지정해주지 않아서 해당 스코어가 낮았었다.
  • 레이아웃 변경을 트리거하는 속성의 애니메이션 (flow를 유발하는 속성)보다 transform 애니메이션을 사용
    • 프로젝트에서 text를 이동하는 애니메이션을 작성했는데 transform으로 변경했다.

결론

상기 내용을 모두 정리하는 것은 코스트가 상당히 크고 내용도 많아 다 기억할 수 없을 것이라고 생각하여 프로젝트(과제)를 진행하면서 마주쳤던 문제들을 예시를 들며 정리했다.

본인이 느끼기엔 Lighthouse에서 중요한 것은 초기렌더링속도와 UX다.

FCP나 LCP가 초기렌더링속도에 가장 큰 영향을 받고 나머지 속성들은 UX적인 측면의 지표를 뜻한다고 이해했다.

반응형

'WEB' 카테고리의 다른 글

MSW로 API 모킹 빠르고 쉽게 하기  (0) 2022.09.24
husky로 git hooks 빠르게 작성하기  (0) 2022.09.16
JWT (Json Web Token)  (0) 2021.07.28
함수형 프로그래밍이라고 불리는 것이 뭘까  (0) 2021.07.28
OAuth ?  (0) 2021.04.27
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
농담곰의 고군분투 개발기