너굴 개발 일지

[Browser] 웹성능 최적화 본문

Web

[Browser] 웹성능 최적화

너굴냥 2023. 6. 30. 20:56

웹 성능 지표를 개선하는 방법에 대해 공부하며 정리한 글입니다.

웹 성능 최적화를 위해서 다양한 방법들을 사용합니다. 이때 웹 성능은 어떻게 측정될까요? 

웹페이지의 퍼포먼스를 지속적으로 개선하기 위해선 측정할 수 있는, 수치화된 지표가 필요합니다.

Web Vitals이라는 지표는 구글에서 제안하는, 더 나은 웹페이지 개발을 위한 가이드라인으로 아래 3가지 핵심 지표들을 포함하고 있습니다.

  • LCP (Largest Contentful Paint)
  • FID (Firsr Input Delay), TBT (Total Blocking Time)
  • CLS (Cumulative Layout Shift)

 

LCP (Largest Contentful Paint)

LCP는 페이지 내용이 화면에 얼마나 빨리 나오는지를 측정하기 위한 지표입니다.

LCP란, 뷰포트 내에서 이미지/비디오/텍스트 블록 중 시각적으로 가장 큰 사이즈를 차지하는 블록이 처음으로 브라우저에 paint 되기까지의 시간을 의미합니다.

 

LCP 영향 요소

LCP에 영향을 주는 요소들과 이 요소들을 해결할 수 있는 방법은 다음과 같습니다.

  • 느린 서버 응답 시간
  • JS 및 CSS의 렌더 블로킹
  • 느린 리소스 로딩 시간
  • 클라이언트측 렌더링

 

느린 서버 응답 시간

브라우저가 서버에서 컨텐츠를 받는데 걸리는 시간이 오래걸릴수록 화면에 렌더링하는 시간도 당연히 길어지게 됩니다.

따라서 다음과 같은 방법으로 개선할 수 있습니다.

  • 서버 최적화
  • 사용자와 가까운 CDN 사용
  • 자원 캐시
  • 서드파티 자원의 연결을 일찍한다

 

(1) 서버 최적화

브라우저 요청에 서버는 단순히 정적 페이지를 제공하는 대신, 서버측 프레임워크가 웹페이지를 동적으로 생성해야 합니다.

즉, 브라우저 요청시 이미 완성된 HTML 파일보다는, 프레임워크가 페이지를 생성하는 로직을 실행해야 합니다.

왜냐하면 DB 쿼리 결과 지연, React 같은 컴포넌트 UI 프레임워크에 의해 마크업으로 생성되어야 하기 때문일 수도 있습니다.

서버에서 동작하는 많은 웹 프레임워크는 이 과정을 빠르게 할 수 있는 성능 가이드를 제공합니다.

(2) 사용자와 가까운 CDN 사용

서버 1대에서 웹페이지 컨텐츠를 제공하면, 물리적으로 멀리 있는 사용자에게는 느리게 로딩됩니다. 따라서 CDN 사용으로 사용자가 먼곳에 있는 서버에 대한 네트워크 요청을 빠르게 처리할 수 있습니다.

CDN
Content Delivery Network의 약자로 콘텐츠 전송 네트워크로 데이터 사용량이 많은 애플리케이션의 웹 페이지 로드 속도를 높이는 상호 연결된 서버 네트워크를 의미합니다.

(3) 자원 캐시

HTML이 정적이고 요청마다 달라질 필요가 없다면, 캐시 처리로 리소스 사용량을 최소화하며 불필요한 네트워크 발생도 방지합니다.

(4) 서드파티 자원의 연결을 일찍 한다

서드파티 오리진에 대한 서버 요청이 특히 페이지에 중요한 콘텐츠를 표시하는데 사용되는 경우, LCP에 영향을 줄 수 있습니다.

따라서 preconnect, dns-prefetch를 사용해 TCP 연결, DNS 조회 최적화를 진행할 수 있습니다.

<link rel="preconnect" href="https://example.com" />
<link rel="dns-prefetch" href="https://example.com" />

 

preconnect

browser가 서버로부터 리소스를 요청하기 전에는 connection이 필요합니다. connection은 3가지 과정으로 진행됩니다.

  1. 브라우저가 DNS 이름 확인 (dns-lookup)
  2. TCP Hand Shake 수행 (신뢰성 확보) (Initial connection)
  3. TLS 터널 협상 (SSL) - 전송계층 상 클라이언트, 서버에 대한 인증 및 데이터 암호화 수행

각 step에서 브라우저는 데이터 조각을 서버로 보내고 응답을 받습니다. 이러한 origin으로부터 서버로 갔다가 되돌아 오는 것을 round-trip이라고 부릅니다.

네트워크 상황에 따라 한번의 round-trip이 상당한 시간이 소요될 수 있고, 세번의 round-trip을 포함한 connection setup 과정이 네트워크 환경이 최적화 되지 않은 경우엔 세번 이상이 될 수 있습니다. 이런 과정을 리소스가 필요한 시점에 하는 것이 아니라 미리 한다면, 리소스가 필요한 시점에 더 빨리 로드할 수 있습니다. 이때 <link rel="preconnect"><link rel="dns-prefetch">를 통해서 할 수 있습니다.

