12장 모든 웹 개발자가 관심을 가져야 할 핵심 웹 지표
12.1 웹사이트와 성능
사용자가 웹사이트 방문 시 기대하는 사항
- 웹사이트를 방문한 목적을 쉽게 달성해야 함
- 위 목적을 달성하는 시간이 짧아야 함
- 개인정보 누출 등의 사고 X ,보안 철저
- 이러한 목적만 잘 달성된다면 웹사이트의 기술은 사용자에게 중요하지 않음.
- 최신 기술을 활용하더라도 결국엔 사용자가 느끼는 성능이 가장 중요한 것
웹사이트의 성능과 사용자 경험 사이의 상관관계
- 로딩 속도가 빠를수록 구매율 증가
- 로딩이 늦어질수록 전환률 감소
- 페이지 로드 시간 0 ~ 2초 사이가 가장 높은 전환율 달성
사용자가 민감한 성능
- 소비자 70%가 커머스 사이트 방문에 영향
- 빠르게 로딩할 수 있으면 애니메이션, 동영상 X
구글 웹 사이트 성능에 관한 통계
- 전체 웹페이지를 표시하는데 필요한 최적의 평균 리소스 요청 수 50회 미만
- 웹 페이지 전체 요청하는 데 평균 15.3 초
- 페이지 로드 시간 1초에서 10초로 늘어날수록 이탈 확률 123% 증가
- 웹사이트의 화려함이 사용자의 시간을 희생해야 한다면 무의미함
- 개발자들은 성능에 대해 관심을 크게 기울이지 않음
- 일반 사용자보다 개발자의 기기가 훨씬 더 성능이 좋아서 성능 문제를 경험하기 어려움
- 성능 개선하는 작업은 새로운 기능 개발보다 쉽지도 재밌지도 않아, 선뜻 내키지 않는 작업
- 웹 사이트의 성능 또한 개발자의 책임
12.2 핵심 웹 지표란 ?
핵심 웹 지표(Core Web Vital)
- 구글에서 만든 지표
- 웹사이트에서 뛰어난 사용자 경험을 제공하는 데 필수적인 지표
- 종류
- LCP(Largest Contentful Paint) : 최대 콘텐츠풀 페인트
- FID(First Input Delay) : 최초 입력 지연
- CLS(Cumulative Layout Shift) : 누적 레이아웃 이동
- 그 외 지표 (특정 문제 진단하는 데 사용)
- TTFB(Time To First Byte) : 최초 바이트까지의 시간
- FCP(First Contentful Paint) 최초 콘텐츠풀 시간
12.3 LCP
12.3.1 정의
- 페이지가 처음으로 로드를 시작한 시점부터 뷰포트 내부에서 가장 큰 이미지 또는 텍스트를 렌더링하는 데 걸리는 시간
- 뷰포트 : 사용자에게 현재 노출되는 화면
- 뷰포트 내부에서 큰 이미지와 텍스트 종류
- <img>
- svg 내부의 <image>
- poster 속성 사용하는 <video>
- url() 을 통해 불러온 배경 이미지가 있는 요소
- 텍스트와 같이 인라인 텍스트 요소를 포함하고 있는 블록 레벨 요소 p, div
- 사용자 시점에 노출되는 시점 : 각 엘리먼트가 등장한 시점부터 텍스트나 이미지가 완전히 로딩되는 시점
12.3.2 의미
- 웹페이지가 로딩이 완료되어 사용자에게 노출되기까지 걸리는 시간 ?
- DOMContentLoaded 이벤트가 호출되는 시간 ?
- HTML 문서를 완전히 불러오고 파싱헀을 때 발생하는 이벤트
- 페이지의 document를 대상으로 일어나며 단 한 번만 호출
- But, 스타일시트, 이미지, 하위 프레임의 로딩은 기다리지 않아서 적절하지 않음 !
- 뷰포트 영역이 대부분의 이미지로 이루어져 있고, 이미지 크기가 커서 로딩이 오래 걸리면 DOMContentLoaded 이벤트가 실행되도 사용자는 페이지 로딩이 끝났다고 여기지 않음
- 사용자에게 노출되는 부분만 로딩돼 있다면 사용자는 페이지 로딩이 완료됐다고 느낄 것
- 사용자 측면에서 로딩은 뷰포트 영역에 보이는 기준 !
- 즉, 안 보이는 페이지의 영역까지 완전히 로딩될 필요는 없는 것
- LCP는 사용자에게 페이지의 정보를 화면에 전달하는 속도를 객관적으로 판단하기 위한 지표로 만들어짐
12.3.3 예제
- LCP는 페이지 로딩에 따라 변화하는 지표
- 디바이스 크기에 따라 실제로 로딩에 필요한 시간에 따라 LCP 지표값이 달라짐
12.3.4 기준 점수
- 좋은 점수 기준 : 2.5 ~ 4초
12.3.5 개선 방안
- 점수를 높을 수 있는 방법
📍 텍스트는 언제나 옳다
- LCP 예상 영역에 이미지가 아닌 문자열을 넣는 것
- 이미지 최적화 < 텍스트
- 가능한 해당 영역은 테스트가 좋음
📍 이미지는 어떻게 불러올 것인가 ?
<!-- 1) img -->
<img src="lcp.jpg" ... />
<!-- 2) svg -->
<svg xmlns="http://www.w3.org/1000/svg">
<image href="lcp.jpg" />
</svg>
<!-- 3) (비디오의 경우) video.poster -->
<video poster="lcp.jpg"></video>
<!-- 4) background-image: url() -->
<div style="background-image: url(lcp.jpg)">...</div>
...
- img
- 브라우저의 프리로드 스캐너에 의해 먼저 발견되어 빠르게 요청됨
- 프리로드 스캐너 : HTML 파싱하는 단계를 차단하지 않고 빠르게 미리 로딩하면 좋은 리소스를 먼저 찾아 로딩하는 브라우저의 기능
- HTML 파싱이 완료되지 않더라도 프리로드 스캐너가 병렬적으로 리소스를 다운해서 LCP 요소를 불러오기 적절. <picture> 도 동일
- svg 내부의 <image>
- svg 내부의 <img> 는 프리로드 스캐너에 의해 발견되지 않아 병렬적으로 다운로드가 일어나지 않음
- video 의 poster
- poster : 사용자가 비디오 요소를 재생하거나 탐색하기 전까지 노출되는 요소
- 프리로드 스캐너에 의해 조기에 발견
- 향후 poster가 없는 video는 video를 실제로 로딩해 첫 번째 프레임을 해당 poster 리소스로 대체할 예정
- background-image
- url() :background-image 를 비롯해 CSS에 있는 리소스는 항상 느림
- 브라우저가 해당 리소스를 필요로 하는 DOM을 그릴 준비가 될 때까지 리소스 요청을 뒤로 미루기 때문
- LCP에 좋지 않음
📍 그 밖에 조심해야 할 사항
- 이미지 무손실 압축
- 웹으로 서비스할 이미지는 가능한 한 무손실 형식으로 압축해 최소한의 용량으로 서비스하는 것이 좋음
- loading=lazy 주의
- 리소스를 중요하지 않음으로 표시하고 필요할 때만 로드하는 전략
- LCP의 이미지를 중요하지 않은 리소스로 분류하면 안 됨
- LCP에서의 사용은 지양할 것
- fadein과 같은 각종 애니메이션
- 애니메이션만큼 LCP도 늦어짐
- 클라이언트에서 빌드하지 말 것
- 서버에서 빌드해온 HTML을 프리로드 스캐너가 바로 읽어서 LCP를 빠르게 가져가는 것이 베스트
- 최대 LCP는 직접 호스팅
- LCP는 가능한 같은 도메인에서 직접 호스팅하는 것이 좋음
- Coludinary 같은 이미지 최적화 서비스를 이용해 하나의 이미지 크기를 줄이고, 포맷 변환하고, 압축해서 이미지를 관리하게 되면 다른 출처에서 정제한 이미지를 가져오는 것은 최적화에 좋은 영향 X
- 이미 연결이 맺어진 현재 출처와는 달리, 완전히 새로운 출처의 경우에는 네트워크 커넥션부터 다시 수행해야 하기 때문
- 중요한 리소스는 직접 다루고, 덜 중요한 리소스에 대해서만 이미지 최적화 서비스를 사용하는 것이 좋음
12.4 최초 입력 지연(FID)
12.4.1 정의
- 웹사이트의 반응성을 측정하는 지표
- First Input Delay : 사용자가 페이지와 처음 상호 작용할 때(예: 링크를 클릭하거나 버튼을 탭하거나 사용자 지정 JavaScript 기반 컨트롤을 사용할 때)부터 해당 상호 작용에 대한 응답으로 브라우저가 실제로 이벤트 핸들러 처리를 시작하기까지의 시간
- 사용자가 얼마나 빠르게 웹페이지와 상호작용에 대한 응답을 받을 수 있는지 측정하는 지표
- 최초의 입력 하나에 대해서만 판단
12.4.2 의미
- 웹사이트 내부 이벤트 반응이 늦어지는 이유 ?
- 해당 입력을 처리하는 브라우저의 메인 스레드가 바쁨
- 대규모 JS 파일 분석 실행 등 리소스 할애
- JS 실행 환경은 싱글 스레드이기 때문에 다른 작업 수행할 수 없기 때문
- 사용자 입력
- 클릭,터치, 타이핑 등 사용자의 개별 입력 작업에 초점
- 스크롤,핀치 투 줌 등은 애니메이션으로 분류
- 구글의 사용자 경험 4가지 분류 RAIL
- Response : 사용자의 입력에 대한 반응 속도. 50ms 미만으로 이벤트를 처리할 것
- Animation : 애니메이션의 각 프레임을 10ms 이하로 생성할 것
- Idle : 유휴 시간을 극대화해 페이지가 50ms 이내에 사용자 입력에 응답하도록 할 것
- Load : 5초 이내에 콘텐츠를 전달하고 인터랙션을 준비할 것
- Response 에 초점
- 화면이 최초에 그려지고 난 뒤 사용자가 웹페이지에서 상호작용을 수행했을 떄 메인 스레드가 이 이벤트에 대한 반응을 할 수 있을 때까지 걸리는 시간 의미
- 메인 스레드가 처리해야 하는 다른 작업이 많을수록 느려짐
12.4.3 예제
- 이벤트가 처리되는 것이 얼마나 지연되는지만 판단
- 최초 이벤트 발생으로부터 해당 이벤트의 핸들러가 실행되는 순간까지 사이의 기간만 측정
- 이벤트가 완료되는 시간은 측정 안 함
12.4.4 기준 점수
- 100ms 이내 좋음
- 300ms 이내 보통
- 그 이상은 나쁨
12.4.5 개선 방안
- 메인 스레드에 이벤트를 실행할 여유를 주기
📍 실행에 오래 걸리는 긴 작업을 분리
- 긴 작업(long task) : 실행을 완료하는 데 오래 걸리는 작업
- long task가 있을 때 대안
- 꼭 웹페이지에서 해야 하는 작업인가
- 개발자의 기기에서도 오랜 시간이 소요되는 작업은 실제 사용자가 이용하는 경우엔 더 오래 걸릴 것
- 사용자 기기 환경과 비슷하게 메인 스레드 성능을 낮추려면 크롬의 개발자 도구 성능 탭에서 CPU 선택
- 꼭 웹페이지에서 해야 하는 작업이 아니면 서버에서 처리
- 긴 작업을 여러 개로 분리하기
- 꼭 웹페이지에서 처리해야 하는 작업이면 작업을 여러 개로 분리
- 단순 실행이 오래 걸리는 작업말고도 최초 로딩에 필요하지 않은 내용을 나중에 불러오는 것도 포함
- 꼭 웹페이지에서 해야 하는 작업인가
📍 자바스크립트 코드 최소화
- 번들링 도구들은 빌드 과정에서 사용되지 않는 코드로 간주되면 번들링에서 제거함
- 번들링 과정에서 제거된다고 하더라도 웹페이지를 불러오는 데 사용되지 않는 필요 없는 코드가 존재할 수 있음
- 크롬 개발자 도구의 커버리지로 확인 가능
- 모든 코드가 사용되지 않는 것은 아닐 수 있음
- 당장 급하지 않은 코드로 간주해 지연 로딩 기법, 사용자가 필요로 하는 순간에 불러오거나 우선순위를 낮춰서 불러오는 것이 좋음
- 폴리필(polyfill) : 브라우저에서 지원하지 않는 기능을 사용하기 위해 웹페이지에서 직접 구현하고 집어넣는 코드
- find처럼 IE 11이하 버전에서 지원하지 않는 메소드를 사용하기 위해서는 웹피이지에서 폴리필이 필요함
- 사용자에게 전달되는 코드가 과하게 커짐
- 폴리필을 집어넣기 전에 확인해봐야 하는 사항
- 폴리필 환경이 필요한가 ?
- 꼭 필요한 폴리필인가 ?
- 애플리케이션에서 자주 사용되는 코드인지
- 만약 많이 사용이 안 된다면 폴리필보다 직접 저수준 코드를 구현해서 코드 크기를 줄이는 것이 나음
📍 타사 자바스크립트 코드 실행의 지연
- GA, Firebase 등 타사 스크립트를 사용하는 경우
- 웹페이지 로드에 중요한 자원이 아니므로 <script>의 async나 defer를 이용해 지연 불러오기
- defer
- 해당 스크립트를 다른 리소스와 함께 병렬로 다운로드
- 다운로드하는 중에도 HTML 파싱 등 메인스레드 작업은 멈추지 않음
- 이 스크립트 실행은 페이지가 완전히 로딩된 이후 마지막에 실행됨
- async
- defer와 유사하게 병렬로 다운
- async 리소스의 다운로드가 끝나면 다른 리소스의 다운로드 작업을 기다리지 않고 바로 실행
- 즉 다운로드가 완료된 순서대로 실행됨
- 둘 다 없는 경우
- script를 만나는 순간 다운로드가 우선
- 다운로드가 끝나면 코드 실행이 우선됨
- 다른 작업은 다운로드와 실행이 끝날 때까지 미뤄짐
- defer
- 실제 사용자의 뷰포트 위치에 따라 불러와야 하는 컴포넌트는 Intersection Observer 이용하여 뷰포트에 들어오는 시점에 불러오는 것이 좋음
- 광고처럼 사용자가 기대하지 않은 추가적인 리소스는 실행을 조금 미뤄두고 실행시점을 최적화
12.5 누적 레이아웃 이동(CLS)
12.5.1 정의
- 페이지의 생명주기 동안 발생하는 모든 예기지 않은 이동에 대한 지표를 계산하는 것
12.5.2 의미
- useEffect 가 많을수록, 이 useEffect가 렌더링에 영향을 미칠수록 CLS에 좋지 않음
- 렌더링이 한 번 끝난 이후에 실행하기 때문
- 뷰포트 내부의 요소에 대해서만 측정
- 최조 렌더링이 시작된 위치에서 레이아웃의 이동이 발생하는 경우
- 단순 요소 추가가 CLS로 간주되지 않음. 추가가되어도 다른 요소의 시작 위치에 영향을 미치지 않았으면 CLS로 간주 X
- 사용자 액션으로 인해 발생한 CLS는 포함 X
- 사용자가 아무런 동작을 하지 않았을 때 생기는 레이아웃 이동만 점수에 포함
📍 CLS를 계산할 때 포함되는 내용 (두 점수 곱함)
- 영향분율
- 레이아웃 이동이 발생한 요소의 전체 높이와 뷰포트 높이의 비율
- 거리분율
- 레이아웃 이동이 발생한 요소가 뷰포트 대비 얼마나 이동했는지 의미
12.5.3 예제
- 로딩 상태임을 보여준느 스켈레톤 UI 추가하여 대략적인 페이지 레이아웃 고정
- 페이지 레이아웃 이동을 최소화
- 클라이언트에서 미리 노출이 예상되는 부분을 HTML로 미리 잡아두는 것이 CLS에 도움
- 콘텐츠가 어떤 위치에 렌더링될지 안정적으로 예측할 수 있고, 뷰포트 내부에서 큰 이동 없이 원하는 콘텐츠를 볼 수 있음
12.5.4 기준 점수
- 0.1 이하 좋음
- 0,25 이하 보통
- 그 이상 나쁨
12.5.5 개선 방안
📍 삽입이 예상되는 요소를 위한 추가적인 공간 확보
- 누적 레이아웃의 이동은 클라이언트에서 삽입되는 동적인 요소로 인해 발생
- 요소의 크기가 바뀌거나 광고 등이 로드되는 작업
- useEffect 내부에서 요소에 영향을 미치는 작업, 뷰포트 내부에서 노출될 확률이 높은 작업 최소화할 것
- useEffect 사용이 불가피하다면, useLayoutEffect 훅 사용
- 그러나 useLayoutEffect 는 동기적으로 발생해 브라우저의 페인팅 작업에 영향을 미치기 때문에 사용자에게 로딩이 오래 걸려보일 수 있음
- 스켈레톤 UI 활용해 레이아웃 이동을 막는 것도 좋은 방법
- best는 SSR. 동적 요소의 유무를 사전에 판단해 HTML 을 제공
- 뷰포트 영역은 사용자에게 첫 번째로 인상을 주는 가장 중요한 영역이기에 동적인 콘텐츠를 신중하게 사용
- 동적인 콘텐츠는 최대한 뷰포트에 영향을 미치지 않는 곳
📍 폰트 로딩 최적화
- 폰트도 레이아웃 이동을 일으키는 원인 중 하나
- FOUT(Flash Of Unstyled Text) : HTML 문서에서 지정한 폰트가 보이지 않고 대체 기본 폰트로 보이고 있다가 뒤늦게 폰트가 적용되는 현상
- FOIT(Flash Of Invisible Text) : HTML 문서에서 지정한 폰트가 보이지 않고 기본 폰트도 없어서 텍스트가 없는 채로 있다가 뒤늦게 폰트가 로딩되면서 페이지에 렌더링되는 현상
- 폰트는 각각 고유의 높이와 너비 가짐, 높이와 너비가 다른 텍스트가 노출되거나 텍스트가 노출이 안 돼서 레이아웃의 이동이 발생할 수 있음
사용자 기기의 기본 폰트 외 다른 폰트를 사용하는 경우 주의해야 하는 점
- <link>의 preload 사용
- rel=preload 페이지에서 즉시 필요로 하는 리소스를 명시하는 기능
- 웹페이지 생명주기에서 초기에 불러와야 하는 중요한 리소스로 간주되어 더 빠르게 사용할 수 있도록 준비
- font-family: optional
- 폰트를 불러올 수 있는 방법 5가지
- auto : 기본값, 브라우저가 폰트를 불러오는 방법 결정
- block : 폰트가 로딩되기 전까지 렌더링 중단
- swap : FOUT 방식
- fallback : 100ms간 텍스트가 보이지 않고, 그 이후에 폴백 폰트로 렌더링. 3초 안으로 폰트 로딩되면 웹 폰트로 전환하고 그렇지 않으면 폴백 폰트 사용
- optional : 0.1초 이내로 폰트가 다운로드돼 있거나 캐시돼 있지 않으면 폴백 폰트 사용
📍 적절한 이미지 크기 설정
img {
width: 100%;
height: auto;
}
<img
width="1000"
height="1000"
src="image-1000.jpg"
srcset="image-1000.jpg 1000w, image-2000.jpg 2000w, image-3000.jpg 3000w"
alt="이미지"
/>
- 이미지의 높이를 명확하게 알지 못하기 때문에 레이아웃 이동 발생
- 해결 방안
- width, height 지정 : auto, 100 % 와 함꼐 사용하면 브라우저가 이미지 로딩 전에 적절한 가로세로 비율을 계산함
- srcset 속성 사용 : 뷰포트 너비에 맞춰 다른 이미지 제공하는 경우
12.5.6 핵심 웹 지표는 아니지만 성능 확인에 중요한 지표들
📍 최초 바이트까지의 시간 (TTFB)
- 브라우저가 웹페이지의 첫 번째 바이트를 수신하는 데 걸리는 시간
- 최초의 응답이 오는 바이트까지가 얼마나 걸리는지 측정하는 지표
- 600ms 이상은 개선 필요
- 서버에서 첫 HTML 만들 떄 하는 작업이 많거나 느릴수록 TTFB 길어짐
- 사용자가 페이지 요청할 때 빈 화면이 뜨는 것 의미
TTFB 개선 시 고려사항
- SSR 경우
- 로직을 최적화해 페이지를 최대한 빨리 준비
- API 호출 횟수와 가져오는 정보의 크기 최소화하여 API 응답 속도 개선
- 방문객의 국적 파악하여 최대한 해당 국적과 가깝게 서버 위치시키기
- 응답해야 할 서버가 사용자와 가까울 수록 응답 속도 빠르기 떄문
- 리액트 SSR 경우
- 스트리밍 API 활용
- 완성된 영역부터 조각조각 받음
📍 최초 콘텐츠풀 페인트(FCP)
- 페이지가 로드되기 시작한 시점부터 페이지 콘텐츠의 일부가 화면에 렌더링될 때까지의 시간
- 웹사이트에 접속한 순간부터 페이지에 뭐라도 뜨기 시작한 시점까지의 시간
- 1.8초 좋음, 3.0 이내 보통, 그 이후는 개선 필요
개선 시 고려 사항
- TTFB 개선
- 렌더링 가로막는 리소스 최소화
- 일단 뭐라도 다운로드가 시작돼야 렌더링 가능
- 렌더링을 최대한 빠르게
- Above the Fold에 대한 최적화
- 스크롤을 굳이 하지 않아도 보이는 영역
- 게으른 로딩, 스크립트에 의존 X
- 페이지 리다이렉트 최소화 : 그만큼 사용자에게 무언가를 보여주는 시간 지연되기 때문
- DOM 크기 최소화
- OM이 복잡하고 크면 그만큼 렌더링되는 데 시간이 오래 걸림
13장 웹페이지의 성능을 측정하는 다양한 방법
13.1 애플리케이션에서 확인하기
13.1.1 create-react-app
- web-vitals 라이브러리
- PerformanceObserver API 사용
- 웹페이지에서 다양한 성능 측정할 수 있는 API
13.1.2 create-next-app
- 성능 측정 메서드 NextWebVItalsMetric
- Next.js에 특화된 사용자 지표
- Next.js-hydration : 페이지가 서버 사이드에서 렌더링되어 하이드레이션하는 데 걸린 시간
- Next.js-route-change-to-render : 페이지가 경로를 변경한 후 페이지를 렌더링을 시작하는 데 걸리는 시간
- Next.js-render : 경로 변경이 완료된 후 페이지를 렌더링하는 데 걸린 시간
13.2 구글 라이트하우스
- 구글에서 제공하는 웹 페이지 성능 측정 도구
- 접근성 PWA, SEO 등도 측정 및 점검
- 실행 방법
- 사이트 방문 후 크롬 개발자 도구에서 Lighthouse 탭 선택
13.2.1 구글 라이트하우스 - 탐색 모드
- 페이지에 접속했을 때부터 페이지 로딩이 완료될 때까지의 성능을 측정하는 모드
📍 성능
- 웹페이지 성능과 관련된 지표
- FCP, LCP, CLS 외 추가적인 지표
- Time to Interactive TTI
- 페이지에서 사용자가 완전히 상호작용할 수 있을 때까지 걸리는 시간
- FCP로 측정되는 페이지 내 콘텐츠가 표시되는 시점
- 보여지는 페이지 요소의 대부분에 이벤트 핸들러가 부착되는 시점
- 페이지가 유저의 상호작용에 50ms 내로 응답하는 시점
- 3.8초 이내 좋음 , 7.3초 이내 보통, 그 이후 개선 필요
- Speed Index
- 페이지가 로드되는 동안 콘텐츠가 얼마나 빨리 시각적으로 표시되는지 계산
- 로드되는 페이지를 실시간으로 캡쳐하고 이를 분석하여 계산함
- 3.4초 이내 좋음, 5.8초 이내 좋음, 그 이후 느림
- Total Blocking Time
- 메인 스레드에서 특정 시간 이상 실행되는 작업, 즉 긴 작업이 수행될 때마다 메인 스렌드가 차단됐다고 간주
- 그동안 다른 작업 실행할 수 없기 때문
- FCP부터 TTI 사이의 긴 작업들의 시간에서 50ms 빼고 이를 모두 합해 계산
- 사용자가 무언가 작업이 진행되고 있지 않다는 걸 눈치 챌 수 있는 시간을 대상
📍 접근성
- 장애인 및 고령자 등 신체적으로 불편한 사람들이 일반적인 사용자와 동등하게 웹페이지를 이용할 수 있도록 보장하는 것
📍 권장사항
- 웹사이트를 개발할 때 고려해야 할 요소들을 얼마나 지키고 있는지
- CSP가 XSS 공격에 효과적인지 확인
- XXS (Cross Site Scripting)
- 개발자가 아닌 제3자가 삽입합 스크립트를 통해 공격하는 기법
- CSP (Content Security Policy)
- 웹사이트에서 호출할 수 있는 컨텐츠를 제한하는 정책
- 감지된 JS 라이브러리
- HTTPS 사용
- 페이지 로드 시 위치정보/알림 권한 요청 방지하
- 사용자 동의 없이 실행되는지 확인
- 알려진 보안 취약점이 있는 FE JS 라이브러리 사용하지 않음
- 비밀번호 입력란 붙여넣기 허용
- 붙여넣기 가능해야 함
- 이미지 - 가로세로 비율, 적절한 해상도
- HTML Docutype
- 없으면 표준을 준수하지 않은 것으로 간주하여 호환 모드로 렌더링되기 때문
- 적절한 charset 정의
- 지원 중단 API 사용하지 않긱
- 콘솔에 로그된 브라우저 오류 없음
📍 검색 엔진 최적화
- 검색엔진이 쉽게 웹페이지 정보를 가져가서 공개할 수 있도록 최적화돼 있는지 확인
13.2.2 구글 라이트하우스 - 기간 모드
- 실제 웹페이지를 탐색하는 동안 지표 측정
- 사용자가 빈번하게 수행할 작업들을 측정하면 성능 최적화에 도움
📍 흔적 (View Trace)
- 시간의 흐름에 따라 어떻게 웹페이지가 로딩됐는지
📍 트리맵
- 페이지를 불러올 때 함께 로딩한 모든 리소스
- 실제 불러온 데이터의 크기 확인
- 실제 불러왔지만 사용되지 않은 리소스 확인
13.2.3 구글 라이트하우스 - 스냅샷
- 탐색 모드와 유사, 현재 페이지 상태를 기준으로 분석
13.3 WebPageTest
- 웹사이트 성능 분석
- 글로벌 웹사이트 분석에 적합
- Site Performence : 웹사이트 성능 분석
- Core Web Vitals : 핵심 웹 지표 확인
- Lighthouse
- Visual Comparison : 2개 이상 사이트를 동시에 실행에 시간의 흐름에 따른 로딩 과정 분석
- Traceroute : 네트워크 경로 확인
13.3.1 Performance Summary
- Opportunities & Experiments
- Is it Quick : 웹사이트 빠른지 평가 ,TTFB, LCP 등 판단
- Is it Usable : 사용성과 시각적인 요소 확인, CLS, 접근성 이슈 등
- Is it Resilent : 보약 취약성 점검
13.3.2 Opportunities & Experiments
- TTFB 점검
- 렌더링을 막는 JS 가 있는지(적을 수록 렌더링 수월)
- 렌더링 막는 CSS 확인
- 주요 영역 내 게으른 로딩 이미지가 적을 수록, 주요 영역 외에는 게으른 로딩 이미지 적용이 좋음
- 최초 다운 받은 HTML과 최종 결과물 HTML 사이에 크기 차이가 작아야 함
- 차이가 크다 : 최종 결과물을 그리기 위해 JS가 많이 사용되었다를 의미
1.3.3 Filmstrip
- 시간의 흐름에 따라 어떻게 웹사이트가 그려졌으며 어떤 리소스가 불러와졌는지 확인
- 렌더링을 가로막는 리소스와 예상보다 일찍 실행되는 스크립트 확인 가능
1.3.6 Optimizations
- 리소스들이 얼마나 최적화돼 있는지 나타냄
- Keep-Alive 설정으로 서버와의 연결 계속 유지하는지
- 이미지를 적절하게 압축했는지
- 리소스가 CDN을 거치는지
13.3.8 Domains
- 중요 리소스는 웹사이트와 같은 곳에서 요청할 수록 도메인 연결에 소요되는 비용을 줄일 수 있음
13.3.9 Console Log
- 사용자가 접속했을 때 console.log가 무엇이 기록됐는지 확인
- console.log 자체도 부하가 발생하는 작업이기에 사용 지양
13.4 크롬 개발자 도구
13.4.1 성능 통계
📍Insights
- 성능 측정 중 살펴봐야 할 이벤트 보여줌
- Performance Measure
- Long Task : 메인 스레드에서 오랜 시간동안 실행된 긴 작업
- Forced Style recalculation
- 스타일이 한 번 계산된 이후 스타일이 다시 강제로 계산되는 작업 실행
- 이는 리소스가 많이 소요되는 일이기에 최초 로딩 시에는 일어나지 않는 것이 좋음
13.4.2 성능
📍 요약
- 측정 기간의 CPU, 네트워크 요청, 스크린숏, 메모리 점유율 확인
📍 네트워크
- 모든 네트워크 요청 확인
- 그래프 분석
- 연한 왼쪽 : 요청 보내고 최초 바이트가 오기까지의 대기 시간
- 진한 오른쪽 : 콘텐츠 다운로드하는 데 걸리는 시간
📍 소요 시간과 기본
- 시간의 흐름에 따라 메인스레드 작업과 JS의 힙 영역 변화
13.5 정리
- 성능을 0.1초 개선하는 것만으로도 사용자 경험 개션
- 웹사이트 성능 개선에 대한 관심, 책임감을 키우자
'React > 모던 리액트 Deep Dive' 카테고리의 다른 글
[14, 15장] 모던 리액트 Deep Dive 스터디 17회차 (0) | 2024.09.05 |
---|---|
[10,11장] 모던 리액트 Deep Dive 스터디 15회차 (0) | 2024.09.05 |
[9장] 모던 리액트 Deep Dive 스터디 14회차 (0) | 2024.09.05 |
[8장] 모던 리액트 Deep Dive 스터디 13회차 (0) | 2024.07.12 |
[7장] 모던 리액트 Deep Dive 스터디 12회차 (0) | 2024.07.12 |