웹 성능에 중요한 부분
웹 페이지를 불러오는 데 전반적으로 영향을 미치는 네트워크 수준의 지표
- 지연 시간 : IP 패킷이 한 지점에서 다른 지점으로 이동하는 데 걸리는 시간. 왕복 시간(Round-Trip Time, RTT) 는 지연 시간의 두 배.
- 대역폭
- DNS 조회
- 연결 시간
- TLS 협상 시간 : HTTPS 연결 시 SSL(Secure Socket Layer), TLS(Transport Layer Security) 협상이 필요. 왕복 시간이 더 추가
서버 자체의 내용이나 성능에 좀 더 의존적인 지표
- TTFB(Time To First Byte) : 클라이언트가 웹 페이지 탐색을 시작한 때부터 기준 페이지 응답의 첫 번째 바이트를 수신한 때까지 걸린 시간
- 콘텐츠 다운로드 시간 : 요청한 개체에 대한 TTLB(Time To Last Byte)
- 렌더링 시작 시간 : 사용자가 빈 페이지를 바라본 시간
- 문서 완성 시간 ( 또는 페이지 로딩 시간 )
- 바이트 수의 증가 : 페이지 크기, 이미지 크기, 자바스크립트와 CSS의 크기가 증가
- 개체 수의 증가
- 복잡도의 증가 : 많은 기능이 추가된 페이지는 렌더링 시간이 길어진다. 모바일 환경은 처리 능력이 떨어지기 때문에 체감이 더 된다.
- 호스트 수의 증가 : 수많은 참조 호스트들은 추가적인 DNS 조회 시간, 연결 시간, TLS 협상 시간을 의미
- TCP 소켓 수의 증가 : 이는 호스트당 연결 협상 오버헤드를 증가, 디바이스의 부하를 가중, 네트워크 연결 과부하, 재전송과 버퍼블로트(bufferbloat)로 실효 대역폭 저하를 유발
HOL 블로킹
브라우저는 대개 한 번에 많은 개체를 가져오려고 한다. 단일 연결 상 브라우저는 요청 하나를 보내고 그 응답을 수신한 후에 또 다른 요청을 보낸다. 이러한 여러 요청이나 응답 중 어디엔가 문제가 발생하면 그 요청/응답을 뒤따르는 다른 모든 것들이 막힌다. 이 현상을 HOL 블로킹(Head of line blocking)이라고 한다.
이로 인해 웹 페이지의 전송과 렌더링이 중단될 수 있다.
TCP 혼잡 회피 메커니즘
혼잡 윈도우(Congestion Window) : 수신자가 확인(ACK)하기 전까지 송신자가 전송할 수 있는 TCP 패킷의 수
느린 시작(Slow Start) : 새로운 연결이 네트워크 상태를 감지해 이미 혼잡한 네트워크를 악화시키지 않게 함. 송신자가 ACK를 수신할 때마다 패킷 수를 늘려서 전송이 가능
경기장 효과(Stadium Effect)
DNS 조회 최적화하기
- 도메인/호스트이름의 수 제한하기
- 조회 지연 시간을 줄이기
- 초기 HTML이나 응답에 대해 DNS prefetch 활용하기. 초기 HTML을 내려받아 처리하는 동안 그 페이지에 있는 특정 호스트이름들의 DNS 조회를 시작할 것
1 | <link rel="dns-prefetch" href="//ajax.googleapis.com"> | cs |
DNS의 고정적인 오버헤드를 최소화시켜 줌
TCP 연결 최적화하기
- preconnect 활용하기. 필요하기 전에 미리 연결을 수립함으로써 폭포수 임계 경로(waterfall critical path)에서 연결 시간을 제거
- 조기 종료(early termination)을 사용. 콘텐츠 전송 네트워크(Content Delievery Network, CDN)를 활용하면, 요청하는 클라이언트와 가까이 위치한 인터넷 경계(edge)에서 연결을 종료시킬 수 있음. 왕복 지연을 최소화 해줌
- HTTPS 최적화 시 최신 TLS 모범 사례를 실행하기
1 | <link rel="preconnect" href="//fonts.example.com" crossorigin> | cs |
리다이렉션 피하기
- CDN 활용하여 클라이언트 대신 '클라우드에서' 리다이렉션 수행하기
- 동일한 호스트 리다이렉션일 경우 대신, 웹 서버에서 'Rewrite Rules'를 사용하여 원하는 자원으로 연결시키기
리다이렉션은 종종 검색 엔진 최적화(Search Engine Optimization, SEO)에서 단기 검색 결과 순위나, 백엔드 정보 레이아웃 변경을 피하는데 사용한다. SEO의 이득만큼의 가치가 있는지 판단할 것
클라이언트에 캐싱하기
- 이미지 또는 버전이 관리되는 콘텐츠와 같은 정적 콘텐츠는 영구적으로 클라이언트에 캐싱할 수 있음. 그러나 이후 콘텐츠를 다시 원본으로부터 가져와야 할 때가 있기 때문에, 실제 TTL은 유저 환경에 달려있다.
- CSS/JS와 맞춤형 개체의 경우, 평균 세션 기간의 2배 정도 캐싱. 통계적으로 대부분의 사용자가 해당 웹사이트를 돌아다니는 동안 로컬에서 자워늘 가져올 수 있을 만큼 길고, 다음 세션에서 네트워크에서 새로운 콘텐츠를 가져오게 할 만큼 짧다.
- 그 외, 요구 사항을 근거로 최적의 결정
네트워크 경계에 캐싱하기
- 여러 사용자 간 공유 가능한 자원
- 어느 정도 노후도(stateness)를 수용할 수 있는 자원
유저의 개인정보같은 민감한 정보는 캐싱하면 안 된다.
조건부 캐싱
- If-Modified-Since HTTP 헤더를 요청에 포함. 최신 콘텐츠가 헤더에 명시된 시점 이후에 갱신된 경우에만 전체 콘텐츠를 반환. 그렇지 않으면 응답 헤더에 새 타임스탬프 Date 를 포함한 304 응답을 반환.
- 개체를 식별하는 고유한 엔티티 태그, ETag 를 요청에 포함. 서버가 현재 ETag와 요청 헤더의 ETag와 비교한 후, 동일하면 304를 반환, 다르면 전체 콘텐츠를 반환.
대부분의 웹 서버에서 이미지와 CSS/JS에 이 기법을 적용. 다른 캐싱된 콘텐츠에도 적용하는지 확인해봐야 함.
압축과 축소화
텍스트 형태의 모든 콘텐츠(HTML, JS, CSS, SVG, XML, JSON, 폰트 등)는 압축(Compression)과 축소화(minification)의 이점을 볼 수 있다.
더 적은 바이트 수는 더 적은 왕복을 의미하고 시간도 덜 소요됨을 의미한다.
축소는 쓸데 없는 바이트를 줄여준다.
압축은 축소된 개체를 한 번 더 줄일 수 있다. 손실 없이 복원할 수 있는 알고리즘을 사용해 개체의 크기를 줄인다. 흔히 gzip과 디플레이트(deflate)를 사용하고, 최근에 등장한 브로틀리(Brotli) 등의 방식이 있다.
CSS/JS 차단을 피하기
- JS의 사용 여부를 주기적으로 재확인하기. 더 이상 필요 없는 JS를 다운로드 받고 있는 것은 아닌지 확인하고, 필요 없는 JS를 제거하는 것이 가장 빠른 대처다.
JS의 실행 순서는 중요하지 않고 onload 이벤트가 시작되기 전에 JS가 실행해야 한다면, async 속성을 설정하기. 이는 HTML 파싱과 동시에 JS를 내려받으며, 전반적인 사용자 경험을 대폭 개선할 수 있다. document.write 를 사용할 경우, 페이지 표시가 중단될 수 있기 때문에 주의 깊게 테스트해야 한다.
JS의 실행 순서는 중요하고 DOM이 로딩된 후에 JS를 실행해도 된다면, defer 속성을 사용하기
JS가 초기 화면 구성에 중요하지 않다면, onload 이벤트가 발생한 후에 JS를 가져와서 처리하는 것이 좋다.
메인 onload 이벤트를 지연시키고 싶지 않다면, 메인 페이지와 별개로 처리되는 iframe 으로 JS를 가져오는 것을 고려할 수도 있다. 그러나 iframe을 통해 내려받은 JS는 메인 페이지의 요소(element)에는 접근할 수 없다.
1 | <script async src="/js/myfile.js"> | cs |
1 | <script defer src="/js/myfile.js"> | cs |
이미지 최적화하기
- 메타데이터(위치, 타임스탬프, 크기 등의 정보)를 제거하기. 저작권과 ICC 프로파일 데이터는 제거하면 안 된다. PNG 의 경우 보통 10% 가량 줄어든다.
- 사용자의 디바이스, 네트워크 상태, 기대 화질에 맞추어 이미지를 제공하기. 이미지 오버로딩(overloading) : 이미지의 원본 크기가 브라우저의 창 크기를 넘거나 이미지 해상도가 디바이스 화면의 범위를 넘어, 브라우저에 의해 이미지의 크기가 자동으로 줄어드는 것. 브라우저가 이 작업을 하면, 대역폭뿐 아니라 CPU 자원을 낭비하게 되며, 휴대용 디바이스에서 큰 영향을 미친다.
출처 : 러닝 HTTP/2
'Front-End > Front-End 자료실' 카테고리의 다른 글
CSS Flex 귀여운 개구리로 실습해보자 (0) | 2020.05.27 |
---|---|
HTTP/2 프레임 정리 (2) | 2018.07.22 |
구글크롬 HTTP/2(h2) 프로토콜 디버깅 툴 (0) | 2018.07.22 |
[CSS] 글 드래그 시 나오는 색상 바꾸기 '::selection' (0) | 2018.06.03 |
티스토리 키보드 자판 효과내기. 단축키 효과 (2) | 2018.05.28 |
댓글