본문 바로가기
BOOKS

[웹 성능 최적화 기법]웹에서 가속을 끌어내는 방법

by zieunee 2023. 4. 10.
반응형

웹 브라우저 동작 이해

  • 웹사이트 주소 입력 함으로써 서버로부터 웹페이지를 다운로드 한다.
    • 도메인 서버와 통신하여 접속하려는 호스트의 IP를 찾는다.
    • 해당 아이피를 가진 서버와 통신을 시도해 TCP연결을 맺는다.
    • (HTTPS에서는 암호화된 연결을 생성하려는 협의단계 추가됨)
    • 서버로부터 리소스를 다운로드해 이를 화면에 표현한다.
      • 방문페이지 HTML을 서버에 요청해 다운로드 한다.
      • HTM구문을 분석하면서 HTML에 참조된 CSS, 자바스크립트, 이미지, 폰트 등의 하위 리소스들을 차례로 다운로드 한다.
      • 화면에 그리는 작업 절차 진행 (= 렌더링 경로)

브라우저 아키텍쳐

  1. 유저 인터페이스
    1. 사용자가 브라우저를 통해 상호작용 할 수 있도록 돕는다. 브라우저 주소 입력창, 북마크, 앞뒤버튼 등.. 기능을 가지고 있음
  2. 브라우저 엔진
    1. 유저인터페이스와 렌터링 엔진 사이에서 렌더링 상태를 조회하고, 렌더링 작업을 제어하기 위한 인터페이스 제공
  3. 렌더링 엔진
    1. HTML을 분석하여 그대로 표현하거나 CSS를 분석해 웹 페이지를 멋지게 꾸미기도 하는 등 실제 웹 콘텐츠를 브라우저 창에 그리는 역할
  4. 네트워킹
    1. HTTP요청을 보내고 응답받는 역할을 한다.
  5. UI백엔드
  6. 자바스크립트 해석기
  7. 데이터 저장소

중요 렌더링 경로

렌더링 엔진 → 단일 스레드에 의해 수행됨…!

HTML분석하면서 DOM트리를 만들고 CSS를 분석하여 CSSOM트리를 만든다. 트리모델을 결합해 최종적으로 렌더 트리를 만든다. 이를 기반으로 페이지 구조를 결정하고 화면에 표현한다.

렌더 트리 생성

DOM트리의태그는 렌더링 하는데 아무런 의미가 없으므로 제외.. 대신 최상위 노드인 루트노르를 중심으로 하위 노드의 위치가 결정된다.

display:none이면 렌터트리에서 제외된다.

레이아웃

레이아웃은 렌더트리 노드의 위치정보가 계산되는 단계이다.

브라우저 왼쪽위에서 시작해서 오늘쪽아래로 이동하며 사각형의 너비와 높이를 계산한다.

렌더트리의 루트 노드부터 계산 시작

루트 노드의 너비는 뷰포트의 크기로 지정됨. 부모노드에서 자식 노드로 재귀하여 반복 수행된다.

높이는 자식 노드의 높이에 따라 부모노드의 높이를 계산한다.

페인트

렌더트리 정보를 바탕으로 브라우저 창에 표현하는 단계

GPU를 이용해 준비된 렌더링 정보를 그린다.

** → 자바스크립트는 DOM, CSSOM을 동적으로 변경할 수 있으며 렌더트리가 변경되면 **레이아웃, 페인트 단계가 다시 수행된다.

이걸 최적화 해야한다!!

DOM최적화

  1. HTML구문 오류를 최소화하고 간소화 하기HTML 구문에 관대하다. 문법오류가 발생해도 브라우저에 정삭적으로 표현됨
  2. but 오류가 많을 수록 많은 메모리와 CPU파워를 소모한다.
  3. XML 정의된 구문을 엄격하게 따라야 한다.
  4. HTML태그를 중첩으로 사용하는 행위도 피해야 한다.
  5. 중첩되어 있으면 자바스크립트에 의해 스타일 변경될때 레이아웃 다시 계산하고 재구성하는데 많은 리소스와 시간이 소요됨

자바스크립트와 css배치

