얼마 전 회사의 기존 프로젝트의 JavaScript 코드가 최적화되었습니다. 이 기사는 최적화 작업을 요약한 것이며 모든 사람과 공유됩니다. 물론 제 최적화 방법이 최적이 아닐 수도 있고, 뭔가 잘못된 부분이 있을 수도 있습니다. 조언 부탁드립니다.
JavaScript 최적화 요약은 다음과 같은 점으로 나누어집니다
최적화 전후 비교
최적화 전
최적화 후
코드 혼동 , 동일한 기능 기능이 여러 곳에 반복적으로 나타납니다. 구현을 수정해야 하는 경우 모든 위치를 찾아야 합니다. 모듈화, 공용 인터페이스 추출 및 명확한 구조, 편리한 코드 재사용 및 다양한 오염 문제 방지 기능을 갖춘 라이브러리로 구성합니다.
JavaScript 파일은 크기가 상대적으로 큽니다. 로드하는 데 네트워크 시간이 소모되고 페이지 렌더링이 차단됩니다. JavaScript 공개 라이브러리 파일은 UglifyJS를 사용하여 압축됩니다.
● 크기가 상대적으로 작고 네트워크 로딩 시간이 최적화됩니다
● 압축은 코드를 난독화하고 어느 정도 코드를 보호합니다
사용할 경우 여러 개의 별도 JavaScript 파일을 로드해야 하므로 http 요청 수가 늘어나고 성능이 저하됩니다. 공용 라이브러리를 병합하고 압축하면 크기가 줄어듭니다. http 요청 수
문서가 부족하여 후속 개발자가 기존 기능을 명확하게 알 수 없게 되어 어느 정도 동일한 기능이 여러 위치에 반복적으로 표시됩니다. 앞에서 언급함) 모든 공공 라이브러리에는 클래스, 함수 및 속성이 모두 문서화되어 있습니다.
● 모듈화(클래스 프로그래밍): 명확한 코드, 가변 오염 문제의 효과적인 방지, 손쉬운 확장을 위한 코드 재사용 등
● JavaScript 압축 혼동: 크기가 줄어들어 로딩 시간이 최적화되고 보호 코드가 난독화됩니다.
● JavaScript 파일 병합: http 요청 최적화 네트워크 시간 소모가 줄어들고 성능이 향상됩니다.
● 문서 생성 : 공공도서관 이용을 용이하게 하고 인터페이스를 쉽게 찾을 수 있습니다.
모듈화(클래스 프로그래밍)
정적 클래스의 경우 JavaScript 구현은 비교적 간단하지만 객체를 직접 사용하는 것만으로도 충분합니다. 어떤 일. JavaScript는 프로토타입 기반 프로그래밍 언어이고 내장 클래스의 구현을 포함하지 않기 때문에(접근 제어 문자가 없고 클래스를 정의하는 키워드 클래스가 없으며 상속을 위한 확장 또는 콜론을 지원하지 않습니다.) 가상 함수(가상 등)를 지원하는 것은 쓸모가 없지만 JavaScript를 통해 클래식 클래스를 쉽게 시뮬레이션할 수 있습니다.
정적 클래스
베이비 JS 퍼블릭 인터페이스의 특성상 인스턴스화할 필요가 없으므로 최적화를 위해 이 방법을 사용합니다. 다음은 PetConfigParser를 예시로 사용하여 구현 방법을 소개합니다.
var PetConfigParser;
if (!PetConfigParser) {
PetConfigParser = {} ;
}
(function () {
//개인 변수, 함수
/**
* 키가 [cate * 10000 + (lvl - 1) * 10 + dex - 1]인 모든 아기 구성 사전
* @attribute petDic
* @ 유형 {객체}
* @private
* /
var petDic = null; //아기 사전
/**
* cate, dex, lvl 조합을 키로 사용하여 __pet_config를 기반으로 객체 사전 구축
* @method buildPetDic
* @private
* @return {void}
*/
function buildPetDic() {
petDic = new Object();
for (var item in __pet_config) {
var lvl =parseInt(__pet_config[item]['lvl']);
var dex =parseInt(__pet_config[item]['dex']);
var cate =parseInt(__pet_config[item]['cate']);
var key = cate * 10000 + (lvl - 1) * 10 + dex;
petDic[key] = __pet_config[item];
}
}
//공개 인터페이스
/**
* baby id를 기준으로 __pet_config에서 해당 baby 정보를 읽어옵니다.
* @method getPetById
* @param {String/int} petId baby id
* @return {Object} 애완 아기의 모든 정적 정보, 예: {id: "300003289", lvl: "1", dex: "2", 가격: "200", 수명: "2592000", cate: "3", name:"Flying Angel Level 1 Proficient 2", 소개:"", Skill:"Amulet", Skill1_prob:"30", Skill2_prob:"0"}
*/
if (typeof PetConfigParser.getPetById !== 'function') {
PetConfigParser.getPetById = function (petId) {
var pet = ("undefine" == typeof (__pet_config)) ? null : __pet_config["pet_" + petId];
내부적으로만 액세스할 수 있는 비공개 범위를 만드는 함수입니다. 위의 과정을 요약하면 다음과 같은 단계로 나누어집니다.
1) 전역 변수(var PetConfigParser)를 정의하고, 변수의 첫 글자와 일반 변수의 차이점에 주의하세요.
2) 그런 다음 익명 함수를 생성하고 ((function () {/*xxxx*/ })(); )를 실행하고, 현재 범위에서만 액세스할 수 있는 익명 함수 내에 지역 변수와 함수를 생성합니다. 🎜>
3 ) 전역 변수(var PetConfigParser)는 익명 함수 내에서 PetConfigParser를 작동하여 정적 함수를 추가하면 어디서든 접근할 수 있습니다. 사용 예: $(function () { DialogManager.init(); }); $('#cofirmBtn').click( Function () {
Dialogmanager.hide ();
false 반환
}} ; 메서드 ● 프로토타입 메서드 ● 혼합 메서드 생성자 방법 생성자는 인스턴스 객체의 속성과 값을 초기화하는 데 사용됩니다. 모든 JavaScript 함수를 생성자로 사용할 수 있으며, 새 인스턴스를 생성하려면 생성자 앞에 new 연산자를 붙여야 합니다. var Person = 함수(이름) { this.name = 이름; this.sayName = 함수(){ Alert(this.name); };} //인스턴스화var tyler = new Person ("tylerzhu");var saylor = new Person("saylorzhu");tyler.sayName();saylor.sayName();
//인스턴스 확인alert(tyler instanceof Person);생성자 메서드가 기존 객체지향 언어에 익숙합니까? 단지 class 키워드가 function으로 대체되었을 뿐입니다. 참고: 그렇지 않으면 new를 생략하지 마십시오. Person("tylerzhu") //==>정의되지 않음. new 키워드를 사용하여 생성자를 호출하면 실행 컨텍스트가 전역 개체(창)에서 새로 생성된 인스턴스를 나타내는 빈 컨텍스트로 변경됩니다. 따라서 this 키는 현재 생성된 인스턴스를 가리킵니다. 따라서 new가 생략되고 컨텍스트 전환이 수행되지 않은 경우 전역 개체에서 name을 검색하여 찾지 못하면 전역 변수 name이 생성되고 undefine이 반환됩니다. 프로토타입 방식생성자 방식은 간단하지만 메모리 낭비 문제가 있다. 예를 들어 위의 예에서는 tyler와 saylor라는 두 객체가 인스턴스화되어 있습니다. 표면적으로는 문제가 없어 보이지만 실제로는 각 인스턴스 객체에 대해 sayName() 메서드의 내용이 완전히 동일합니다. 인스턴스가 생성되면 애플리케이션 콘텐츠의 내용이 반복되어야 합니다. alert(tyler.sayName == saylor.sayName)는 false를 출력합니다! ! ! Javascript의 모든 생성자에는 다른 객체를 가리키는 프로토타입 속성이 있습니다. 이 객체의 모든 속성과 메서드는 생성자의 인스턴스에서 공유됩니다. var Person = 함수(이름) { Person.prototype = 이름; Person.prototype.sayName = 함수(){ 경고(this.name); }} //인스턴스화var tyler = new Person("tylerzhu");var saylor = new Person("saylorzhu");tyler.sayName();saylor.sayName(); //인스턴스 확인alert(tyler instanceof Person);이때 tyler와 saylor 인스턴스의 sayName 메소드는 모두 동일합니다. 메모리 주소(프로토타입 객체를 가리킴)이므로 프로토타입 메서드는 메모리를 절약합니다. 그러나 tyler.sayName();saylor.sayName();의 출력을 보면 문제가 있음을 알 수 있습니다. 둘 다 "saylorzhu"를 출력합니다. 프로토타입의 모든 속성이 공유되기 때문에 하나의 인스턴스가 변경되는 한 다른 인스턴스도 그에 따라 변경되므로 인스턴스화된 객체 saylor가 tyler를 덮습니다. 생성자+프로토타입 하이브리드 방식
생성자 메서드는 동일한 클래스의 각 개체에 대해 서로 다른 메모리를 할당할 수 있습니다. 이는 클래스를 작성할 때 속성을 설정하는 데 매우 적합합니다. 그러나 메서드를 설정할 때는 동일한 클래스의 여러 개체가 동일한 메모리를 공유하도록 해야 합니다. 프로토타입 방식으로 메소드를 작성하는 것이 가장 좋습니다. 따라서 클래스를 작성할 때 생성자 메서드와 프로토타입 메서드를 혼합해야 합니다(많은 클래스 라이브러리에서 제공하는 클래스 생성 방법이나 프레임워크의 클래스 작성 방법은 기본적으로 생성자 + 프로토타입).
var Person = 함수(이름) {
Person.prototype = 이름;
Person.prototype.sayName = 함수(){
경고(this.name);
}
}
//인스턴스화
var tyler = new Person("tylerzhu");
var saylor = new Person("saylorzhu");
tyler.sayName();
saylor.sayName();
//인스턴스 확인
alert(tyler instanceof Person);
이렇게 생성자를 통해 서로 다른 이름을 가진 사람들을 구성할 수 있으며, 객체 인스턴스도 sayName을 공유합니다. method, no 메모리 낭비가 발생합니다.
JavaScript 압축/병합
JavaScript 코드 압축 난독화의 의미: 간단히 말하면 js 파일의 크기를 줄이고, 중복된 주석, 줄바꿈, 들여쓰기 등을 제거하는 것이므로 사용자 경험을 더 빠르게 다운로드할 수 있습니다.
“JQuery 1.5가 출시되었을 때 John Resig는 사용된 코드 최적화 프로그램이 Google Closure에서 UglifyJS로 전환되었으며 새로운 도구의 압축 효과가 매우 만족스럽다고 말했습니다.”