웹에 날개를 달아주는 웹 성능 최적화 기법 Chapter6

웹에 날개를 달아주는 웹 성능 최적화 기법

  • 본 책을 읽고 책의 내용을 간략하게 정리한 글입니다.

Chapter 6. 캐시 최적화

캐시

  • 캐시: 컨텐츠 요청에 빠르게 응답하기 위해 서버와 클라이언트 사이에서 응답 컨텐츠 사본을 저장하는 공간
  • 캐시는 보통 클라이언트와 서버 사이에 존재
  • 캐시 서버의 종류 및 이점
캐시 종류 위치 이점
브라우저 캐시 브라우저 한 번 다운로드한 리소스들을 재사용하여 사이트 로딩 속도 개선
프록시 캐시 브라우저와 ISP 조직 내 사용자들이 접속하는 웹 사이트의 리소스들을 캐시하여 네트워크 연결과 대역폭 사용률을 감소시키고 사용자의 웹 사이트 로딩을 빠르게 함
트랜스패어런트 캐시 ISP ISP는 캐시를 사용하여 ISP 간 대역폭이 낭비되는 것을 방지함
리버스 프록시 캐시 ISP와 웹 서버 원본 서버로 향하는 트래픽 대역폭을 감소시키고 사용자 응답 개선
  • 쉽게 사용할 수 있는 오픈 소스 웹 캐시 서버
    • Apache Traffic Server
    • Nginx
    • Varnish Cache

웹 캐시 동작원리

HTTP
  • 캐시 서버는 HTTP/1.1 규격을 기반으로 동작하므로 HTTP를 먼저 이해해야 함
  • TCP Connection 이 맺어지면 HTTP는 어떤 종류의 데이터든 전송할 수 있도록 설계
  • HTTP의 특징
    • 클라이언트 서버 모델로 동작
    • 비연결성이며 상태를 유지하지 않는 프로토콜 (Connectionless, Stateless)
    • 클라이언트와 서버 간 HTTP 메시지를 주고받으며 통신
    • HTTP 메시지는 헤더와 바디 부분으로 구분되어 전송
    • 하위 Transport Layer 프로토콜로 TCP를 사용하는데 일반적으로 80포트 (SSL은 443포트)를 사용
  • HTTP 메시지는 크게 헤더와 페이로드로 구분
    • 헤더에는 메시지를 전송할 호스트명, URL 패스 등 메시지 전송 및 처리에 필요한 데이터들이 포함
    • 페이로드에는 HTML, 이미지 등 서버가 실제 전송하고자 하는 데이터들이 포함
HTTP의 캐시 제어 방식
  • HTTP/1.1 부터 명시적으로 캐시를 제어할 수 있는 헤더를 추가함 = Cache-Control 헤더
  • HTTP/1.1에서는 캐시를 제어하는 목적을 크게 두 가지로 정의
    • 원본 서버로의 요청 수를 최소화함, 이는 네트워크 왕복 수를 줄여 결과적으로 사용자 요청에 대한 응답 속도를 단축
    • 완전한 컨텐츠를 응답하지 않아도 됨, 이는 네트워크 대역폭과 리소스 낭비를 줄이고 비용을 효율화함
Expires
  • HTTP/1.0은 Expires 헤더를 통해 원본 서버 컨텐츠의 유효 기간을 지정하도록 정의
    • Expires: Thu, 28 Sep 2017 05:16:39 GMT
  • Expires 헤더는 캐시를 명시적으로 제어하지는 않지만 브라우저를 포함한 대부분 캐시 서버에서 컨텐츠를 언제까지 저장할 것인가 판단하기 위해 사용
  • 캐시는 간단하게 Expires 날짜에서 Date 날짜를 빼는 것으로 해당 응답의 캐시 유지 시간 (Time To Live) 결정 가능
    • Time To Live (TTL) = Expires_value - Date_value