HTML과 CSS에서 사용하는 구문분석 알고리즘과 스레드가 다르다.

자바스크립트가 이미 생성한 DOM,CSSOM 언제든 변경 가능하다.

→ HTML구문 분석기가 HTML을 해석하다가 자바스크립트를 만나면 다운로드하고 수행완료될때 까지 DOM생성 작업을 중단한다.

→ CSS 구문분석처리 및 CSSOM작업이 진행중이면 자바스크립트가 변경하려는 스타일 시트가 생성되지 않았을 수도 있으므로 CSSOM이 완성될때까지 수행을 중지한다. 스타일 시트가 생성이 안되었기 때문에 스크립트 오류가 발생할 수 있다.

결론: CSS는 최대한 위쪽에 배치하여 CSSOM이 가능한 빨리 생성되도록 한다. 그리고 자바스크립트는 HTML아래쪽에 배치하여 DOM,CSSOM이 모두 생성된 이후에 수행될 수 있도록 한다.

자바스크립트 최적화하기

HTML아래쪽에 배치를 못하거나, 페이지 로딩 시간이 길어질 수 있다. 이런 로딩시간의 영항을 주는 것을 막으려면 자바스크립트 수행이 렌더링 스레드를 방해하지 않도록 “별도의 스레드”로 자바스크립트를 수행시켜야 한다.

OR 렌더링 작업이 어느정도 끝난 이후 스크립트를 수행해야 한다.

<script src=",,," async> </script>
<script src=",,," defer> </script>

async

HTML구문 분석과 동시에 자바스크립트를 다운로드 하고 수행되도록 한다.

→ HTML구문분석 + js다운 → js수행 → HTML구문분석

defer

구문 분석중에 별도의 스레드로 자바스크립트를 다운로드하고 구문분석이 끝난 이후에 수행되도록 한다.

→ 분석, 광고용 타사 자바스크립트들이 주로 사용하여 메인페이지 렌더링 프로세스에 영항을 주지 않도록 구현된다.

→ HTML구문분석 + js다운 → js수행

더 확실한 방법 : 브라우저가 페이지 로딩을 명시적으로 끝낸 후 나머지 스크립트를 수행시키는 방법 onload가 되면(로딩완료) 이후에 스크립트 수행 시킨다.

CSS 최적화하기

한파일에 통합하지 않기..! 처음 나오는 첫 렌더링 화면만 사용되게 하기

CSS는 필요한 정보만 빠르게 다운로드하고 실행해야 브라우저 렌더링을 가속시킬 수 있다. 적절히 분리하여 페이지에 필요한 CSS파일만 포함해야 한다.

  1. 적절하게 css를 분리한다.
    1. 미디어 쿼리 활용 >> 조건에 맞지않는 파일은 다운안한다.

이미지 로딩 최적화하기

display:none을 적용하기

그러나 DOM, CSSOM은 별도로 생성되기때문에 브라우저는 미리 알지못하고 DOM트리에 나타난 객체(이미지)를 다운한다.

  1. background-image속성을 사용한다.
  2. 자바스크립트를 이용한 지연로딩 방식을 적용해 불필요한 다운로드를 피한다.

도메인 분할 기법

여러 도메인을 소유한 경우 웹 콘텐츠를 병렬적으로 동시에 다운로드 할 수 있는 방법. HTTP1.1은 도메인에 순차적 다운로드 방식을 사용한다.

브라우저에서 보통 6개의 동시 연결을 지원한다.

도메인 분할기법 활용하면 쿠키 사이즈도 축소할 수 있다.

그러나 동시에 다운로드 할때 더 많은 CPU리소스를 사용할 수 있으므로 적절한 도메인 개수를 결정해야한다.

HTTP1.1의 Head Of Line Blocking현상을 해결한 HTTP2의 멀티플랙싱 기술로 도메인 분할기법을 사용할 이유가 사라졌다.

최근 HTTP/2기능을 저해하지않으면서 다중도메인을 사용할 방법은 TCP연결을 병합하는 방식이다.

이미지로딩,폰트사이즈 줄이기woff2(FOUT),background-image에 Hero이미지 사용하지않기, 필요한건 Preload하기 등등 있다.

반응형