(3) 백엔드 최적화 : 웹 서버, 웹 애플리케이션 서버, 데이터베이스, 로드 밸런싱, DNS 서버 등을 최적화한다.
백엔드 최적화하는 대표적 기술은 표와 같다.
DNS 응답이 빨라지도록 서버 증설한다. | CDN을 사용해 인터넷상에 콘텐츠 캐싱한다. |
---|---|
DNS 응답을 빠르게 할 수 있도록 DNS정보를 최대한 캐싱한다. | 데이터베이스 정규화로 디스크 I/O 최적화한다. |
웹 서버가 있는 데이터 센터의 네트워크 출력/대역폭 증설한다. | 데이터베이스 캐싱으로 응답을 빠르게한다. |
웹 서버, 웹 애플리케이션 서버의 CPU/RAM 증설한다. | 로드밸런싱을 통해 가장 성능이 좋은 웹 서버로 요청을 연결한다. |
프록시 서버를 설정하여 웹 콘텐츠를 캐싱 한다. | 웹 애프리케이션 로직을 가볍고 빠르게 개발한다. |
(4) 프로토콜 최적화 : HTTP 프로토콜 자체의 효과를 극대화하면 콘텐츠를 최도 속도와 최저 지연 시간으로 전달할 수 있다. 즉 프로토콜 최적화는 웹 콘텐츠를 더 빠르게 요청하고 응답하도록 프로토콜을 업그레이드하는 과정이다
(1) :
(2) TCP네트워크 대표적인 성능 지표 : 대표적인 성능 지표는 대역폭과 지연 시간이 있다.
(3) TCP 혼잡 제어 :
받는 쪽은 패킷이 정상적으로 송신되었음을 알리는 ACK 패킷을 보내며 ACK 패킷을 받은 호스트는 지속적으로 패킷을 보낼 수 있다. 호스트가 네트워크의 상태를 시시각각 파악하고 전송 속도를 조절하는 것 또한 혼잡 제어 기능 중 하나이다.
느린 시작은 전송 가능한 버퍼의 양인 혼잡 윈도우(CWND)의 초깃값을 작게 설정하여 전송한다. 예를 들어 통신이 시작되면 패킷 1개만 보내고, ACK를 받으면 패킷 2배인 2개를 전송한다. 이러한 과정을 패킷 유실이 발생하기 전까지 반복하는 방식이다. ACK 응답을 받지 못하면 혼잡윈도의 크기는 더 이상 늘리지 않는다.
이런 식으로 네트워크에서 수용할 수 있는 혼잡윈도우의 크기를 파악하면 그 이상의 패킷을 보내지 않는다. HTTP에서도 그대로 사용된다.
빠른 재전송은 먼저 도착해야 하는 패킷이 도착하지 않고 다음 패킷이 도착한 경우에도 수신자가 일단 ACK패킷을 보내는 방식이다. 중간에 패킷 하나 손실되면 송신자는 중복된 ACK 패킷을 통해 이를 감지하고 유실되었던 패킷을 재전송한다. 또한 중복된 패킷을 3개 받으면 반드시 손실된 패킷을 재전송한다.
(1) : HTTP는 콘텐츠를 웹에서 전달하기 위해 만들어진 프로토콜로 HTTP 성능을 개선하면 웹 성능도 향상된다.
(2) HTTP최적화 기술 : HTTP는 크게 여섯 차례 업데이트했다.
(3) HTTP 지속적 연결 :
위의 사진처럼 TCP의 통신을 연결하는 방식은 3 way handshake 방식이다.
초기 HTTP도 3 way handshake 방식으로 TCP 연결을 맺었다. 하지만 많은 웹 콘텐츠 전달에 번거로움이 발생했다.
HTTP 지속적 연결은 클라이언트와 서버가 TCP상에서 한 번 연결되면 둘 사이의 연결이 완전하게 끊어지기 전까지 맺어진 열결을 지속적으로 재사용하는 기술이다.
HTTP/1.0에서는 요청 헤더의 Connction : keep-alive를 통해서 가능하다. 그 후 HTTP/1.1 버전에서부턴 지속적 연결을 기본으로 지원한다. 필요하지 않은 경우만 Connection : close를 포함하면 된다.
(3) HTTP 파이프라이닝 :
HTTP 파이프라이닝은 HTTP 선입 선출 단점을 극복하는 방법이다.
(1) DNS란? : DNS는 인터넷 호스트명을 클라이언트와 서버가 이해할 수 있는 IP 주소로 변환해주는 시스템이다. 기억하기 쉬운 호스트명을 사용한다. DNS 질의, 응답 성능은 웹 사이트 로딩에 영향을 준다.
(2) DNS의 작동 원리 :
웹 브라우저에 www.naver.com을 입력하면 먼저 Local DNS에게 "www.naver.com"이라는 hostname"에 대한 IP 주소를 질의하여 Local DNS에 없으면 다른 DNS name 서버 정보를 받음(Root DNS 정보 전달 받음)
Root DNS 서버에 "www.naver.com" 질의
3. Root DNS 서버로부터 "com 도메인"을 관리하는 TLD (Top-Level Domain) 이름 서버 정보 전달 받음
TLD에 "www.naver.com" 질의
TLD에서 "name.com" 관리하는 DNS 정보 전달
6. "naver.com" 도메인을 관리하는 DNS 서버에 "www.naver.com" 호스트네임에 대한 IP 주소 질의
Local DNS 서버에게 "응! www.naver.com에 대한 IP 주소는 222.122.195.6 응답
Local DNS는 www.naver.com에 대한 IP 주소를 캐싱을 하고 IP 주소 정보 전달
출처:
(3) 사용 중인 다양한 도메인 확인 방법 : 최근 웹사이트는 다른 웹 서비스의 다양한 콘텐츠를 호출하여 사용한다.
크롬에서 [도구 더보기] -> [개발자 도구] -> [Source] 항목을 통해 어떤 도메인들이 사용되고 있는지 볼 수 있다.
(4) 웹 성능을 최적화하는 도메인 운용 방법 :
프리페치 사용 시 웹페이지 사용된 도메인들의 DNS를 조회하는 시간이 좀 더 빨라진다. 프리 페치란 하나의 웹페이지에 다수의 도메인 호스트명이 섞여있을 때 웹 문서 페이지를 여는 시점에 멀티스레드 방식으로 미리 DNS를 조회해 빠르게 IP주소를 불러오는 기술이다. 단 특정 브라우저는 프리 페치 기능을 지원하지 않을 수 있다.
(1) 브라우저란? : HTTP, DNS를 사용해 사용자가 원하는 HTML, 동영상 등의 웹 콘텐츠를 전달하는 소프트웨어이다.
(2) 브라우저의 역사와 특징 : 1900 초반 웹이 만들어진 시대와 함께 개발되었다. 초기 HTTP, DNS 기술 접목한 주소에서 접속할 웹 서버의 ip를 찾고 HTTP로 웹서버에 접속해 콘텐츠를 가져오는 단순한 기능을 수행했다. 그 후 익스플로러 3 버전 출시 후 CSS와 오디오가 추가되었고 점점 비디오 형태 증가로 HTML5, CSS3버전이 개발되었다.
속성들
(1) 내비게이션 타이밍 API란? : 웹 사이트의 성능을 측정하는데 사용할 수 있는 데이터를 제공한다. 정확한 종단 간 대기 시간 정보를 제공합니다.
(2) window.performance.timing 속성 :
timing 속성은 탐색과 페이지 로드 이벤트에 대한 데이터를 갖고 있다.
timing 속성은 페이지 로드 이벤트 시간을 1970년 1월1일 자정을 기준으로 측정한 값이다.
이것을 통해서 각 단계가 언제 완료 되었는지, 어떤 항목에서 시간이 지체되는지 확인할 수 있다.
0 값은 이벤트가 발생하지 않은 것이다.
(3) window.performance.navigation :
(4) window.performance.timing.navigation : 을 이용한 사용자가 느끼는 페이지 로딩 시간 값구하기.
<!DOCTYPE html><html lang="en">
<head>
<title>Document</title>
<script type="text/javascript">
functiononLoad() {//함수 정의var now =new Date().getTime();//현재시간 기록var page_load_time = now - performance.timing.navigationStart;//현재시간에서 로딩시간 차이console.log("사용자 인식 페이지 로딩시간 : " + page_load_time);
}
</script>
</head>
<body>
사용자가 인식하는 페이지 로딩시간 구하기.
<script>
onLoad();//onLoad 함수 실행
</script>
</body>
</html>
(5) performance.timing의 여러 이벤트들 :
<!DOCTYPE html><html lang="en">
<head>
<title>Document</title>
<script type="text/javascript">
functiononLoad() {
var perfData = window.performance.timing;
var pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
console.log(pageLoadTime);
var connectTime = perfData.redirectEnd - perfData.redirectStart;
console.log(connectTime);
}
</script>
</head>
<body>
여러가지 콘텐츠들
<script>
onLoad();
</script>
</body>
</html>