Cache-Control: max-age
  • HTTP/1.1에서는 Cache-Control: max-age 헤더로 컨텐츠의 유지 시간을 정의
  • 원본 서버는 해당 헤더를 사용해 캐시에서 특정 컨텐츠를 얼마나 오래 유지하고 있어야 하는지 명시적으로 설정
  • Expires 헤더는 만료 일자를 지정하는 반면 Cache-Control: max-age는 유효 기간 지정
    • Cache-Control: max-age=2592000
  • HTTP/1.0 기반의 캐시 서버나 브라우저가 Cache-Control: max-age를 지원하지 않기 때문에 원본 서버는 모든 응답에 두 헤더 값을 모두 표시해야 함
Cache-Control: s-maxage
  • CDN과 같은 공용 캐시 주기 관리
  • s-maxage를 이용하면 사용 중인 모든 CDN의 캐시 주기를 일괄적으로 설정하거나 변경 가능
  • s-maxage는 표준으로 도입된 지 얼마 되지 않아 CDN 업체가 이 헤더를 지원하는지 먼저 확인 필요
ETag
  • ETag (Entity Tag) 헤더는 원본 서버가 리소스를 식별하기 위해 부여하는 고유 번호
  • 캐시 서버에서 ETag를 통해 원본 서버의 리소스가 시간이 지나 만료되었는지, 캐시된 리소스를 새로 갱신해야 하는지 여부 판단 가능
  • ETag는 어떤 조합으로 작성할 지는 전적으로 ETag를 생성하는 원본 서버가 결정
  • ETag는 컨텐츠의 해시값이나 TimeStamp 해시값 또는 일련 번호 등 구현하기 편한 문자를 사용할 수 있지만 고유한 값이어야 함
    • ETag: "27dad37 1425fcc55e4d42a1478"
  • 크게 Strong ETag와 Weak ETag로 구분
    • Strong ETag는 모든 리소스에 대해 유일한 값을 가져야 하므로 Weak ETag에 비해 값을 생성하는 과정이 까다로움
    • Weak ETag를 사용하면 간단하게 값을 생성할 수 있지만 신뢰도가 약해짐
    • Weak ETag 값을 할당할 때는 ETag 값에 w/ 를 붙여 이 값이 유일하지 않을 수 있지만 괜찮다는 메시지를 캐시 서버에 전달해야 함
      • ETag: w/ "0317"
  • ETag는 캐시에 저장된 리소스의 캐시 주기가 끝났을 때 캐시 서버가 원본 서버와 캐시 유효성을 체크할 때도 중요하게 사용
Cache-Control: public
  • Cache-Control: public으로 설정하면 그 응답은 모든 캐시 서버에 캐시될 수 있고 사용자 제한 없이 모든 사용자에게 응답이 전달됨
Cache-Control: private
  • private로 설정하면 HTTP 요청에 대한 응답은 요청한 사용자만 캐시할 수 있고 CDN 같은 범용 캐시 서버에서는 캐시할 수 없음
    • 엄밀히 말하면 범용 캐시 서버에도 캐시할 수 있지만 그 응답을 모든 사용자에게 공유할 수 없음
  • Cache-Control: private를 설정한다고 해서 응답에 담긴 개인 정보까지 보호되지는 않으니 주의할 것
Cache-Control: no-cache
  • no-cache 지시자가 요청 헤더에 있으면 브라우저는 원본 서버나 그 중간에 존재하는 캐시 서버들에게 캐시된 응답을 받지 않겠다는 메시지를 전달하는 것
  • max-age=0을 사용하는 것과 비슷하게 동작하지만 미묘한 차이 존재
    • no-cache를 설정하면 캐시 서버는 항상 원본 서버로부터 최신 응답을 받아와야 함
    • max-age=0은 캐시 서버가 원본 서버에서 전체 응답을 가져오기보다 조건부 요청을 이용해 캐시된 컨텐츠에 변경이 있는지를 검증
  • no-cache 지시자가 HTTP 응답 헤더에 포함되면 원본 서버가 캐시 서버들에게 캐시된 응답을 보내기 전 원본 서버를 항상 확인하도록 강제
  • 만약 원본 서버가 전체 응답이 아닌 특정 헤더 항목만 캐시하고 싶지 않다면 지시자 옆에 캐시하고 싶지 않은 헤더들을 나열하면 됨
    • ex) no-cache="Accept-Range": 캐시 서버는 응답을 캐시하되, Accept-Range 헤더는 캐시하지 않음
