개발
Nginx gzip 적용하는 법 (웹 리소스 압축)
51 views as of .
목차
웹페이지를 최적화 하는방법은 당장 웹사이트에 걸리는 여러 리소스를 압축하거나 제거, 필요할때 로딩하는 방식으로 줄일 수 있다.
하지만 웹서버 자체가 클라이언트에게 웹리소스를 보낼때 자체적으로 압축을해서 보내는 방법이 있는데 그게 서버단 압축 방법인 gzip을 통해 구현할 수 있다.
Nginx 는 기본적으로 gzip을 지원하긴하지만 세부적인 설정을 우리가 해줘야 하는 경우가 있다.
이 포스팅에선 그 세부설정에 대한 설명과 적절한 옵션을 알아보고자 한다.
gzip 옵션
일단 서버 설정에 들어가보자.
일반적으로 nginx 서버 설정 파일은 /etc/nginx/nginx.conf 또는 /etc/nginx/sites-available/your-site 에서 제어할 수 있다.
통상적으로 우분투 환경에선 아래와 같이 나노 에디터를 이용해 Nginx 설정을 편집할 수 있다.
$ sudo nano /etc/nginx/nginx.conf
Copy
gzip 켜기
gzip on; # Gzip 압축 활성화
Copy
일단 압축을 켜는 옵션이다.
gzip 비활성
gzip_disable "msie6|Mozilla/4"; # IE6 및 오래된 Mozilla 4.x 브라우저에서 Gzip 비활성화
Copy
gzip은 서버뿐만이 아니라 클라이언트 브라우저도 지원해야 사용할 수 있는 기술이다.
최신 브라우저는 대다수 지원하긴하나 너무 오래된 레거시 브라우저는 지원하지 않으니 그럴경우에 대해서 예외처리를 해주는 구문이다.
gzip 타입 추가
gzip_types
text/plain
text/css
text/javascript
text/xml
application/json
application/javascript
application/x-javascript
application/xml
application/xml+rss
image/svg+xml; # SVG 파일도 Gzip 압축 적용
Copy
기본적으로 gzip은 텍스트 형태의 본문만 압축을 지원하나 여기에 추가적으로 파일의 MIME 타입을 기재하면 해당 파일이 웹서버로부터 제공될때 압축을 지원한다.
너무 작은 파일 예외 처리
gzip_min_length 1024; # 최소 1KB 이상 파일만 압축
Copy
gzip은 결국 서버자원을 사용하는거기때문에 너무 작은파일까지 압축을 해버리면 그만큼 서버는 연산을 할 수 밖에없다.
현실적으로 1KB도 안되는 리소스는 압축을애도 그 효과가 미미하므로 제외해주는 코드를 작성한다.
gzip 압축 수준
gzip_comp_level 5; # 압축 수준: 4~6 권장
Copy
어느정도 수준으로 압축률을 사용할지 정한다.
디폴트값은 1이다. 1~9까지의 설정을 사용할 수 있고 1이면 압축률이 낮은대신 속도가 빠르고 9면 압축률이 높은대신 서버의 자원을 많이 사용해서 압축을 실행해서 상대적으로 많이 느리다.
gzip 압축 버퍼
gzip_buffers 16 8k; # 압축 버퍼 설정
Copy
Nginx가 압축을 처리할 메모리 버퍼 크기를 지정한다.
기본값은 32 4k인데 이를 16 8k로 변경하면 더 큰 청크(chunk)를 처리할 수 있어 압축작업이 효율적으로 변하고 버퍼개수가 줄어들어 메모리 할당과 시스템 호출이 줄어든다.
캐싱개선을 위한 헤더 추가
gzip_vary on; # Vary 헤더 추가
Copy
vary 헤더를 추가하면 Accept-Encoding 헤더가 추가되어 브라우저 캐싱 효율성을 높인다.
프록시 환경에서 캐싱 요청
# 프록시 서버가 정적 파일을 캐싱처리하지 않는 경우
gzip_proxied any;
# 프록시 서버가 정적 파일을 캐싱처리 하는 경우
gzip_proxied expired no-cache no-store private auth; # 특정 조건에 Gzip 활성화
Copy
프록시 서버를 통해 웹서비스가 제공되는경우 프록시서버와의 캐싱처리로인한 옵션의 명시적 나열이 필요할 수도 있다.
이때
expired
(유효기간이 지난 리소스), no-cache no-store
(캐싱 금지된 리소스), private
(개인 리소스), auth
(인증이 필요한 리소스) 옵션등을 부여해서 프록시 요청에대한 상세한 gzip 활성화 조건을 부여할 수 있다.프록시 서버를 사용해 서비스를 한다면 통상적으론 모든 프록시 응답에도 대응하기위해
any
옵션으로 쓰면된다.http 버전 추가
gzip_http_version 1.1; # HTTP/1.1 이상에만 적용
Copy
위의 브라우저 예외처리와 마찬가지로 오래된 브라우저를 상징하는
HTTP/1.0
을 배제하기위해 1.1
을 명시적으로 옵션 설정한다.종합 옵션
gzip on;
gzip_disable "msie6|Mozilla/4"; # IE6 및 오래된 Mozilla 브라우저 비활성화
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/x-javascript
text/xml
application/json
application/xml
application/xml+rss
image/svg+xml; # SVG 추가
gzip_min_length 1024; # 최소 1KB 이상 파일만 압축
gzip_comp_level 5; # 압축 수준: 4~6 권장
gzip_buffers 16 8k; # 압축 버퍼 설정
gzip_vary on; # Vary 헤더 추가
gzip_proxied any; # 프록시 서버 응답 사용중이면 설정
gzip_http_version 1.1; # HTTP/1.1 이상에만 적용
Copy
위의 옵션들을 모아서 설정하면 이렇게 적용할 수 있다.
이 코드는 server, location 블록에 개벌적으로 적용할수도 있고 모든 서버에 적용하려면 http 블록에 전역으로 적용할수도 있다.
이후 Nginx 재시작을 해주면 된다.
$ services nginx -s reload
Copy
추가 - 캐싱 옵션 설정
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|otf|eot|ttf|otf|ttf|otf|json)$ {
expires max;
add_header Cache-Control "public, immutable";
}
Copy
위의 압축기능은 서버의 캐싱 전략과 함께 사용한다면 그 시너지가 막대하다.
그러나 이렇게 영구적으로 저장요청한 데이터는 한 번 이상 방문한 브라우저에서 절대 사라지지 않아서 웹페이지 리뉴얼이나 이미지 교체작업을 할때 같은이름으로 하면 절대로 새로운 리소스 반영이 되지않는 문제가 발생하므로 필요에 따라 적절하게 사용해야 한다.
적용 결과
먼저 제대로 gzip이 적용되었는지 확인하려면 터미널을 통해 curl로 헤더에 gzip 이 포함되었는지 확인하는 방법이 있다.
$ curl -I -H "Accept-Encoding: gzip" https://erulabo.com
HTTP/2 200
server: nginx/1.24.0
date: Thu, 23 Jan 2025 06:59:48 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
x-powered-by: PHP/7.3.33
cache-control: private, must-revalidate
pragma: no-cache
expires: -1
permissions-policy: browsing-topics=*
set-cookie: XSRF-TOKEN=eyJpdiI6IklTODg1eWtFMHNZUjEyYllwcjZ3cHc9PSIsInZhbHVlIjoiYXlLWkdtZjVxUmJZZ2IzRUp2NWNFendLWlljSzNXQXZGbTZneVhzN2pTYVd2SGFnRDMyNGE0NjhteHR0VHNnSDlkdFJCd0piQStRMUdpdDBpUVhTMkNmTDdpU0VFQ3BcL08wRGZ5RGEzU1pcL3p6dzE4dEhWajIxU29ZczhjQm1VRiIsIm1hYyI6IjY3ODA2OGJlMTYzYzMwMmI2Y2EyNmU4MzZmOWQxMzBkMTc4M2I3ZDBkYmE1ZTA2ZTA0ZjA0YzdiMGU0YmMxNjEifQ%3D%3D; expires=Thu, 23-Jan-2025 08:59:48 GMT; Max-Age=7200; path=/
set-cookie: _session=eyJpdiI6Im94c0xqU3BGRWxzSk12SEIrWHVrQkE9PSIsInZhbHVlIjoiQkhNRTVpSVJEZStBSVY3YUpkNTllTDc5ZjdtYjQyOHpYRCs0Wk9VXC91SDBYdmVTdTJmaDdkRmg4WjN6RUxSbzd5KzB2dm4zQUVRZGFJcHM1a1crU2dseG1lelwvNkJhYlppb3ZDKzlvaW5CdGVUWktcL25VMmlQXC8rRW5Xa0FvV0RZIiwibWFjIjoiY2QwNjI1Y2RjNjk4OTgxY2RiNjVkZjA1NTBmYmRhZmVkNmEyNTIxYWUzNDAyOTFhOTJjNDMxM2I0ZGZkZWY4MiJ9; expires=Thu, 23-Jan-2025 08:59:48 GMT; Max-Age=7200; path=/; httponly
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
content-encoding: gzip
Copy
위의 실행 결과처럼 마지막에
content-encoding: gzip
이 보이면 서버 설정이 잘 되었다는 의미이다.실제로 압축레벨 1과 5로 비교해보면 아래와 같이 웹서버에서 전송하는 리소스파일의 크기의 차이가 있음을 알 수있다.
레벨 1의 경우 css파일의 크기는 35.7KB고 레벨 5의 경우에는 27.6KB 이다.
무려 1레벨 -> 5레벨 압축률은 23%에 해당한다.
0 55.38 KiB (100.00% of original size)
1 11.22 KiB ( 20.26% of original size)
2 10.89 KiB ( 19.66% of original size)
3 10.60 KiB ( 19.14% of original size)
4 10.17 KiB ( 18.36% of original size)
5 9.79 KiB ( 17.68% of original size)
6 9.62 KiB ( 17.37% of original size)
7 9.50 KiB ( 17.15% of original size)
8 9.45 KiB ( 17.06% of original size)
9 9.44 KiB ( 17.05% of original size)
Copy
그러나 관련 압축률에 대한 웹페이지 텍스트 데이터에 대한 압축 정도를 비교하면 위와 같다고한다.
압축을 하냐 안하냐에 대한 차이가 엄청큰거지 1~9사이의 레벨값에서는 그렇게까지 드라마틱하게 변하지는 않는다.
What is the best nginx compression gzip level?
I'm using nginx reverse proxy cache with gzip enabled. However, I got some problems from Android applications HTTP-requests to my Rails JSON web service. It seems when I turn off reverse proxy cach...
https://serverfault.com/questions/253074/what-is-the-best-nginx-compression-gzip-level
이렇게 Nginx의 gzip 적용법과 그 영향에 대해 기록으로 남겨보았다.
끝!
#Nginx
0
개의 댓글
개발 카테고리의 다른 글
01/24
Mac 터미널로 유튜브 다운로드 하기 (yt-dlp)
우리가 유튜브에서 영상을 찾아보다면 필요에 따라 영상을 다운받고 싶을때가 있다.이럴때 제일 무난한거는 온라인에서 유튜브...
01/23
php gd 라이브러리를 이용한 이미지 리사이징 (webp)
거의 5년전에 php 이미지 용량 리사이징이라는 개발 글을 쓴적이 있다.해당 글에서는 순수 php 코드를 이용해서 간단히 용량 리...
01/14
페이지네이션과 로드 모어(Load More)를 동시 구현해보자
우리가 일반적으로 여러 데이터 레코드를 보기좋게 구현하기 위해서는 테이블 구조를 이용하곤한다. 테이블 구조는 행과 열로 구...