[HTML5] 오프라인 웹 어플리케이션

Posted in 모바일/HTML5 // Posted at 2010.08.12 16:22

인터넷 연결 없이 웹 사이트를 사용한다?
인터넷에 연결이 되어 있지 않은 상황에서 웹 사이트를 이용하는 것을 상상해 본 적이 있는가?
웹 사이트는 인터넷 연결을 기반으로 하는 WWW 서비스이다
따라서 네트워크 저 넘어에 있는 웹 사이트에 접속하기 위해서는 인터넷 연결이 필수이다

그러나 HTML 5 는 이러한 웹의 룰(rule)을 깨(?) 버렸다

HTML 5 에서는 인터넷 연결 없이 웹 사이트 이용이 가능한 스펙들을 포함하고 있다
오프라인 웹 실현의 중심이 되는 스펙이 바로 어플리케이션 캐시(Application Cache) 이다

구글의 캘린더 서비스를 사용해 본 적이 있는가?
오프라인 웹 어플리케이션의 전형적인 예이기도 한 구글 캘린더는,
일정 관리를 제공해 주는 서비스인데 인터넷 연결 없는 오프라인 환경에서도 사용이 가능하다
(물론 읽기 전용으로만 사용이 가능하다)

 
 
   
구글 Gears 를 이용하여 오프라인 환경을 지원하는데, 인터넷이 연결되지 않은 상태에서도
캘린더 페이지를 실행할 수 있고 일정 목록을 조회할 수 있다 (오프라인 캘린더는 읽기 전용이다)
구글 캘린더 뿐만 아니라 구글 독스(Docs), Gmail 등이 오프라인 환경을 지원한다

웹 사이트가 혹은 웹 사이트의 어떠한 기능이,
오프라인에서 동작 가능하다는 것은 웹을 기반으로 하는 서비스 분야에 많은 장점을 가져다 준다

인터넷이 연결되어 있지 않아도 서비스를 이용할 수 있다는 확장성과 서버와의 통신을 줄여
네트워크 트래픽을 감소한다는 성능적 장점도 취할 수 있다

특히 이동성이 부각되는 모바일 환경에서는 더욱 매력적인 환경일 것이다
모바일 환경은 언제 네트워크가 끊길지 모르는 특징이 있으며 경량의 트래픽은 매우 중요한 이슈이다


어플리케이션 캐시(Application Cache) 개요
HTML 5 의 어플리케이션 캐시는 html, css, js 파일 및 이미지 파일, 폰트 파일 등
웹 페이지를 구성하는 각종 웹 리소스들을 클라이언트 단 다운로드 해서 캐싱해 둠으로써
인터넷 접속 없이 해당 리소스들을 이용할 수 있도록 하는 기술이다

매니페스트라는 일종의 구성파일에 캐시 될 웹 리소스를 (개발자가) 정의할 수 있으며
이 구성파일을 메인 페이지(혹은 서비스 되는 어떤 페이지)에 명시하는 것 만으로 
어플리케이션 캐시가 자동으로 동작한다. 매우 심플하다

매니페스트 파일에는 캐시될 리소스 이외에도 반드시 네트워크를 통해서만 접근 가능한
리소스를 별도로 지정할 수 있으며 존재 하지 않는 리소스 요청에 대한 대체 리소스 지정도 가능하다

또한 어플리케이션 캐시와 관련된 여러 유용한 자바스크립트 API를 제공해 주는데,
캐싱 상태 조회, 캐시 갱신, 각종 캐시 관련 이벤트 등이 있다

이러한 API를 이용하면 어플리케이션 캐시 동작을 보다 세세하게 제어할 수 있게 된다


임시 인터넷파일과 어플리케이션 캐시
HTML 5 이전 환경에서도 웹 브라우저에서 임시 인터넷파일이라는 장치를 두어
클라이언트에 웹 리소스를 다운로드 해 두고 인터넷이 아닌 하드디스크로부터
리소스를 액세스 하는 매커니즘이 제공된다.
이렇게 함으로써 동일한 웹 리소스 요청은 웹이 아닌 로컬 파일을 액세스 하게 되어
성능을 향상시킨다

아래 그림은 IE 의 임시 인터넷파일에 대한 설정 화면이다