Cache-Control: no-store
  • 서버가 로컬 저장소에 메시지를 저장하지 않도록 지시
  • no-cache는 응답을 항상 최신 상태로 유지하도록 지시하지만 로컬 저장소에 저장하는 것을 막지 않음
  • 반면 no-store는 응답 메시지가 저장소에 저장되는 것 자체를 금지
  • no-store의 목적은 캐시 데이터의 예기치 않은 유출 방지
캐시 유효성 체크
  • 비효율적인 요청/응답을 방지하고자 HTTP 표준은 조건부 요청 (conditional request)라는 메커니즘 정의
  • 저장된 응답 TTL이 만료되었을 경우 캐시가 항상 원본 서버에서 완전한 컨텐츠를 받아오는 대신 TTL 주기 동안 컨텐츠에 변화가 있을 때만 새 응답을 만들도록 요청
    • 해당 컨텐츠에 변경이 있을 때 200 응답 코드와 함께 변경된 컨텐츠를 응답 본문에 포함해 보내짐
    • 변경이 없다면 응답 본문 없이 304 (Not-modified) 코드만 헤더에 설정하여 보내는데, 응답에 본문이 없으므로 네트워크 자원 낭비 방지
  • 조건부 요청을 보낼 때는 시간을 기반으로 보내는 방법과 컨텐츠 기반으로 보내는 두 가지 방법 사용
  • 시간 기반의 조건부 요청
    • 어떤 요청에 대한 원본 서버의 컨텐츠가 캐시에 저장된 후 변경되었는지 여부를 컨텐츠의 최종 변경 시간 중심으로 확인하는 방법
  • 컨텐츠 기반의 조건부 요청
    • 어떤 요청에 대한 요청에 대한 원본 서버의 컨텐츠가 캐시에 저장된 후 변경되었는지 여부를 컨텐츠 고유값 중심으로 확인하는 방법
    • 원본 서버는 미리 정의된 대로 ETag 헤더에 해당 고유값을 넣어 보냄
    • Cache-Control: public, max-age=31536000
      ETag: "15f0fff99ed5aae4edffdd6d7131f"
      
    • 캐시는 최초 요청에 대한 응답을 캐시에 저장하고 TTL 시간이 지난 후 같은 요청이 오면 원본 서버에 ‘만약 이 컨텐츠와 일치하는 고유값이 없다면 전체 응답을 주세요.’ 같은 의미의 요청을 함
    • If-none-match 헤더에 ETag 값을 복사해 원본 서버에 전송함으로써 이런 요청을 수행
    • If-none-match: "15f0fff99ed5aae4edffdd6d7131f"
      
캐시 컨텐츠 갱신
  • 웹 사이트가 개편되거나 컨텐츠를 급하게 변경한 경우 캐시에 저장된 복사본들을 강제로 갱신해야 사용자에게 정상적인 웹 페이지 제공 가능
  • 캐시 갱신 방법 1. 퍼지
    • 저장소를 완전히 지우는 방식으로 대부분의 캐시 서버가 캐시를 모두 지우는 명령어나 API 제공
    • 브라우저의 옵션 메뉴에서 로컬 캐시 삭제 가능
  • 캐시 갱신 방법 2. 무효화
    • 조건부 요청을 통해 캐시된 리소스들 중 변경이 있던 리소스만 새로 갱신하는 방법
    • Cache-Control 헤더를 통해 캐시 서버의 내용을 강제로 무효화 가능
    • Cache-Control: max-age=0, must-revalidate
      
    • 실제 변경된 리소스에 한해서만 전체 컨텐츠가 반환되므로 네트워크 대역폭 낭비를 크게 줄임

캐시 최적화 방안

