티스토리 뷰
LightHouse
과제를 수행하며 해결해나간 항목들을 정리해둔 것
웹 페이지 품질 개선할 수 있는 자동화도구
Chrome의 개발자도구 탭에서 사용가능
npm으로 설치해서 사용가능
Lighthouse에서 측정하는 지표는 실제 사용자의 사이트 경험을 이해하고 개선하는데에 중요하다.
- Lighthouse으로 미리 측정하여 확인하면 이런 해프닝을 방지할 수 있다.
다음은 Lighthouse에서 측정해주는 UX를 높이는데에 필요한 지표들을 알아보자.
성능측정 지표
Lighthouse는 Mertics(척도)로 다음 6가지를 측정한다.
이 성능값들은 절대적인 수치가 아니다. 컴퓨터의 퍼포먼스나 익스텐션들로 인한 네트워크 요청들, 바이러스 소프트웨어 등등에 의해 영향을 미칠 수 있다.
각 지표는 가중치를 매겨 전체 점수를 계산하게 된다.
이름(-)가중치
- First Contentful Paint (FCP) 10%
- Largest Contentful Paint (LCP) 10%
- First Input Delay (FID) 25%
- Time to Interactive (TTI) 10%
- Total Blocking Time (TBT) 30%
- Cumulative Layout Shift (CLS) 15%
1. First Contentful Paint
페이지가 로드되기 시작한 시점부터 컨텐츠 일부가 화면에 렌더링 될 때까지의 시간
1.8초 이하여야 좋은 UX를 제공할 수 있다.
- FCP는 전체 콘텐츠가 아닌 일부의 콘텐츠만 랜더링되는 프레임인, 오른쪽에서 두번째 프레임에서 발생하는 것
1. FCP 개선방법
lighthouse를 측정해보면 제안을 해주므로 해당하는 항목을 개선시키면된다.
- 렌더링 차단 리소스 제거
- CSS 축소
- 사용하지 않는 CSS 제거
- 필요한 원본에 사전 연결
- 서버 응답 시간 단축(TTFB)
- 여러 페이지 리디렉션 방지
- 핵심 요청 사전 로드
- 막대한 네트워크 페이로드 방지
- 효율적인 캐시 정책으로 정적 자산 제공
- 과도한 DOM 크기 방지
- 크리티컬 요청 깊이 최소화
- 웹폰트 로드 중에 텍스트가 계속 표시되는지 확인
- 요청 수를 낮게 유지하고 전송 크기를 작게 유지
프로젝트에서 해당하는 문제점은 다음과 같았다.
웹 폰트를 적용시키고 있었는데 웹폰트가 가지는 문제점이 있었다.
바로 브라우저가 렌더링하는 과정에서 웹 폰트가 다운로드되지 않았다면 해당 텍스트 랜더링을 차단한다는 것이었다.참고
이런 이슈때문에 초기 컨텐츠 로딩속도가 웹폰트 다운까지 늦춰지게 되었다.
font-display
속성을 추가하여 웹폰트 다운로드 전 텍스트를 출력해 이를 해결할 수 있었다.
- 통과한 사항들
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파일은 다음과 같았다.
코드 스플리팅이 적용되지 않아 화면에 불필요한 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 개선 방법
4. Time to Interactive
상호작용하기까지의 시간
사용자 입력에 대해 응답할 수 있는 시점까지의 시간
FID는 입력에 대한 처리 준비시간이고 TTI는 응답을 할 수 있는 시점까지임
4. TTI 개선방법
- JavaScript 축소
- 필요한 원본에 사전 연결
- 핵심 요청 사전 로드
- 타사 코드의 영향 줄이기
- 크리티컬 요청 깊이 최소화
- JavaScript 실행 시간 단축
- 메인 스레드 작업 최소화
- 요청 수를 낮게 유지하고 전송 크기를 작게 유지
5. Total Blocking Time
50ms이상 실행되는 작업이 있을 때마다 메인쓰레드는 차단된 것으로 간주되는데 작업단위당 50ms이상인 것이 있으면 유저는 페이지가 버벅이는 것으로 인지하게 됨
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