뭔가... 어플리케이션 캐시와 유사한 느낌이지 않는가?
어플리케이션 캐시 역시 웹 리소스를 클라이언트에 다운로드 해서 웹이 아닌 로컬 자원을
사용하는 것이니 말이다

그러나 여기에는 핵심적인 차이가 있다
바로 '오프라인 사용이 가능한가?' 라는 것이다

임시 인터넷파일과 어플리케이션 캐시의 차이점을 살펴 보자

- 오프라인 사용이 가능한가?
어플리케이션 캐시의 가장 핵심적인 컨셉은 오프라인 어플리케이션이 가능하다는 것이다

기존 임시 인터넷파일이 비록, 웹 리소스를 클라이언트에 다운받아 두고 
이를 사용한다고 해도 오프라인 상황에서는 무용지물이라는 점이다

다시말해, 임시 인터넷파일도 html, css, js, 이미지 파일 등이 클라이언트에 캐시되지만
버전의 변경 체크를 위해 온라인을 통해 각 파일의 변경 여부를 매번 확인한다는 것이다
브라우저는 웹에 있는 리소스와 로컬에 있는 리소스를 비교하여 변경이 없으면 캐시된 리소스를
이용하고 변경되었으면 웹에서 다시 다운로드 받도록 한다

반면 어플리케이션 캐시는 최초 한번만 다운로드 되면 이후로는 각 파일의 변경 체크를 위해
온라인을 확인하지 않는다

결과적으로 어플리케이션 캐시는 인터넷 연결이 완전히 끊긴 상황에서도 잘 동작하지만
임시 인터넷파일은 온라인일 때에만 정상 동작하게 되는 것이다

- 모든 파일을 확인 하는가?
임시 인터넷파일이 경우 캐시된 모든 리소스에 대한 변경 사항을 체크 하지만
어플리케이션 캐시는 매니페스트 파일의 변경만 체크한다
따라서 캐시된 모든 파일을 확인하는 것보다 효과적이라 할 수 있다

- 캐시 항목의 설정이 자유로운가?
임시 인터넷파일이 경우 웹 브라우저가 알아서 리소스들을 캐시한다
이는 웹 사이트 설계자나 개발자가 개입할 여지가 별로 없다는 것이다
반면 어플리케이션 캐시는 캐시될 항목과 그렇지 않은 항목을 자유자재로 지정할 수 있다

- 기타 캐시 관련 세세한 조작이 가능한가?
앞서 살펴본대로, 어플리케이션 캐시를 위한 다양한 자바스크립트 API가 존재한다
이는 캐시와 업데이트, 캐시 발생 간 이벤트 제어 등이 가능하여 보다 세밀한 제어를 할 수 있다


몇 가지 차이점을 알아봤지만 궁긍적인 차이점은
오프라인 웹 어플리케이션이 가능한가 여부에서 판가름 난다고 할 수 있다


브라우저 지원 현황
어플리케이션 캐시를 지원하는 브라우저 현황을 살펴보자
아래 표는 http://caniuse.com/ 에서 제공하는 브라우저(버전)별 어플리케이션 캐시 지원 표이다




대부분의 브라우저에서 어플리케이션 캐시를 지원하고 있다

그리고 표 하단의 Note 에서도 나와 있듯이,
아이폰의 사파리에서 테스트를 해 보니 정상적으로 동작하는 것을 확인하였다

다음의 코드로 브라우저 지원 여부를 체크해 볼 수 있다

if( !!window.applicationCache ) {
    alert("현재 브라우저는 어플리케이션 캐시를 지원합니다")
}
else{
    alert("현재 브라우저는 어플리케이션 캐시를 지원하지 않습니다")
}



캐시 매니페스트(Cache Manifest) 파일
어플리케이션 캐시의 동작에 핵심이 되는 파일이다
이 파일의 특성과 작성 방식을 아는 것이 곧 어플리케이션 캐시를 아는 것과 다름이 없다

캐시 매니페스트는 실제로 캐시될 웹 리소스에 대한 정의를 포함하는 일종의 설정파일이다
브라우저는 이 파일에 명시된 리소스를 기반으로 로컬 캐시 항목을 결정한다

