성능

웹 성능

웹페이지가 로딩되고 작동하는 속도와 효율성을 측정한 것

최적의 성능을 유지하는것은 긍정적인 사용자 경험을 보장하는데 매우 중요

브라우저 동작 원리

렌더링

렌더링의 주요 단계는 레이아웃, 페인트 단계

  • 브라우저는 HTML 문서를 받으면 파싱 처리함

  • 파서는 받은 문서를 읽고 DOM 트리를 생성

  • 브라우저는 DOM 트리를 사용해 컨텐츠 렌더링함

    • 레이아웃 단계에서 CSS 스타일과 레이아웃 규칙을 기반으로 페이지의 각 요소의 위치와 크기를 계산

    • 레이아웃을 완료하면 페인트 단계에 진입하여 각 요소를 화면에 그림

  • 주로 브라우저는 레이아웃을 계산하는데 많은 시간을 소요함

    • 페이지의 요소 수를 최소화하거나 CSS Grid, Flexbox를 사용해 레이아웃을 단순화시키자

로딩

  • HTML 문서를 받아 참조된 다른 리소스들을 로딩하기 시작함

  • 로딩해야할 리소스들이 많으면 병목이 생김

  • lazy loading, prefetching, preloading, resource hint

자바스크립트 비용 줄이기

다운로드 시간 (네트워크 전송)

자바스크립트 번들의 크기를 작게(특히 모바일기기를 위해) 유지해야한다.

  • 하나의 거대한 번들의 사용을 피하자

  • 번들의 크기가 50~100KB를 초과한다면 작은 번들로 나눠야한다.

  • HTTP/2 멀티플렉싱을 사용하면 복수 요청과 응답 메시지를 전송하여 추가적인 요청의 오버헤드를 줄일 수 있다.

실행 시간

다운로드를 완료한 뒤 스크립트 실행 시간이 대부분의 비용을 차지함

  • 브라우저의 메인스레드가 자바스크립트를 실행하느라 바쁘면 사용자 인터렉션이 지연될 수 있음

  • 스크립트 실행 시간과 네트워크 관련 병목을 최적화하는것이 영향을 끼침

  • 메인스레드를 오래 점유하는 긴 테스크 피하기

    • 작은 작업으로 분할

    • 로드되는 순서의 우선순위를 지정

  • 거대한 인라인 스크립트 피하기

    • 스크립트 크기가 1KB를 넘으면 인라인으로 작성하지 않기

    • 1KB는 외부 스크립트에 관한 코드 캐싱을 실행하는 크기이기도 함

파싱과 컴파일

2024 기준 파싱과 컴파일 비용은 과거만큼 높지 않다. (덜 중요하게됨)

  • Chrom V8 엔진은 메인스레드의 파싱과 컴파일 양이 평균 40% 줄음

    • 워커 스레드로 작업 분할

  • 메인 스레드를 중지시키지 않고 자바스크립트를 파싱 및 컴파일 할 수 있음

  • V8 엔진 (바이트)코드 캐싱 최적화

    • 스크립트가 처음 요청되면 다운받고 V8에게 컴파일 지시 및 브라우저의 온디스크에 캐시

    • 두 번째 요청에서 파일을 캐시에서 꺼내고 V8 재컴파일 지시 (컴파일된 코드는 직렬화되어 캐싱된 스크립트 파일에 메타데이터로 추가)

    • 세 번째 요청에선 두 파일을 모두 꺼내고 캐시에서 해당 파일의 메타데이터를 꺼내 V8에 전달

    • V8은 메타데이터를 역직렬화 후 컴파일을 건너뜀

    • 첫 두 번의 방문이 72시간 안에 발생하면 코드 캐싱함

모바일 기기

자바스크립트는 모바일 기기의 배터리 수명에도 영향을 미칠 수 있음

  • 자바스크립트를 실행하기 위해서는 많은 CPU 리소스 필요

  • 느린 CPU가 탑재된 모바일에서는 자바스크립트 실행시간이 중요

    • 번들의 크기 줄이기

    • 큰 번들을 작은 번들로 나누기

    • 메인 테스크를 블로킹하는 긴 테스크 피하기

상호작용 최적화

상호작용 대비는 상호작용에 대해 웹페이지가 얼마나 빠르게 반응할 수 있는지를 평가하는 웹 성능지표

  • 웹 성능의 핵심 지표

  • 상호작용 대비는 네트워크 지연, 서버 처리 시간, 브라우저 렌더링 성능 등 다양한 요소의 영향을 받음

  • TTI, time to interactive

    • 상호작용 시작 시간

  • TBT, Total Blocking Time

    • 사용자 입력에 응답하지 못하는 총 시간

  • INP, Interaction to Next Paint

    • 상호작용 시작 후 스크린에 다음 프레임이 그려지는 순간까지 응답성 측정

  • startTransitionSuspense를 사용하여 개선 할 수 있음

    • 앱이 대규모 트랜지션 중에도 호버 및 클릭에 보다 잘 반응하게됨

    • Next.js 앱라우팅은 기본적으로 startTransition을 사용해 라우트를 전환한다

네트워킹

  • HTTP/3은 QUIC 전송 프로토콜을 사용하는데 지연과 혼잡율을 줄이고 멀티플렉스 스트림과 커넥션 마이그레이션을 지원하기 위해 설계됨

  • 스트리밍은 전체 파일 혹은 리소스가 로딩될 때까지 기다리지 않고 데이터를 조각으로 보내고 받을 수 있는 능력

    • 사용자들이 보다 컨텐츠를 빠르게 소비하게 함으로써 성능 개선

  • 플러싱은 전체 응답이 생성되기 전에 데이터를 브라우저에게 보낼 수 있는 능력

    • 컨텐츠를 스트리밍하는데 유용

    • 모든 리소스가 로딩되기 전에 페이지 렌더링을 시작해서 인지된 성능을 개선