캐시 가능한 컨텐츠 구분하기
  • 운영 또는 개발하는 웹 페이지가 어떻게 구성되었고 얼마나 많은 파일들을 캐시할 수 있는지 WebPageTest를 통해 확인 가능
  • 웹 사이트 구성 컨텐츠는 크게 정적 컨텐츠와 동적 컨텐츠로 분류할 수 있음
  • 정적 컨텐츠
    • URL을 호출할 때마다 변함없이 같은 응답을 주는 컨텐츠로 이미지, CSS, 자바스크립트 등이 대표적
  • 동적 컨텐츠
    • 사용자가 요청할 때마다 서버에 의해 다시 생성, 응답되는 컨텐츠로 서버에서 HTTP 요청과 함께 입력 시간을 포함한 다양한 변수값에 따라 컨텐츠를 동적으로 생성하여 응답함
    • Ajax를 사용한 XHR 요청, 사용자가 로그인했을 때 만들어지는 개인화된 웹 페이지
  • 캐시하기 어려운 컨텐츠는 다음과 같이 분류 가능
    • 개인화된 컨텐츠
      • 접속하는 사용자의 정보에 따라 달라지는 컨텐츠로 원본 서버에서 가공되는 컨텐츠를 의미
    • API 호출이나 Ajax 요청에 대한 컨텐츠
      • 인증이나 결제 등 서버의 작업이 필요하거나 시간에 따라 빠르게 변하는 정보를 받을 때 사용되므로 캐시에 적합하지 않음
    • Beacon 전달 또는 쿠키 설정을 위한 호출
      • 사용자 정보를 수집하거나 브라우저에 쿠키를 설정하기 위해 아주 작은 이미지를 호출하는 경우
      • 이러한 요청에 대한 응답이 캐시에 저장되면 원본 서버에 정보를 보내거나 받을 수 없으므로 캐시하면 안 됨
올바른 캐시 정책 세우기
  1. 먼저 캐시할 수 있는 컨텐츠인지 판단
  2. 캐시할 수 있는 컨텐츠들은 매번 원본 서버에 변경 사항을 확인해야 하는지 판단
    • 변경에 민감한 리소스는 응답 헤더에 Cache-Control: no-cache 나 Cache-Control: max-age=0 설정
    • 응답할 리소스가 변경되지 않았다면 전체 리소스가 아닌 304 코드만 응답하면 되므로 네트워크 대역폭 낭비 방지
  3. 캐시할 컨텐츠들의 성격 판단
    • 모든 사용자에게 공통으로 사용될 수 있다면 Cache-Control: public
    • 개인화된 컨텐츠라면 Cache-Control: private
    • Cache-Control: private 로 설정하면 일반적인 웹 캐시 서버에서 캐시할 수 없고 오직 개인 브라우저에서만 캐시함
  4. 캐시 주기를 설정하고 max-age 추가
캐시 주기 결정하기
  1. 캐시 주기는 컨텐츠 타입별로 다르게 설정 가능
    • 특별한 이유가 없다면 캐시 주기를 1년 정도로 길게 설정하는 것 권장
  2. 만약 링크 변경 없이 이미지 내용만 바꿔야 한다면 캐시 무효화 방식으로 해당 이미지만 캐시에 업데이트
    • 이미지나 미디어 파일을 제외한 CSS, 자바스크립트, 폰트 등의 웹 리소스 파일들은 변경이 얼마나 자주 일어나는지에 따라 다르게 설정하되, 그 범위에서 가능한 길게 설정
  3. 모든 정적 파일에 대해 캐시 주기를 길게 설정하고 수동으로 캐시 주기를 관리하는 방법
    • 파일 요청 시 쿼리 스트링으로 버전을 지정하는 방법
    • core.min.js?201707311505
      index.js?v=201709041404
      lazy_loading.js?version=1.0
      
    • 필요할 때마다 쿼리 스트링의 버전을 바꿔주면 됨
  • 고객 반응에 민감할 경우 충분히 캐시할 수 있는 정적 컨텐츠도 캐시하지 않으려 하는 경우가 있음
  • 이런 경우 Cache-Control: no-store 설정보다 Cache-Control: no-cache, max-age=0 을 사용하는 것 권장
    • 전자는 모든 요청에 대해 원본 서버에 항상 전체 컨텐츠를 받는 방법
    • 후자는 변경이 있을 경우만 바로 캐시에 업데이트하는 방법 = 네트워크 대역폭 낭비 방지