또한 캐시된 리소스가 서버에서 업데이트 되었다면 이를 다시 새 버전으로 캐시해야 하는데
이 역시 캐시 매니페스트 파일의 업데이트 여부가 기준이 된다

 그럼 가장 간단한 형태의 매니페스트 파일 예를 보자

CACHE MANIFEST
# Version 1.0.0.0
ac.html
ac.js
ac.css

매니페스트 파일의 확장자는 .manifest 로 하고, 첫줄은 CACHE MANIFEST 라고 정의해야 한다
그리고 그 아래로 캐시될 웹 리소스들을 정의한다(각 항목은 줄바꿈으로 구분됨)
(#... 은 파일의 주석이다)

그리고 메인페이지(혹은 어떤 페이지)에서 매니페스트 파일을 지정해 주면 된다
이후 이 페이지가 호출 되면 캐시는 동작하게된다

<!DOCTYPE html>
<html manifest="cache.manifest">
 ....


캐시 매니페스트파일과 MIME 타입
클라이언트의 웹 브라우저는 매니페스트 파일을 기준으로 캐시 여부를 판단한다
따라서 매니페스트 파일은 클라이언트가 접근할 수 있어야 하며 파일의 MIMIE 타입을 
알맞게 설정해 줘야 한다

마이크로 소프트의 웹 서버인 IIS 의 경우 인터넷서비스 관리자 화면에서 MIME 타입 설정이 가능하다
.manifest 확장자에 대한 MIME 타입을 text/cache-manifest 로 설정한다


캐시 매니페스트 파일의 3가시 섹션
캐시 매니페스트 파일에는 캐시될 리소스 지정 이외에도
대체 리소스 및 반드시 온라인 액세스를 해야 하는 리소스의 지정도 가능하다

CACHE 섹션
가장 핵심이 되는 섹션이다. 클라이언트에 캐시되어야 할 항목을 지정한다
Cache 섹션으로 지정된 웹 리소스는 오프라인에서도 접근이 가능하게 된다
섹션의 기본값이다. 즉 섹션을 직접 명시하지 않으면 기본적으로 CACHE 섹션이 된다

그리고 CACHE 섹션에 명시하지 않아도 자동으로 캐시되는 파일이 있는데,
바로 manifest  속성을 지정한 html 파일이다

NETWORK 섹션
CACHE 섹션과 반대 되는 개념이다. 반드시 온라인 상태에서만 접근 가능한 항목을 지정한다
업데이트가 매우 잦거나 동적으로 변화하는 웹 리소스를 지정할 때 유용하다

FALLBACK 섹션
대체 리소스를 지정하는 섹션이다
요청한 URL에 해당하는 리소스가 존재하지 않을 때 이를 대신해서 표시할 리소스를 지정한다
다른 요소와는 달리 (공백 혹은 탭을 기준으로) 좌/우 쌍으로 지정한다

예) 다음은 home 폴더에 요청한 리소스가 없을 경우 fallback.html 이 대체리소스로 사용되는 예이다

FALLBACK:
./home   fallback.html

섹션의 기본 값은 CACHE 섹션이며, '섹션이름 :(콜론)' 으로 시작한다


데모 만들어 보기
이제 간단한 어플리캐이션 캐시 데모를 제작해 보자. 파일 구성은 다음과 같다

cache.manifest : 매니페스트 파일
ac.html            : HTML 파일 (manifest 속성이 지정된 페이지)
ac.js                : 자바스크립트 파일 (어플리케이션 캐시 지원 유/무를 체크하는 로직 포함)
ac.css             : 스타일시트 파일 (문자열을 박스로 감싸는 간단한 스타일 지정)
mkex.jpg          : 샘플이미지
mkex2.jpg         : 샘플이미지2 (NETWORK 섹션 지정)

위 파일 중 mkex2.jpg 는 NETWORK 섹션으로 지정하여 반드시 온라인 상태에서만 액세스 가능하도록
설정하고 나머지 파일들은 CACHE 섹션으로 지정하여 오프라인 액세스가 가능하도록 지정한다
chace.manifest 파일과 html 파일을 아래와 같이 정의한다

- cache.manifest 파일
CACHE MANIFEST
# Version 1.0.0.0

CACHE:
ac.html
ac.js
ac.css
mkex.jpg

NETWORK:
mkex2.jpg

