웹서비스 최적화 방법중에 하나로 gzip 압축전송이 있습니다.
gzip은 파일 압축에 쓰이는 응용 소프트웨어로 GNU zip의 준말이며 무료 소프트웨어이다(출처: 위키백과)
이를 사용하기 위해서는 사용하는 브라우저가 지원을 해야합니다.
(브라우저에서 request headers > “Accept-Encoding”에 gzip이 포함되어 있어야 합니다.)
마찬가지로 서버에서도 gzip으로 전송해야 합니다.
(response headers > “Content-Encodding:gzip”)
배경
일반적인 Http Request & Response와 gzip사용시 차이점을 간단히 설명하면 다음과 같습니다.
1.브라우저에서 index.html을 서버에 요청합니다.
2.서버는 해당 파일을 찾습니다.
3.파일을 요청한 브라우저로 전송합니다(100KB).
4.브라우저는 해당 파일을 표시합니다.
1.브라우저에서 index.html을 서버로 요청시 gzip을 지원한다는 내용을 서버로 전달합니다.
2.서버는 해당 파일을 찾습니다.
3.gzip으로 파일을 압축해서 보냅니다(30KB).
4.브라우저에서 압축된 파일을 풀고 표시합니다.
테스트 환경
- 서버 OS: Windows7
- 웹서버: Apache 2.4
- 브라우저: IE9, 크롬, Firefox, Safari
환경설정
1.Apache httpd.conf 파일 열기
2.LoadModule 영역에서 아래내용에 주석처리 되었으면 해제합니다.
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule filter_module modules/mod_filter.so
3.적당한 위치에 아래 내용을 추가합니다.
<IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript DeflateCompressionLevel 9 BrowserMatch ^Mozilla/4 gzip-only-text/html # Netscape 4.xx에는 HTML만 압축해서 보냄 BrowserMatch ^Mozilla/4\.0[678] no-gzip # Netscape 4.06~4.08에는 압축해서 보내지 않음 BrowserMatch \bMSIE !no-gzip !gzip-only-text/html # 자신을 Mozilla로 알리는 MSIE에는 그대로 압축해서 보냄 ##예외 설정 SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|bmp|zip|gz|rar|7z)$ no-gzip dont-vary ####로그설정. ##DeflateFilterNote Input instream ##DeflateFilterNote Output outstream ##DeflateFilterNote Ratio ratio ## ##LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate ##CustomLog logs/deflate_log deflate
4.아파치를 restart 시킨 후 아래 사이트에서 gzip전송이 정상동작하는지 테스트 합니다.
http://www.whatsmyip.org/http-compression-test/
위 결과 페이지에서는 특정페이지가 84.5% 절감되고 있습니다.
Response Headers 내용은 아래와 같습니다.
※ 3번 “로그설정” 주석해제 후 apache logs폴더에 생성된 deflate_log파일을 보면 압축률을 확인할 수 있습니다.
각 라인 마지막 부분의 괄호안 퍼센트는 압축전 파일크기에 대한 압축 후 파일크기 비율을 나타냅니다. "GET /nexacro14lib/framework/SystemBase.js HTTP/1.1" 23987/176486 (13%) "GET /nexacro14lib/framework/Platform_HTML5.js HTTP/1.1" 18786/138984 (13%) "GET /nexacro14lib/framework/ErrorDefine.js HTTP/1.1" 4886/18684 (26%) "GET /nexacro14lib/framework/CssObjs.js HTTP/1.1" 25266/271916 (9%) "GET /nexacro14lib/framework/BasicObjs.js HTTP/1.1" 9152/50003 (18%) "GET /nexacro14lib/framework/Platform.js HTTP/1.1" 58726/370077 (15%) "GET /nexacro14lib/framework/SystemBase_HTML5.js HTTP/1.1" 50261/334443 (15%) "GET /nexacro14lib/component/CompBase/CompBase.js HTTP/1.1" 28574/167299 (17%) "GET /nexacro14lib/component/CompBase/CompEventBase.js HTTP/1.1" 17397/255753 (6%) 이하생략
미리 gzip으로 압축후 사용할 순 없을까?
gzip 사용시 단점은 요청시 gzip으로 압축하는 과정으로 인해
서버의 CPU사용량이 gzip을 사용하지 않을 때 보다 증가한다는 것이다.
그렇다면 거의 변할 일이 없는 file은 미리 압축해서 사용하는것도 괜찮지 않을까?
1.gzip으로 압축하기
Online YUI Compressor에 접속 후 아래그림 처럼 소스를 gz파일로 변환한다.① 원하는 소스를 붙여넣기 한다.② 결과는 “Redirect to gzipped output”을 선택한다.③ “Compress”버튼을 누르면 잠시 후 파일을 저장할 수 있는 팝업창이 표시된다.④ “gz”확장자로 원하는 위치와 파일명으로 저장합니다.
2.해당 파일을 영역안에 포함시킵니다.
<script type="text/javascript" src="./pkg/EcoBasic.js.gz"></script>
3.위와 같이 하고 해당페이지에 접속하면 아래처럼 log가 발생하고 정상적으로 load되지 않습니다(크롬).
Content-Encoding:gzip Content-Type:application/x-gzip Resource interpreted as Script but transferred with MIME type application/x-gzip: "http:// ~ /pkg/EcoBasic.js.gz".
4.Apache httpd.conf 파일의 LoadModule 영역에서 아래내용에 주석처리 되었으면 해제합니다.
LoadModule dir_module modules/mod_dir.so
아래 2줄을 주석처리 되어있으면 해제합니다.
AddEncoding x-compress .Z AddEncoding x-gzip .gz .tgz
아래 2줄을 주석처리 합니다.
#AddType application/x-compress .Z #AddType application/x-gzip .gz .tgz
아래 내용도 추가해야 한다고 나와있었는데 실제로 해보니 적용하지 않아도 처리되었습니다(참고하세요).
:gz 확장자에 대해서 강제로 content-encoding을 설정하는 내용입니다.
# 경로는 root 이하 파일위치를 적어줌. <Directory /~/EcoPkg> Options Indexes MultiViews FollowSymLinks #AllowOverride None #Order deny,allow #Deny from all #Allow from 127.0.0.0/255.0.0.0::1/128 AddEncoding gzip gz <FilesMatch "\.gz$"> ForceType text/plain Header set Content-Encoding: gzip FilesMatch> ## <FilesMatch "\.css\.gz$"> ## ForceType text/css ## Header set Content-Encoding: gzip ## FilesMatch> Directory>
5.설정 후 아파치 restart후에 Response Headers를 확인하면 다음과 같습니다.
마치며…
※ RUNTIME(2014,9,3,1 버전 기준)에서는 지원하지 않습니다.
이미지와 PDF파일은 gzip으로 압축하지 않는다(이미 압축되어 있음).
gzip을 지원하는 브라우저 목록(출처: webmasters.stackexchange.com, 참고: schroepl.net)
- Netscape 6+ (Netscape 4-5 does, but with some bugs).
- Internet Explorer 5.5+ (July 2000) and IE 4 if set to HTTP/1.1.
- Opera 5+ (June 2000)
- Firefox 0.9.5+ (October 2001)
- Chrome since forever
- Safari since forever (as far as I can tell)
이 글에서는 Apache httpd.conf 파일을 이용한 예제가 작성되었지만 .htaccess 파일을 이용할 수 도 있다.