캐시에 적합한 디렉토리 구조 구성하기
  1. 캐시할 수 있는 컨텐츠들을 별도 폴더에 분류해 관리
    • ex) 정적 컨텐츠들을 /static 폴더 아래에 배치
  2. 캐시 주기별로 나누어 구성
    • 같은 자바스크립트라도 라이브러리와 특정 모듈에 사용되는 자바스크립트의 캐시 주기는 다름
    • 모듈에 사용하는 자바스크립트는 자주 변경, 라이브러리에 사용되는 자바스크립튼느 쉽게 변경되지 않음
    • /static/js/lib
      /static/js/module/A
      /static/js/module/B
      
  3. 동일한 파일을 여러 곳에 분산시키지 않기
    • 캐시 서버 역시 제한된 메모리와 디스크 영역으로 동작하므로 필요 없는 객체들로 리소스를 낭비하지 말아야 함
캐시 키 올바르게 사용하기
  • 캐시 키: 캐시 서버가 원본의 복사본을 저장하고 빠르게 조회하기 위해 사용하는 키 값
  • 일반적인 캐시 키 구성
    • 호스트/패스?쿼리 스트링
      www.foekorea.com/kr/feo/optimization/myPic.jpg?width=200&height:100
      
    • 아래 캐시 키들은 서로 다른 객체를 참조함
      www.foekorea.com/kr/feo/optimization/myPic.jpg
      www.foekorea.com/jp/feo/optimization/myPic.jpg
      www.foekorea.com/kr/feo/optimization/myPic.jpg?width=200
      www.foekorea.com/kr/feo/optimization/myPic.jpg?width=200&height=100
      www.foekorea.com/kr/feo/optimization/myPic.jpg?width=200&height=200
      
  • 캐시 오염과 캐시 충돌
    • 캐시 오염: 원본 서버에 하나의 원본 파일만 존재하는데 캐시에 복사본이 여러 개 존재하는 것
    • 캐시 충돌: 요청 URL이 하나인데 브라우저 환경에 따라 서버에서 제공하는 응답이 달라지는 것
  • 캐시 오염 제거
    1. URL에 붙은 특정 쿼리 스트링 값이 달라지더라도 응답이 항상 같다면 캐시 키에서 쿼리 스트링을 무시하도록 설정
    2. 쿼리 스트링의 순서를 동일하게 정렬
      • 쿼리 스트링 순서가 달라져도 캐시는 다르게 인식함
    3. Vary 헤더를 바르게 사용하기
      • Vary 헤더가 잘못 사용되었을 때 캐시는 같은 페이지의 복사본을 여러 가지 캐시 키로 다르게 저장하기도 함
      • 꼭 필요한 경우가 아니라면 Vary 헤더를 사용하지 않거나 Cache-Control: private 설정할 것을 추천
  • 캐시 충돌 방지
    • 주로 동적 페이지를 캐시할 때 발생
    • 일부 동적 페이지에 캐시를 사용하고자 한다면 Cache-Control: private로 사용자 브라우저에만 캐시하여 페이지 로딩 시간을 단축할 수 있음
CDN 사용하기
  • CDN 서비스를 사용하면 세계 여러 지역 데이터 센터들에 리버스 프록시 캐시 서버를 두고 필요한 정적 컨텐츠들을 저장해놓을 수 있음
  • 사용자와 가장 가까운 캐시 서버에서 해당 컨텐츠가 서비스되므로 시간 지연 없이 빠르게 웹 페이지를 로딩할 수 있음

