웹사이트 최적화: 브라우저 처리 과정
브라우저
- 브라우저는 1. 서비스 이동, 2. 리다이렉트, 3. 어플리케이션 캐시 확인, 4. 네트워크 통신, 5. 브라우저 처리 단계로 나누어지며 각 단계마다 최적화에 고려해야 할 사항들이 있다.
동작 방식 기반 최적화
- 웹페이지 최적화는 브라우저가 네트워크와 통신하는 과정과 브라우저에서 페이지를 표시하는 과정에서의 응답 속도를 개선하는 것이기 때문에 브라우저가 어떻게 동작하는지 이해하는게 좋다.
서비스 이동(prompt for unload)
-
사용자가 웹 서비스를 이용하다 다른 주소로 이동할 때 브라우저가 제일 먼저 실행
-
사용자가 웹 서비스를 이용하다 다른 주소로 이동할 때 브라우저가 제일 먼저 실행하는 단계로 페이지가 표시될 떄 이벤트가 할당되고 메모리를 사용하게 되는데 이 메모리를 더이상 사용하지 않을 때(페이지를 떠날 때) 메모리를 해제해야한다. 필요없는 메모리를 해제(가비지 컬렉션)하지 않으면 브라우저가 응답 없음 상태가 되거나 실행 속도가 급격히 느려지게 된다.
-
DOM의 생성과 삭제가 많거나, 한 페이지에 통신이 많거나, 이벤트 바인딩 수가 많은 페이지 혹은 사용자의 체류 시간이 긴 페이지를 개발할 때는 필요없는 변수나 오브젝트 삭제, 이벤트 해제 등을 활용해 메모리를 관리한다.
redirect
-
사용자가 요청한 URL에서 다른 URL로 다시 보내는 단계
-
리다이렉트가 발생하면 301 혹은 302 코드를 반환하는데 이는 HTTP 요청을 완수하기 위해서는 user agent 가 추가적으로 문언가를 해야하다는 것을 의미하며 어떤 자원도 다운로드 하지 않고 브라우저에 일시적으로 빈 페이지가 보인다.
-
URL 뒤에 trailing slash를 넣으면 더 빠른 속도로 리소스를 찾을 수 있다.
*트레일링 슬래시를 URL 끝에 붙이는 것은 해당 URL 리소스가 디렉토리(directory)임을 의미하며 붙이지 않은 것은 해당 URL 리소스가 파일(file)임을 의미한다. 트레일링 슬래시가 없을 경우 서버는 해당 리소스를 우선 파일로 간주하여 해당 이름의 파일이 존재하는지 확인하고 없을 경우 디렉토리를 확인한다. 그 후 디렉토가 있으면 그 안의 기본파일을 확인한다. 트레일링 슬래시가 있을 경우 서버는 해당 해당 이름의 디렉토리를 확인하고 디렉토리가 있으면 그 안의 기본 파일을 확인하기 때문에 디렉토리 리소스를 요청하는 경우 트레일링 슬래시를 명시한다면 파일 확인을 하는 동작을 생략할 수 있다. 파일 리소스에 트레일링 슬래시를 붙일 경우 디렉토리를 확인하고 디렉토리가 없을 경우 동명의 파일을 확인하지 않기 때문에 404 에러 페이지를 보게된다.
https://www.google.com/example/ -> 디렉토리
https://www.google.com/example -> 파일
어플리케이션 캐시 확인(App cache)
-
브라우저의 캐시에 데이터가 있는지 확인한다.
-
리다이렉트 작업을 마치고 HTTP 요청을 처리하기 위한 준비가 끝나면 먼저 서버로 요청을 보내게 된다. 서버에서 응답이 오면 개별요소(이미지, 스타일시트, 자바스크립트)가 사용자 PC에 있는지 캐시 데이터를 찾게 된다. (캐시 데이터의 종류에는 쿠키, 이미지, 스크립트, 스타일시트가 있다.)
-
성능 향상을 위한 가장 효과적인 방법을 브라우저와 서버 사이의 통신을 최대한으로 줄이는 것이며 이를 위한 캐시를 잘 활용해야한다.
네트워크 통신 단계(DNS, TCP, Request, Response)
-
브라우저가 네트워크와 통신해서 웹페이지와 구성 요소를 다운로드하는 단계
-
Blocked
-
브라우저에서 리소스를 호출하기 전에 소요되는 대기시간으로 브라우저 캐시를 확인하는 시간과 네트워크에 연결하기 전에 소요되는 준비시간으로 이뤄진다.
-
네트워크에 연결하기 전에 소요되는 대기시간은 브라우저 동시 연결 개수와 밀접한 관련이 있으며 도시 연결 개수가 많을 수록 대기 시간은 짧아진다.
-
-
DNS
- 호스트 이름으로 IP 주소를 조회한 시간으로 이 작업이 완료되지 않으면 어떤 자원도 다운로드 하지 않는다.
- 브라우저에서 IP 주소를 조회할 떄 동일한 호스트로 요청하는 요솔는 다시 IP 주소를 확인하지 않아 시간이 추가로 걸리지 않는다. 하나의 호스트로 모든 리소스를 호출하면 시간을 줄일 수 있지만 호스트별 도시 연결 기능은 포기해야하므로 하나의 웹페이지를 기준으로 2~4개 정도의 호스트를 사용하는 것을 권장한다.(보통 이미지 크기가 크고 개수가 많은 이미지 검색 서비스 개발시 고려)
-
TCP
- 웹 서버와 TCP 연결을 생성하는데 필요한 시간으로 프론트에서는 줄일 수 없다.
-
Request
- TCP 연결이 이뤄지면 우너하는 정보를 서버에 보내는 시간으로 주로 요청 헤더 정보를 보내는 시간이다. 요청 시간을 파일 올리기 처럼 보내야할 정보가 많을수록 오래걸린다.
-
wait
- 서버에서 보내는 응답 메세지를 받기까지 대기시간으로 서버 연산 처리 시간이다.
-
Response
- 서버에서 보내는 응답 메세지를 받는 시간으로 해당 요소의 데이트 크기에 비례하기 때문에 사용자의 네트워크 상태에 따라서 다를 수 있다. 성능을 개선하기 위해서 데이터 크기를 줄이기 위해 Gzip과 같은 파일 압축을 사용할 수 있다.
- 동적인 기능이 많아져 자바스크립트 파일의 크기를 줄이기 위해서는 주석이나 공백을 없애 코드의 양을 줄이고, 코드의 양을 줄인 파일을 Gzip 등으로 압축해서 줄인다.(원본 파일의 30% 정도로 줄어든다 )
-
TTFB(Time To First Byte)
- 서버가 해당 요소의 첫번째 바이트 정보를 브라우저에 보내는데 걸린 시간으로 프론트에서는 조절할 수 없다.
-
Cache Read
- 사용자 PC에 저장되어 있는 캐시를 읽어오는 시간으로 캐시가 설저오디어 있지 않으면 많은 단계를 거친다.
브라우저 처리(processing, onload)
- 다운로드한 웹 페이지 구성 요소로 웹 페이지를 화면에 그린다.
- processing 과 onLoad에 해당하는 브라우저 처리 단계는 서버에서 받은 HTML과 이미지, 스타일 시트를 조합해 사용자가 실제로 보는 화면을 만든다. 서버에 요청한 요소가 모두 도착하면 DOM을 생성하기 시작하고 조작하는 시점에 따라 응답속도가 달라질 수 있다.
위 이미지에 따른 처리 과정을 보자면
- HTML 마크업을 처리하고 DOM 트리를 빌드한다.
- CSS 마크업을 처리하고(parse stylesheet) CSSOM 트리를 빌드한다.
- DOM 및 CSSOM을 결합하여 렌더링 트리를 형성한다.
- 렌더링 트리에서 레이아웃을 실행하여 각 노드의 형태를 계산한다.
- 개별 노드 화면에 페인트한다.
- 페이지 초기 렌더링 이후 UI 상태가 변경된다고해도 위 프로세스의 전체 혹은 일부를 거쳐 화면이 그려지게 되기 때문에 최적화를 하여 초기 렌더링 시간을 줄이며 이후 업데이트 시간도 함께 줄일 수 있다.
Build DOM Tree
- Document Object Modl은 브라우저가 웹 페이지를 잘 핸들링 하기 위해 필요한 객체이다. 브라우저는 수신받은 HTML을 가지고 Bytes>Caracters>Tokens>Nodes>DOM의 과정을 거쳐 DOM Tree 를 만든다.
- Bytes > characters
- 브라우저가 HTML의 바이트를 다스크나 네트워크에서 읽어와서 해당 파일에 대해 지정된 인코딩에 따라 개별 문자로 변환한다.
- characters > Tokens
- 브라우저가 문자열을 W3C HTML5 표준에 지정된 고유 토큰으로 변환하며 각 토큰은 특별한 의미와 고유한 규칙을 가진다.
- Tokens > NOdes
- 토큰은 해당 속성 및 규칙을 정의하는 객체로 변환된다.
- Nodes > DOM
- HTML 마크업이 여러 태그간의 관계를 정의하기 때문에 생성된 객체는 트리 데이터 구조 내에 연결된다.
Build CSSOM Tree
수신된 CSS 규칙을 브라우저가 이해하고 처리할 수 있는 형식으로 변환하며 HTML과 동일한 프로세스가 적용되며 마지막 DOM 부분만 CSSOM으로 대체된다.
Build Render Tree
DOM은 컨텐츠, CSSOM은 스타일 규칙을 설명하는 독립적인 개체이다. 각각의 개체를 가지고 화면에 픽셀을 찍기 위해서는 두 객체를 합쳐 Render Tree 를 만들어야한다.
- DOM 트리의 루트에서 시작하여 표시되는 노드를 각각 traverse 한다.
-
스크립트 태그, 메타 태그, display none 속성을 가진 일부 노드는 표시되지 않으며 렌더링된 출력에 반영되지 않으므로 생략된다.
-
필요에 따라 1개 이상의 레이어가 만들어지며 레이어 중간에 GPU 처리가 필요하면 graphic layer 가 만들어진다.
-
표시된 노드에 대해 적절하게 일치하는 CSSOM 규칙을 찾아 적용한다.
-
표시된 노드를 콘텐츠 및 계산된 스타일과 함께 내보낸다.
layout(Reflow)
노드와 노드의 스타일이 표시된 화면의 정확한 위치 및 크기를 계산한다. 페이지에서 각 객체의 정확한 크기와 위치를 파악하기 위해 브라우저는 렌더 트리 루트에서부터 탐색하며 각 노드의 box type을 확인한다. Type이 block 이면 세로로 Inline이면 가로로 box 의 위치를 계산한다.
Paint, Rasterize, Composite layer(Repaint)
레이아웃 과정이 완료되면 브라우저가 pain 이벤트를 발생히켜 노드를 픽셀로 변화한다. 레이아웃 과정에서 render layer 가 2개 이상 생성되면 각각의 layer를 painting 한 뒤 하나의 이미지로 composite 하는 과정을 추가로 거쳐 브라우저에 표현한다.
- paint/rasterize
- paint 는 렌더트리를 화면의 픽셀로 변환하는 프로세스이다. 텍스트, 색, 이미지, 경계 및 그림자 등 요소의 모든 시각적 부분을 그리는 작업을 포함한다. paint 는 그릴 호출 목록을 호출하고 실제로 픽셀을 채우는 작업은 rasterize라고 한다.
- composite
- 사용된 HTML이나 CSS 속성에 따라 여러개의 layer가 생성된 경우 생성된 layer 들을 합성하여 한장의 bitmap으로 만드는 과정이다. 각 layer 별로 paint 되기 때문에 불필요한 painting을 줄여 효율적으로 그릴 수 있다.