preconnect란 현재 페이지에서 외부 도메인의 리소스 참고를 브라우저에게 알려 외부 도메인과의 연결을 미리 설정하며 병렬적으로 실행될 수 있습니다.

preconnect 사용시 브라우저가 사이트에 필요한 연결을 미리 예상할 수 있으며, 브라우저는 필요한 소켓을 미리 설정할 수 있기에 DNS, TCP, TLS 왕복에 필요한 시간을 절약할 수 있습니다.

preconnect를 이용하면 round trip을 제거할 수 있고 이 결과로, 소요 시간을 줄일 수 있습니다.

 

같은 도메인의 CSS, font 초기 연결을 병렬로 설정하고, css 파일 다운로드가 완료되면 font 파일의 초기 연결이 설정될때까지 기다릴 필요 없이 다운로드를 시작할 수 있으므로 0.6초의 시간이 절약되고 결과적으로 3개의 round trip을 제거할 수 있습니다.

preconnect 주의사항

외부 도메인과의 연결을 구축하기에 많은 CPU 시간을 차지할 수 있습니다. 따라서 10초 이내로 브라우저가 닫힌다면, 이전의 사전 연결 작업은 낭비되기에 빨리 닫힐 수 있는 페이지에서는 사용하지 않는 것이 좋습니다.

 

dns-prefetch

사이트는 서버위 위치를 이름(URL)로 기억하지만 실제로는 IP 주소를 통해 서버로 요청을 전송합니다. 따라서 브라우저는 DNS server에게 요청을 보내 서버의 IP 주소를 획득하게 됩니다.

connection의 첫번째 단계인 위 과정을 미리 수행해 20~120ms 정도의 시간을 줄일 수 있습니다.

또한 preconnect를 지원하지 않는 일부 브라우저도 존재해 이에 대한 fallback으로 dns-prefetch를 사용할 수 있습니다.

 

preconnect & dns-prefetch 요약

preconnectdns-prefetch는 다른 도메인에서 리소스를 다운로드 할 예정이지만 리소스의 정확한 URL을 모르는 경우 속도를 개선하는데 유용합니다. 예로 JavaScript 라이브러리, 이미지 또는 글꼴을 포함하는 CDN이 있습니다. 

그리고 중요한 리소스에 대해서만 preconnect를 이용하고 나머지는 dns-prefetch를 사용하는 것이 좋습니다.

 

느린 리소스 로딩 시간

많은 타입의 리소스를 로드하는데 걸리는 시간도 렌더링 시간에 영향을 미칩니다. LCP에 영향을 주는 엘리먼트 타입은 다음과 같습니다.

  • img 엘리먼트
  • svg 엘리먼트 내부의 image 엘리먼트
  • video 엘리먼트
  • url() 함수를 통해 로드된 배경 이미지가 있는 엘리먼트

위와 같은 엘리먼트를 로드하는데 걸리는 시간은 LCP에 직접적인 영향을 미치며, 이런 파일을 빠르게 로드하는 방법은 다음과 같습니다.

 

중요한 리소스 미리 로드하기

우선 순위를 높여야 하는 특정 리소스가 있다면 빨리 로드하기 위해 <link rel="preload">를 사용할 수 있습니다.

다양한 종류의 리소스가 미리 로드될 수 있지만, 폰트, 상단부의 이미지나 비디오, 핵심적인 CSS, JS를 로드할 수 있습니다.

<link rel="preload" as="script" href="super-important.js">
<link rel="preload" as="style" href="critical.css">

 

preload 주의 사항

위처럼 as 속성을 사용해 리소스의 유형을 알려줘야 합니다. 브라우저는 올바른 유형이 설정되어 있지 않으면 미리 가져온 리소스를 사용하지 않습니다.

또한 preload는 브라우저가 반드시 리소스를 가져오게 만듭니다. 리소스를 중복 참조하면 중복된 개수만큼 리소스를 가져오기 때문에 리소스를 중복해서 참조하지 않도록 하며 반드시 사용되는 리소스에만 사용합니다.

preload를 이용해 리소스를 가져왔지만 현재 페이지의 3초 내로 사용되지 않는 리소스는 위그림 같은 경고 문구가 출력됩니다.

 

 

FID (First Input Delay), TBT (Total Blocking Time)

CLS (Cumulative Layout Shift)

 

 


참고 자료

성능 최적화 관련

https://ui.toast.com/fe-guide/ko_PERFORMANCE

 

성능 최적화

애플리케이션 성능 최적화는 앱과 웹에서 모두 중요하다. 최근 웹 애플리케이션은 Ajax 통신, 복잡한 UI 등 많은 기능을 담으면서 크고 무거워졌다. 무거워진 웹은 긴 로딩 시간 함께 사용자 경험

ui.toast.com

LCP 관련
https://web.dev/optimize-lcp/

https://ui.toast.com/posts/ko_202012101720

preconnect 관련
https://developer.chrome.com/ko/docs/lighthouse/performance/uses-rel-preconnect/

https://www.keycdn.com/support/preconnect

https://www.keycdn.com/blog/resource-hints

https://www.igvita.com/2015/08/17/eliminating-roundtrips-with-preconnect/

https://web.dev/preconnect-and-dns-prefetch/