- ac.html 파일
<!DOCTYPE html>
<html manifest="cache.manifest">
  <head>
    <link rel="stylesheet" type="text/css" href="ac.css">
    <script type="text/JavaScript" src="ac.js"></script>
    <script type="text/JavaScript">
      var isSupportCache = supports_offline();
      if(supports_offline) {
          alert("현재 브라우저는 어플리케이션 캐시를 지원합니다")
      }
      else{
          alert("현재 브라우저는 어플리케이션 캐시를 지원하지 않습니다")
      }
    </script>
  </head>
  <body>
    <div class='etcBox'> Hello, Application Cache !  </div>    
    <img src="mkex.jpg"><br>
    <img src="mkex2.jpg"><br>
  </body>
</html>


예제 실행(온라인 상태에서 첫 실행)
이제 온라인 상태에서 데모 페이지를 실행해 보자
파이어폭스 브라우저에서 데모를 처음 실행하면 다음과 같이 오프라인을 허가할지 여부를 묻게 된다



메니페시트 파일에 지정된 URL은 같은 도메인으로 제한된다

따라서 데모를 처음 실행하면 해당 도메인에 대한 오프라인 액세스 허용 유/무를 묻는 것이다

'허가'를 선택하면 브라우저는
매니페스트 파일을 다운로드 하여 그 안에 명시된 각 CACHE 섹션 항목들에 대해 로컬 캐싱을 해 둔다
이후 CACHE 섹션의 항목들은 로컬에 캐싱된 것을 이용하게 된다


오프라인 상태에서 다시 실행
해당 페이지를 다시 실행해 보는데, 이번에는 오프라인 상태에서 실행 해 보자
네트워크가 차단된 상태에서 해당 페이지를 호출해도 문제없이 실행되는 것을 알 수 있다
(해당 페이지는 물론 스타일 시트, 스크립트 로직이 모두 정상 동작한다)

즉 온라인이 아닌 오프라인에 캐시된 리소스를 이용하기 때문에 네트워크 접속 없이도 가능하게 된 것이다 (참고로 인터넷 임시파일은 오프라인 상태에서는 무용지물이다)

다만 캐시 매니페스트파일의 NETWORK 섹션에 지정한 mkex2.jpg 이미지는 표시되지 않았다
NETWORK 섹션은 반드시 온라인 상태에서만 접근 가능한 항목이기에 당연하다

참고>
파이어폭스의 '오프라인으로 작업' 메뉴를 통한 오프라인 테스트는 정상동작 하지 않았다
실제로 네트워크 카드를 '사용 안함'으로 하여 테스트를 수행 해 보았다


캐시 업데이트
매니페스트 파일에 지정된 CACHE 섹션 항목들은, 첫 요청 이후 모든 재 요청은 로컬에서 처리된다
즉 a.html 파일이 캐시되었다면 앞으로 이 파일에 대한 모든 액세스는 클라이언트에 캐시된 것이
이용되며 서버로의 요청은 이루어 지지 않는다

만일 a.html 파일이 서버에서 업데이트 되었다면 이를 반영할 수 있어야 하는데
이때에도 역시 캐시매니페시트 파일이 기준이 된다

브라우저는 캐시된 모든 항목들의 변경 사항을 일일이 확인하는 대신
캐시매니페스트 파일의 변경 사항만을 확인하여 캐시 업데이트 여부를 판단한게 된다


매 요청시 마다 캐시매니페스트 파일의 변경 여부를 확인하여,
이 파일이 변경 된 경우 모든 캐시 항목들을 다운로드하여 다시 캐싱 하는 것이다

따라서 클라이언트에 캐시된 리소스를 업데이트 하기 위해서 캐시매니페스트 파일을 변경하면 된다

캐시 매니페스트 파일의 버전(주석) 을 통한 업데이트 관리
캐시 업데이트가 매니페스트 파일의 변경을 기준으로 하기 때문에 이 파일의 업데이트 관리 방법
염두해 둘 필요가 있다.

캐시 업데이트가, 매니페시트 파일에 정의된 파일명의 변경이나 추가,제거라면 매니페스트 파일을
직접 수정하면 되지만, 기존 캐시된 파일안의 내용만 변경된다면 파일명 변경이 일어나지 않기 때문에
딱히 매니페시트 파일을 수정할 것이 없게 된다.

