다양한 웹성능 최적화 기법 - DNS, 브라우저 타이밍 API, 이미지 최적화

Date:

카테고리:

태그:

2.4 DNS

📌 DNS란? ‘인터넷 호스트명을 클라이언트와 서버가 이해할 수 있는 IP주소로 변환해주는 시스템’
  • 일반 유저가 웹 사이트 접속을 위해 숫자로 이루어진 IP 주소를 기억하는 것은 어려움
  • 따라서, 웹 서비스는 보통 사용자가 기억하기 쉬운 호스트명을 주소로 사용
💡 DNS 질의의 응답 성능이 나쁘면 로딩 성능에 영향 → 확인 및 개선 필요

2.4.1 DNS의 작동 원리

스크린샷 2024-01-14 오후 8.20.45.png

단계 설명
로컬 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] 항목에서 확인 가능

aa

💡 특정 도메인 조회가 불가 / 지연  →  모듈 다운 후 자신의 웹 서버의 업로드하는 것도 고려

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의 현재 지원 범위

dns-prefetch: dns-prefetch

사용 가능한 브라우저의 글로벌 점유율은 증가한 상태

캔아이유즈 스크린샷 - 책에 있는 글로벌 점유율

캔아이유즈 스크린샷 - 내가 확인한 글로벌 점유율

오페라 미니는 여전히 지원 불가 + 파이어폭스(HTTPS)에서 사용 불가 상태 (최근 중요도만 격상 됨..)

캔아이유즈 스크린샷 - 오페라미니 미지원 캔아이유즈 스크린샷 - 파이어폭스 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 링크) 리소스 힌트로 브라우저 지원하기

리소스 힌트로 브라우저 지원 - 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)

네비게이션 타이밍 API 속성

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 - 페이지가 닫히거나 다른 페이지로 이동 시 필요한 청소 작업이 진행

HTML Standard

[새로운 페이지 로드 시 발생하는 속성들]

속성 내용
App cache HTTP 요청을 통해 새로운 리소스 불러오는 시점 (캐시 확인)
DNS DNS 조회 시작/종료 시점 (캐싱 또는 TCP 세션이 남아 있는 경우 0)
TCP TCP 연결 시도 / HTTPS 연결 시도 / 연결 종료 시점
Request 서버 또는 캐시 시스템에 요청을 보낸 시작 시간
Response 서버 또는 캐시 시스템에 첫 번째 바이트와 마지막 바이트를 받은 시간
Processing 웹 페이지 4단계 준비 상태 이벤트의 시작 시점
  (start / interactive / DomContentLoaded 이벤트 호출 / complete)
onLoad 웹 페이지의 load 이벤트의 시작/종료 시점

2.5.4 네비게이션 타이밍 속성값 구하기

네비게인션 개체 속성

  • 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초)

CSS 파일 로딩 속도 개선 사례 이미지

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/)

Untitled

Untitled

참고링크

CSS : 스프라이트 이미지(sprite images) 이해와 적용

[HTML/CSS] 이미지 스프라이트 기법 ✂️

React 카테고리 내 다른 글 보러가기

댓글 남기기