서드파티 의존성 줄이기

대규모 앱에서 서드파티 의존성은 때때로 성능 병목에 가장 큰 영향을 주는 요소가 될 수 있음

가장 비싼(느린) 의존성 식별

  • 로딩과 실행에 가장 많은 시간을 사용하는 서드파티 의존성이 무엇인지 식별해라

    • 라이트하우스, WebPageTest 같은 도구 활용

각 의존성의 필요성 평가

  • 이 의존성이 앱의 핵심 기능에 필수적인지 확인

  • 더 작거나 빠른 대안으로 대체할 수 있는지 확인

대체 라이브러리 고려

  • 핵심 기능에 필수적이지 않다면 더 작고 빠른 대안 라이브러리로 대체할 것을 고려

의존성 로딩 최적화

  • 지연 로딩, 코드 분할, 트리 셰이킹 같은 기법 사용해서 서드파티 의존성의 로딩을 최적화

    • 지연 로딩: 의존성이 필요할 때만 로딩

    • 코드 분할: 코드를 작은 덩어리로 나누고 필요할 때만 로딩

    • 트리 셰이킹: 번들러들이 사용하는 기법으로 빌드시 사용하지 않는 코드들 제거

CDN 호스팅 사용

  • CDN 호스팅을 사용하면 로딩 시간을 줄이고 성능 개선하는데 도움됨

  • 사용자들이 자신과 가까운 서버로부터 의존성을 다운로드

  • 더블 키 캐싱을 사용하면 CDN 캐싱의 이익을 크게 줄일 수 있다는 점을 유의

    • 동일한 URL을 사용하더라도 쿼리 파라미터나 세부 사항에 따라 캐시가 달라질 수 있기 때문에, 캐시 히트율(cache hit rate)이 감소하고, 캐시 효율성이 떨어질 수 있음

번들 분석

서드파티 의존성 구성을 최적화

몇몇 서드파티 의존성은 그 성능을 개선하기 위해 최적화될 수 있는 구성을 갖음

  • 예를 들어 시각화 라이브러리를 사용한다면 표시되는 항목의 수를 제한함으로서 렌더링되는 데이터 양 줄이기

렌더링 패턴

각 패턴은 특정 유스 케이스를 해결하기 위해 설계된 것으로 적절한 패턴을 사용

  • partial hydration: 클라이언트에서 컴포넌트의 일부만 수화 (서버 컴포넌트)

  • progressive hydration: 클라이언트에서 컴포넌트 수화 순서 통제하기

  • islands arhitecture: 정적 사이트에 여러 엔트리 포인트가 있는 동적 행동의 고립된 섬

  • incremental static generation: 초기 빌드 이후 정적 사이트를 동적으로 수정하는 기술 (ISR)

  • streaming SSR: 서버측에서 렌더링된 컨텐츠를 작은 스트림으로 나누는 것

  • resumability: 서버에서 프레임워크 상태를 직렬화해 클라이언트가 중복된 코드 없이 실행 재게

  • edge rendering: 렌더링된 HTML을 에지에서 대체한 뒤 이를 클라이언트로 보냄

인지된 성능 최적화하기

인지된 성능은 앱의 로딩 및 응답 속도와 관련된 주관적인 경험을 뜻함

  • 시각적 단서, 피드백, 애니메이션 같은 다양한 요소에 영향을 받음

  • 인지된 성능을 개선하면 실제 로딩시간이 느리더라도 보다 나은 사용자 경험을 만들 수 있음

  • 핵심적인 사용자 경험이 실질적으로 더 빨리 로딩되도록 하기 위해 완료해야 하는 작업을 방해해선 안됨

  • 스켈레톤과 플레이스홀더 UI

    • 인지된 성능을 전반적으로 개선

    • 최종 컨텐츠를 정확하게 반영하지 않기 떄문에 사용자를 혼란스럽게 만들거나 불만을 갖게 만들 수 있음

    • 스켈레톤을 올바르게 구현하지 않으면 사용자 주의를 산만하게 만들 수 있음

레퍼런스 자료 사이트

서비스 워커, 사전 캐싱, 내비게이션 사전 로딩

스트리밍

V8 코드 캐싱과 바이트코드 캐시

Stale-While-Revalidate

브로틀리 압축

조기 힌트, 우선 힌트, HTTP/3

클라이언트 힌트

적응적 로딩

리스트 가상화

콘텐츠 가시성

이미지 최적화

성능 문화

조직이 웹 성능에 관해 갖는 태도나 접근법을 가리킴

성능은 비즈니스 성공을 위한 핵심적인 지표

  • 대규모 조직에서 이런 문화로 움직이는데까지는 시간이 걸린다.

  • '빨라지는 것이 하나의 도전'이라면 '빠름을 유지하는 것'은 또 다른 도전임을 깨닫는데 의의

  • 건강한 성능 문화를 구축하는 것은 웹 성능을 우선하고, 과학적 방법론을 프로세스에 통합하고, 데이터 주도 접근법을 사용해 시간이 지남에 따라 성능을 개선하는 것을 포함한다.

  • 성능 문화는 조직이 지속적인 속도를 달성하고, 잠재력을 최대화하면서 동시에 보다 나은 사용자 경험을 제공하고 비즈니스 성공을 이끄는데 도움을 준다.

Last updated