그러나 캐시는 업데이트 되어야 하므로 매니페스트파일을 어떤 식으로든 수정을 해야 한다
(그래야 브라우저는 캐시를 업데이트 할 것이다)

따라서 이런 저런 경우를 다 포함하는 방법이 바로,
매니페스트 파일에 버전 문자열을 주석으로 정의해 두는 것이다

앞서 데모에서도 매니페스트파일에 버전번호를 주석으로 달았는데,
이것이 바로 캐시 업데이트를 위한 것이다. 이렇게 버전 번호를 업데이트 시 마다 변경해 주면
매니페스트파일이 변경된 것과 같으므로 브라우저에게 다시 캐시하도록 할 수 있게 되는 것이다


어플리케이션 캐시 관련 스크립느 API
어플리케이션 캐시는 기본적으로 매니페스트파일을 기준으로 동작하지만
추가 세세한 제어를 위해 스크립트 API 및 몇 가지 이벤트를 지원한다

어플리케이션 캐시 API 의 핵심객체는 applicationCache 객체이며
이 객체의 status 속성으로 캐시 상태를 점검할 수 있다
또한 update() 함수로 캐시 업데이트를 명시적으로 수행할 수 있으며
updaterdady 이벤트를 수신하여 최신 캐시를 얻은 시점을 제어할 수 있다
더불어 업데이트 에러를 알려 주는 error 이벤트, 캐시 완료를 알려 주는 cached 이벤트 등이 있다

또한 progress 이벤트는 업데이트 진행 중에 발생함으로 이 이벤트를 이용하면, 대량 캐시 업데이트 시
진행상태바와 같은 도우미 UI를 제공할 수 있게 된다

기타 몇 가지 유용한 API 와 이벤트가 제공되니 캐시 업데이트를 더욱 세세하게 제어하고 싶으면
관련 자료를 참조하기 바란다


진정한 오프라인 웹 어플리케이션
어플리케이션 캐시가 오프라인 웹 어플리케이션의 근간이 되는 기술이긴 하지만,
보다 철저한 오프라인을 지원하기 위해서는 뭔가 부족함이 있어 보인다

인터넷 연결을 끊어 졌을 때,
URL을 기반으로 하는 웹 리소스에 대한 오프라인 액세스 뿐만 아니라
데이터 조회, 수정, 삭제 등 동적 데이터 관리도 가능하게 하려면 이 기술만으로는 부족하다

동적 데이터 관리를 오프라인 상태에서도 가능토록 하려면, 클라이언트 저장소 기술이 접목되어야 하는데 HTML 5 의 스펙 중 Web Storage, Web Database 등이 이 시나리오에 적합해 보인다

따라서 진정으로 동적 동작이 가능한 오프라인 웹 어플리케이션을 개발하기 위해서는
어플리케이션 캐시와 더불어 Web Storage, Web Database 와 같은 클라이언트 저장소 기술을
같이 사용해야 할 것이다


참고> 리소스가 캐시되는 위치
어플리케이션 캐시는 서버의 리소스를 오프라인에서 사용할 수 있는 것이기 때문에
클라이언트 PC 어딘가에는 해당 리소스를 저장해 둘 필요가 있다
이는 브라우저마다 조금씩 그 위치가 다르긴 하지만 폴더의 구조만 봐도 어느정도 알 수 있다

이 글이 테스트된 파이어폭스의 경우 아래와 같은 경로에 위치하고 있다
(현재 나의 PC 기준이다)
C:\Documents and Settings\사용자이름\Local Settings\Application Data\Mozilla\Firefox\Profiles\o5ywhov7.default\OfflineCache

참고>
http://www.html5rocks.com/tutorials/appcache/beginner/


 

 

'모바일 > HTML5' 카테고리의 다른 글

[HTML5] Canvas  (3) 2010.08.19
[HTML5] Web SQL Database  (0) 2010.08.17
[HTML5] 오프라인 웹 어플리케이션  (0) 2010.08.12
[HTML5] Web Storage  (1) 2010.08.11
[HTML5] 드래그 앤 드롭 (Drag & Drop)  (3) 2010.08.10
[HTML5] Geolocation  (1) 2010.08.09

submit