압축과 난독화
- 서비스에서 공통으로 사용되는 주요 소스 코드들은 별도의 파일로 분리하여 사용
- 코드의 재사용, 캐시 적용, CDN 사용 등의 장점
- 코드 압축은 최소의 노력으로 큰 효과를 볼 수 있는 최적화 방법중 하나.
- 파일의 용량이 감소하며, 민감한 코드를 알아보기 어렵게 만들 수 있다
- 경우에 따라서는 스크립트의 수행 속도에도 영향을 미침
- 설정에 따라 압축한 소스로도 디버깅을 위한 Source Maps 기능을 사용 가능.
압축(Minify)
압축은 전체 소스코드 중 아래와 같은 경우를 제거하는 작업을 말합니다.
- 불필요한 줄바꿈, 공백 밑 들여쓰기
- 짧게 쓸 수 있는 긴 구문(줄일 수 있는 if 구문, 형 변환 축약 등)
- 스코프 내 사용하지 않는 변수
- 주석
- 경우에 따라, console.log, debugger 등의 디버깅용 구문 또는 메서드 호출
- 경우에 따라, 무의미한 메서드 호출 및 루프(Google Closure Compiler 사용하여 적용)
난독화(Uglify)
- 자바스크립트 코드 자체를 분석하기 어렵게 만드는 과정
- 난독화를 했다고 보안처리 없이 중요 정보나 루틴을 자바스크립트에 넣는 것은 매우 위험
- 변수명, 함수명 치환에서부터 자바스크립트의 일부 루틴을 문자열로 바꿔 변수에 담고 뒤섞는 단계 등 여러 단계 존재
- 난독화의 단계를 높일 수록 루틴을 알아보기 어렵게 만들 수 있음
- 변수, 함수명 등이 줄어 용량이 감소하지만 난독화 단계를 높일수록 코드를 해석하고 실행하는 속도가 느려질 수 있으므로, 프로젝트에 맞게 선택하여 적용하는 것이 좋음
UglifyJS
- 현재 주요 자바스크립트 라이브러리에서 가장 많이 쓰이는 소스 압축 도구
- Node.js 기반으로 개발되어 다른 Node.js 모듈들과의 연계 좋음
- Google Closure Compiler보다 방대한 양의 상세 옵션 제공
npm install -g uglify-js
uglifyjs hello.js -o hello.min.js
압축 시 유의점
코드 압축시, 모든 들여쓰기와 공백이 제거되고, 전체 코드가 한줄로 병합됩니다. 원본 코드에서 들여쓰기, 공백, 세미콜론, 콤마, 대괄호 등이 바르게 사용되지 않았을 경우 압축된 코드가 정상적으로 동작하지 않을 수 있습니다.
자바스크립트는 명시적으로 수행되는 컴파일 과정이 없어 이런 오류를 사전에 알아내는 것은 쉽지가 않습니다.
JSHint와 같은 정적 분석 도구를 사용하면 사전에 문제될만한 코드를 검출해낼 수 있습니다. 또한 하드 코딩된 메서드명 또는 변수명은 난독화 과정에서 아래와 같은 문제를 일으킬 수 있습니다.
// before uglify
var myObj = {
test: function() {} }
};
myObj['test']();
// After Uglify
// myObj.test가 b로 변경되었지만, 하드 코딩된 'test'는 변경되지 않음
var a={b:function(){}};a['test']();
난독화 도구는 하드코딩된 코드를 처리할 수 없으므로, 피하는 것이 좋습니다. 혹은 mangle 옵션을 이용하여 특정 이름의 치환을 막을 수 있습니다. UglifyJS에서는 -m 옵션으로 제공되고 있습니다.
-m 변수명이 바뀌어도 상관없는 변수들을 하나의 문자로 바꿔줌으로써 코드의 길이를 줄여준다.
Mangle all properties (except for JavaScript builtins):
$ uglifyjs example.js -c -m --mangle-props
var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());
특정 문자를 제외하고 가능
Mangle all properties except for reserved properties:
$ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_]
var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());
특정 문자가 포함된 것만 가능
Mangle all properties matching a regex:
$ uglifyjs example.js -c -m --mangle-props regex=/_$/
var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc());
옵션을 같이 사용 가능
Combining mangle properties options:
$ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc());
쌍따움표 안에 있는 것 유지
// stuff.js
var o = {
"foo": 1,
bar: 3
};
o.foo += o.bar;
console.log(o.foo);
$ uglifyjs stuff.js --mangle-props keep_quoted -c -m
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
-o 파일로 따로 저장하기. 기존의 파일에서 .min를 붙여주는 암묵적인 규칙을 가진다.
-c
SourceMaps
- SourceMaps은 압축된 코드와 압축 전의 코드를 Base64 기반으로 매핑한 데이터를 의미
- 브라우저가 지원할 경우, 압축된 Base64 내용을 원본과 매핑시켜 압축된 코드를 원본처럼 풀어서 보여주거나, 디버깅이 가능하게 하는 등의 기능을 제공
대부분의 압축도구는 SourceMaps를 지원하지만 아직까지 완벽하게 동작하지는 않습니다. BreakPoint가 제대로 걸리지 않는다던가, SourceMaps 파일이 일정크기 이상 커질 경우 인코딩 문제가 발생하는 등 해결되어야할 문제들이 남아있습니다.
SourceMaps 생성
SourceMaps의 생성은 간단하며, 아래는 Google Closure Compiler 사용시 명령어 입니다.
uglifyjs js/file1.js js/file2.js \
-o foo.min.js -c -m \
--source-map "root='http://foo.com/src',url='foo.min.js.map'"
출처: https://12bme.tistory.com/357 [길은 가면, 뒤에 있다.]
'typescript' 카테고리의 다른 글
자바스크립트 13. 비동기의 꽃 JavaScript async 와 await 그리고 유용한 Promise APIs (0) | 2020.07.07 |
---|---|
자바스크립트 11. 비동기 처리의 시작 콜백 이해하기, 콜백 지옥 체험 😱 JavaScript Callback (0) | 2020.07.02 |
자바스크립트 8. 배열 제대로 알고 쓰자. 자바스크립트 배열 개념과 APIs 총정리 (0) | 2020.06.22 |
Typescript - class (0) | 2020.06.19 |
자바스크립트 7. 오브젝트 넌 뭐니? | 프론트엔드 개발자 입문편 (JavaScript ES6) (0) | 2020.06.17 |
댓글