동적 컨텐츠 개시

  1. 정적 컨텐츠와 동적 컨텐츠
    • 정적 컨텐츠는 한번 생성되어 좀처럼 변하지 않는 컨텐츠
    • 동적 컨텐츠는 사용자 요청에 따라 서버가 바로 생성하는 컨텐츠
  2. 익명 컨텐츠와 개인화 컨텐츠
    • 동적 컨텐츠를 좀 더 분류하면 익명 컨텐츠와 개인화 컨텐츠로 나눌 수 있음
    • 익명 컨텐츠는 누구에게나 드러나는 컨텐츠
    • 개인화 컨텐츠는 요청한 사용자 정보에 따라 다르게 나타나는 컨텐츠
  3. 시간에 민감한 컨텐츠와 둔감한 컨텐츠
    • 시간에 민감한지 여부는 컨텐츠를 필요로 하는 사람이나 제공자의 비즈니스 목적에 따라 다를 수 있음
    • 통상 주식 시세, 환율 정보, 경기 중계 등은 시간에 민감한 컨텐츠
    • 일기 예보, 비행기나 선박 스케줄 정보 등은 시간에 둔감한 컨텐츠
  • 동적 컨텐츠를 사용자에게 전달하기 위해 원본 서버에서는 두 가지 방법 이용
    1. 동적 정보를 쿠키에 넣어 보냄
    2. Ajax 요청으로 관련 정보를 동적으로 받아옴
  • 요청 쿠키, 헤더 또는 쿼리 스트링에 동적 컨텐츠에 대한 정보가 있으면 이 정보들을 캐시 키에 추가함으로써 동적 컨텐츠를 캐시할 수 있음
    1. 보안에 주의해야 함
    2. 캐시 서버 용량에 유의해야 함
  • Ajax 요청에 대한 응답 형태인 JSON/XML 타입 컨텐츠는 다른 정적 응답 타입과 동일한 방식으로 캐시 가능, 단지 시간에 민감한지 여부가 관건
  • 캐시하고자 하는 컨텐츠의 시간에 따른 민감도를 미리 결정하고, 이에 맞게 캐시 주기를 설정
    • TTL 1-3mins : sport results, currency feed, ...
      TTL 0s : real time data polling (e.g. trading feed ...)
      
  • 캐시는 통상 HTTP GET 방식에서 동작하므로 Ajax 요청에 대한 응답을 캐시하고자 하면 HTTP POST 방식보다 GET 방식을 사용해야 함
  • 캐시 주기로 0 TTL을 사용하려면 서버에서 해당 컨텐츠에 대한 If-Modified-Since (IMS) 요청을 지원해야 함
    • IMS 요청을 지원하지 않으면 캐시 서버는 모든 요청을 서버로 보내고 서버는 매 요청마다 새로운 컨텐츠로 응답하므로 캐시하지 않은 것고 동일
POST 응답 캐시
  • POST 메서드를 사용하면 HTTP 페이로드에 쿼리 스트링 내용을 포함해 보내므로 데이터 크기에 제한 없음
  • 일반적으로 POST 메서드에 의한 응답은 POST 요청 본문에 포함된 매개 변수들에 의해 결정
  • POST 응답 내용이 보안 측면에서 공개되어도 안전한 내용이라면 이 POST 요청/응답 역시 캐시 가능
    • 캐시 키에 요청 매개 변수값들이 모두 포함되어야 캐시 오염, 캐시 충돌 같은 오류 현상 방지 가능
    • 캐시 키에 매개 변수값들이 노출되지 않아야 하므로 MD5 같은 해시 알고리즘을 이용해 타인이 쉽게 알 수 없도록 값을 암호화해야 함
  • POST 요청/응답을 캐시하기 위해선 다음 조건들을 만족해야 함
    • 매개 변수값에 항상 같은 응답이 오는 경우
    • 개인 정보가 포함되지 않은 경우
    • 요청 사이즈가 크지 않은 경우

고급 캐시 전략

