다양한 웹성능 최적화 기법 - DNS, 브라우저 타이밍 API, 이미지 최적화
카테고리: React
태그: Optimization
2.4 DNS
📌 DNS란? ‘인터넷 호스트명을 클라이언트와 서버가 이해할 수 있는 IP주소로 변환해주는 시스템’
- 일반 유저가 웹 사이트 접속을 위해 숫자로 이루어진 IP 주소를 기억하는 것은 어려움
- 따라서, 웹 서비스는 보통 사용자가 기억하기 쉬운 호스트명을 주소로 사용
💡 DNS 질의의 응답 성능이 나쁘면 로딩 성능에 영향 → 확인 및 개선 필요
2.4.1 DNS의 작동 원리
단계 | 설명 |
---|---|
로컬 DNS 서버로 질의 | - 브라우저, 운영체제, ISP의 캐시 확인 → 캐싱 값이 없다면 다음 단계 |
루트 DNS 서버로 질의 | - www.example.com 도메인에 대한 질의 |
- 전체 정보가 없으므로, .com 네임 서버의 IP 정보를 응답 | |
.com DNS 서버로 질의 | - www.example.com 도메인에 대한 질의 |
- example.com 네임 서버의 IP 정보를 반환 | |
example.com DNS 서버로 질의 | - www.example.com 도메인에 대한 질의 |
- www.example.com 네임 서버의 IP 정보를 반환 |
2.4.2 사용 중인 다양한 도메인 확인 방법
📌 모듈, 폰트, CSS 파일, 스크립트 등 외부 웹 서비스의 도메인
→ [개발자 도구] - [source] 항목에서 확인 가능
💡 특정 도메인 조회가 불가 / 지연 → 모듈 다운 후 자신의 웹 서버의 업로드하는 것도 고려
2.4.3 웹 성능을 최적화하는 도메인 운영 방법
공통 된 상위 도메인을 사용 하기
- 공통의 상위 도메인을 사용 시
- 캐싱 된 정보를 사용해 DNS 질의 시간 단축
- (HTTPS 사용 시) SSL 인증서를 와일드카드 형식으로 사용 → 인증서 발급 비용, 수고 줄어듬
DNS 프리 패치 기능 사용하기
📌 페이지 내 다수의 도메인 호스트명이 있을 때, 멀티스레드 방식으로 미리 DNS를 조회
<link **rel="dns-prefetch"** href="https://www.naver.com/" />
Can I use 서비스를 통해 dns-prefetch 기능의 브라우저 지원 범위 확인
- 오페라 미니 브라우저는 기능을 지원하지 않음
APPENDIX - 책 이외에 추가로 찾아본 것들
dns-prefetch의 현재 지원 범위
사용 가능한 브라우저의 글로벌 점유율은 증가한 상태
오페라 미니는 여전히 지원 불가 + 파이어폭스(HTTPS)에서 사용 불가 상태 (최근 중요도만 격상 됨..)
1596935 - Firefox doesn’t resolve <link rel=dns-prefetch> on HTTPS
그럼에도 불구하고 필요하다면 사용하는 것이 좋아 보임
MDN 문서 내용 중 The logic behind pairing these hints is because support for dns-prefetch is better than support for preconnect. Browsers that don’t support preconnect will still get some added benefit by falling back to dns-prefetch. Because this is an HTML feature, it is very fault-tolerant. If a non-supporting browser encounters a dns-prefetch hint—or any other resource hint—your site won’t break. You just won’t receive the benefits it provides.
Using dns-prefetch - Web performance - MDN
Cross origin 요청을 더욱 빠르게 하려면
Preconnect: DNS 확인 + TCP 연결 설정 + (HTTPS 사용 시) TLS 핸드셰이크
<link rel="preconnect" href="https://www.naver.com/" />
Using dns-prefetch Web performance - MDN
추가로 최적화를 하고 싶다면
(web.dev 링크) 리소스 힌트로 브라우저 지원하기
2.5 브라우저
📌 사용자가 원하는 이미지, 오디오, 영상 등의 웹 콘텐츠를 전달하는 소프트웨어
2.5.1 브라우저의 역사와 특징
- 초기의 브라우저는 IP 주소를 이용해 콘텐츠를 가져오는 단순한 기능 수행
- 이후 오디오, 비디오 등 멀티미디어 요소 지원을 위해 다양한 기능 추가
- 웹 성능에 있어서 콘텐츠를 제공하는 브라우저의 동작 속도는 중요함
2.5.2 네비게이션 타이밍 API
📌 웹 사이트의 성능을 측정하는데 사용할 수 있는 데이터를 제공
- 편리하게 종단(end-to-end)간 대기 시간(latency) 정보 제공
- window.performance 객체의 속성에서 확인 가능
※ 이전까지는 웹 페이지가 열리는 시간 등의 측정을 위해 자바스크립트 기능 사용
// 페이지 상단, 하단에 두어 페이지를 측정
var start = Date.now();
var end = Date.now();
// 콘솔 기능과 라벨을 통한 손쉬운 구분
console.time(label)
console.timeEnd(label)
2.5.3 네비게이션 타이밍 속성
[특수한 경우 발생하는 속성들]
속성 | 내용 |
---|---|
Prompt for unload | 이전 페이지에서 모든 작업이 끝나고 새로운 페이지를 로딩 준비 완료 |
unload | 전/후 페이지가 동일 origin 일 때 unload의 시작/종료 시점 |
(origin이 다르다면 값은 0임) | |
redirect | HTTP에서 페이지 재전송이 수행되는 시작/종료 시점 |
(redirect가 없었다면 값은 0임) |
[PerformanceTiming - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceTiming) |
※ unload - 페이지가 닫히거나 다른 페이지로 이동 시 필요한 청소 작업이 진행
[새로운 페이지 로드 시 발생하는 속성들]
속성 | 내용 |
---|---|
App cache | HTTP 요청을 통해 새로운 리소스 불러오는 시점 (캐시 확인) |
DNS | DNS 조회 시작/종료 시점 (캐싱 또는 TCP 세션이 남아 있는 경우 0) |
TCP | TCP 연결 시도 / HTTPS 연결 시도 / 연결 종료 시점 |
Request | 서버 또는 캐시 시스템에 요청을 보낸 시작 시간 |
Response | 서버 또는 캐시 시스템에 첫 번째 바이트와 마지막 바이트를 받은 시간 |
Processing | 웹 페이지 4단계 준비 상태 이벤트의 시작 시점 |
(start / interactive / DomContentLoaded 이벤트 호출 / complete) | |
onLoad | 웹 페이지의 load 이벤트의 시작/종료 시점 |
2.5.4 네비게이션 타이밍 속성값 구하기
navigation 객체
-
redirectCount 속성
(만일 있다면) 마지막 페이지에 도달할 때까지, 몇 번의 리다이렉션이 일어났는지
-
type 속성
상수 값 설명 TYPE_NAVIGATE 0 링크, 북마크, 폼 전송, URL 브라우저 타이핑 등의 방식으로 페이지 접속 TYPE_RELOAD 1 브라우저의 새로고침 버튼을 통해 페이지 접속 TYPE_BACK_ FORWARD 2 뒤로가기 버튼을 통해 페이지 접속 TTPE_RESERVED 255 그 외의 방법으로 페이지 접속 ※ URL 브라우저 타이핑 - 웹 브라우저 주소창에 URL 입력하는 경우
속성을 이용해 페이지 로딩에 걸린 시간 구하기
-
아래 코드를 콘솔에 붙여 넣으면 페이지 로딩 관련 지표 확인 가능
// 내비게이션 타이밍 API 개체 생성 var perfData = window.performance.timing; // navigationstart, loadEventEnd 속성을 사용하여 페이지 전체 로드 시간 구하기 var pageLoadTime = perfData.loadEventEnd - perfData.navigationStart; console.log("pageLoadTime: " + pageLoadTime + "ms."); // requeststart, responseEnd 속성을 사용하여 HTTP 요청에서 응답까지 걸린 시간 구하기 var connectTime = perfData.responseEnd - perfData.requestStart; console.log("connectTime: " + connectTime + "ms.");
-
pageLoadTime 값이 예상보다 크면
→ 웹 사이트 최적화를 진행하거나 콘텐츠 수나 크 기를 줄여 로딩을 빠르게
-
connectTime 값이 항상 크다면
→ 웹 서버를 좀 더 빠르 게 네트워크에 연결할 수 있는 방법을 찾아야
3.1 HTTP 요청 수 줄이기
📌 웹 페이지에서 일어나는 HTTP 요청 수를 줄여 로딩 속도를 개선한다
3.1.1 스크립트 파일 병합
📌 **분산 된 파일을 병합하여 로딩 시간을 줄인다**
- 모듈화
- 분업화 및 유지 보수를 위해 최소 기능 단위별로 모듈을 나누어 개발
- 파일 병합
- 그러나, 모듈화 방식은 HTTP 요청 수를 증가시켜 웹 성능에 부정적 영향
- 여러 개의 파일을 병합하여 성능을 향상 시킬 수 있음
- 단, 하나의 파일이 너무 크다면 로딩이 길어질 수 있어 적절한 크기 유지 필요
CSS 파일 로딩 속도 개선 사례 (0.6초 → 0.45초)
3.1.2 인라인 이미지
📌 ~~CSS 내 해시 정보를 통해 이미지를 삽입하는 방법~~
📌 작은 이미지나 파일을 페이지에 문자열 형태로 임베드 (w/ base64 인코딩) (can i use 의 정의)
- 장점
- 여러 이미지를 따로 호출하는 것보다 전체 로딩 시간이 단축 됨
- 단점
- 별도의 이미지 파일이 존재하지 않아 캐싱 불가 (페이지 전체가 캐싱되야 함)
Data URL (또는 Data URI scheme)이 정확한 용어로 보입니다
[data URL]
Can I use - https://caniuse.com/?search=data urls
MDN - https://developer.mozilla.org/en-US/search?q=inline+image
Wiki - https://ko.wikipedia.org/wiki/데이터_URI_스킴
[inline image 검색 결과]
Can I use - https://caniuse.com/?search=inline image
MDN - https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs
Wiki - https://ko.wikipedia.org/w/index.php?search=inline+image&title=특수%3A검색&ns0=1
base64 기반의 이미지 인코딩 / 디코딩을 체험할 수 있는 사이트
Base64에서 이미지 디코딩 (jpg, png, gif)
웹팩에서 url-loader
플러그인을 사용해 Data URL scheme 활용하는 방법
{
test: /\.(png|jpe?g)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
fallback: 'file-loader' // default
}
}
]
}
Image Loading Optimization - Camels and Snakes
3.1.3 CSS 스프라이트
📌 여러 개의 이미지를 하나로 결합 → 픽셀 좌표 정보를 이용해 사용
CSS 구문에서 픽셀 좌표 정보를 이용해 아이콘을 사용하는 예시
.sprite_face {
background: url(**'imgs/sprites_image.png'**);
**background-position: 0 -64px; // 시작 지점의 x, y 좌표**
**width: 50px; // x축 방향으로 얼마나 가져올지**
**height: 50px; // y축 방향으로 얼마나 가져올지**
float:left;
transition: all .2s ease-in-out;
}
.sprite_rss {
background: url(**'imgs/sprites_image.png'**);
**background-position: -57px -64px;**
**width: 50px;**
**height: 50px;**
margin-left:10px;
float:left;
transition: all .2s ease-in-out;
}
CSS 스프라이트를 실제로 적용하는 방법
[CSS Sprites Generator Tool | Toptal®](https://www.toptal.com/developers/css/sprite-generator/) |
참고링크
CSS : 스프라이트 이미지(sprite images) 이해와 적용
댓글 남기기