Edge Side Include
  • 첫 번째 HTML이 서버에서 브라우저까지 도달하는 시간을 Time To First Byte 라고 하며 웹 사이트 성능을 측정하는 매우 중요한 지표
  • 많은 관리자들이 첫 HTML을 캐시하지 않는데, 이 HTML을 구성하는 컨텐츠 중 서버에서 동적으로 만들어내는 부분들이 존재하기 때문
  • 이런 동적으로 만들어내는 부분만 따로 떼어 별도로 수행시킨 후 캐시된 나머지 부분과 다시 조합할 수 있다면 로딩 성능 개선 가능
  • ESI (Edge Side Include): 인터넷 Edge에서 웹 페이지 조각을 동적으로 조합, 조립, 전달할 수 있도록 이에 대한 문법과 용도 등을 정의한 XML 기반 표준 마크업 언어
  • ESI를 사용하면 한 페이지 안에 다른 페이지를 포함시킬 수 있을 뿐만 아니라 각 페이지들이 독립 객체로 취급되어 각각 다른 캐시 정책을 사용할 수 있음
  • 캐시 서버는 HTML을 캐시 또는 서버에서 먼저 가져온 뒤 ESI 작성 부분을 수정하여 완벽한 HTML을 만들어 클라이언트에게 전달
HTML5 로컬 스토리지
표준안 연도 설명 관련기관
HTML 2.0 1995 IETF의 HTML Working Group이 개발함
1994년 실제 사례를 기반으로 HTML 핵심 기능들을 표준으로 개발
IETF
HTML 3.2 1997 1996 동안 사용된 HTML 주요 특징들에 대한 상호 합의를 기반으로 W3C에서 처음 권고
HTML 3.2는 현재도 널리 쓰이는 테이블, 애플릿 이미지 주변의 텍스트 플로우 등의 기능들을 추가
W3C
HTML 4.01 1999 추가적인 멀티미디어 옵션들, 스크립팅 언어, 스타일 시트 등 사용자 접근성을 높이는 기능들을 추가 W3C
XHTML 1.0 2000 HTML4.01과 XML의 강점을 통합하여 새로운 표준 제시 W3C
HTML5 2014 HTML4.01과 XHTML1.0을 대체할 새로운 표준으로 등장 W3C, WHATWG
  • HTML5의 주요 기능
    • WeSemantic Tag
      • 본래 많은 양의 DIV를 통해 부여했던 Semantic을 표준 Tag로 정의해 사용하게 됨
      • 머신 간 가독성 및 사용자 접근성을 향상시킴
    • Web Storage
      • API를 통해 세션 스토리지, 로컬 스토리지 IndexedDB를 사용할 수 있고 오프라인인 상태에서 웹 페이지 로딩 가능
    • Multimedia
      • 플러그인 없이 오디오와 비디오 재생 가능
    • Graphics
      • 그래픽을 위한 툴박스가 SVG, Canvas, WebGL, CSS3 3D 등으로 확대되어 플러그인 없이 그래픽 표현
    • Device Access
      • 기기의 마이크로폰, 카메라, 연착처, 이벤트 등에 네이티브 앱처럼 접근 가능
    • Performance
      • Web Worker를 도입해 백그라운드 프로세싱 기능과 멀티스레드를 사용해 속도 향상
    • Connectivity
      • Web Socket을 사용해 클라이언트와 서버 간 TCP 통신 가능
      • 실시간 메시징, 푸시 알림 등 양방향 통신 구현 가능
    • CSS3
      • CSS3를 지원하여 유연하고, 풍성한 화면을 더욱 쉽게 구현 가능
  • 웹 성능과 관련해선 웹 스토리지 API 기능을 살펴볼 필요 있음
    • 사용자의 주요 정보들이나 웹 리소스를 브라우저 로컬 저장소에 저장하여 재사용할 수 있음
  • 스토리지는 세션이 살아있는 동안만 저장되는 세션 스토리지와 영원히 저장되는 로컬 스토리지가 존재
  • 렌더링에 있어 중요한 CSS, 자바스크립트를 로컬 스토리지에 저장해놓으면 나중에 재방문할 때 로딩 속도 대폭 개선 가능
  • 폰트 파일 역시 로컬 스토리지에 저장하면 폰트로 인한 사이트 로딩 지연 방지 가능

웹에 날개를 달아주는 웹 성능 최적화 기법, 강상진, 윤호성 저, 루비페이퍼 출판