>  기사  >  웹 프론트엔드  >  JavaScript 템플릿 엔진-tmpl 버그 수정 및 성능 최적화 분석_javascript 기술

JavaScript 템플릿 엔진-tmpl 버그 수정 및 성능 최적화 분석_javascript 기술

WBOY
WBOY원래의
2016-05-16 18:00:251004검색

오픈소스에는 정교한 tmpl
프런트엔드 템플릿이 많이 있지만 jQuery 작성자 John Resig가 개발한 “javascript micro template”가 가장 절묘합니다. 단 몇 번의 스트로크만으로 템플릿 엔진의 핵심 기능을 구현합니다.
소개 및 사용법은 작성자의 블로그를 참조하세요: http://ejohn.org/blog/javascript-micro-templating/
먼저 그의 소스 코드를 살펴보겠습니다:

코드 복사 코드는 다음과 같습니다.

(function(){
var 캐시 = {};
this.tmpl = 함수(str, 데이터){
var fn = !/W/.test(str) ?
cache[str] = 캐시[str] || .getElementById(str).innerHTML):
new Function("obj",
"var p=[],print=function(){p.push.apply(p,arguments);};"
"with(obj ){p.push('"
str
.replace(/[rtn]/g, " ")
.split("<%").join(" t")
.replace(/((^|%>)[^t]*)'/g, "$1r")
.replace(/t=(.*?)%> /g, "', $1,'")
.split("t").join("');")
.split("%>").join("p.push( '")
.split("r").join("\'")
"');}return p.join('');");
return data ? fn( data ) :
};
})();

참새는 작지만 기본 데이터 외에도 모든 기능을 갖추고 있습니다. 캐싱 메커니즘 및 논리 지원. 이제 JavaScript에서 가장 에너지를 절약하는 사용자 정의 함수의 순위를 매긴다면 첫 번째는 $ 함수(document.getElementById 단축 버전)이고 두 번째는 tmpl입니다.
물론 완벽하지는 않습니다. 사용 중에 몇 가지 문제를 발견했습니다.
tmpl에 연고가 있습니다
1. 다음과 같은 이스케이프 문자를 올바르게 처리할 수 없습니다.

코드 복사 코드는 다음과 같습니다.
tmpl('<%=name%>//<%=id% > ', {name:'sugar Pie', id: '1987'})
오류가 보고됩니다. 제대로 작동하면 다음과 같이 출력되어야 합니다. Sugar Cookie/1987
사실 해결 방법은 매우 간단합니다. 이스케이프 문자를 이스케이프 처리하는 정규 표현식 줄을 추가하면 됩니다.

코드 복사 코드는 다음과 같습니다.
str.replace(/\/g, "\\")
2. 가끔 제대로 구분이 안 됩니다. 첫 번째 매개변수는 ID인가요, 아니면 템플릿인가요?
tmpl-photo-thumb과 같이 페이지 템플릿 ID에 밑줄이 그어진 경우 이 이름의 템플릿을 찾지 않고 전달된 원본 템플릿을 직접 컴파일하여 출력하는 것으로 간주합니다.
원래 템플릿과 요소 ID의 가장 직관적인 차이점은 공백이 포함되어 있는지 여부이므로 정규식을 변경하면 됩니다.
view sourceprint?1 !/s/.test(str)
3. 내부에도 테스트용 코드가 남아 있어 삭제할 수 있습니다.

코드 복사 코드는 다음과 같습니다.
print=function(){p.push.apply( p,arguments );}
tmpl 효율성에 대한 의심
얼마 전 YayaTemplate을 소개하는 Baidu mux의 소프트 기사를 읽기 전까지, 원본 기사의 작성자는 주요 인기 템플릿 엔진에 대한 효율성 테스트를 수행했는데, 마침내 YayaTemplate이 가장 인기 있는 템플릿 엔진이라는 결론을 얻었습니다. tmpl의 테스트 결과는 YayaTemplate만큼 좋지는 않지만, 실제 적용에서는 전통적인 문자열 연결과 거의 동일하므로 성능에 대한 우려를 해소할 수 있습니다. 매우 큰 규모의 분석을 수행하는 경우에만 성능 차이가 커집니다. (초대형? JavaScript 자체는 이에 적합하지 않습니다. 어느 날 프로그래머가 한 번에 수천 개의 목록 데이터를 브라우저에 삽입했는데 속도가 극도로 느리다면 의심의 여지가 없습니다. 문제는 이 프로그래머에게 있습니다. )
엔진 효율 순위에 있어서는 이것이 템플릿 엔진을 측정하는 주요 기준이 아니라고 생각합니다. 이때 템플릿 구문도 중요한 부분이 됩니다. 훨씬 더 모호한 점은 몇 가지 정규식을 저장하기 위해 템플릿 구문을 교묘하게 변형한 것입니다.
먼저 YayaTemplate의 소스 코드를 보여주세요:

코드 복사 코드는 다음과 같습니다.

//author:yaya,jihu
//uloveit.com.cn/template
//사용 방법 YayaTemplate("xxx").render({}); var YayaTemplate = YayaTemplate || function(str){
//핵심 분석 방법
var _analyze=function(text){
return text.replace(/{$(s|S)*?$} /g,함수(들){
return s.replace(/("|\)/g,"\$1")
.replace("{$",'_s.push("')
.replace("$}",'");')
.replace(/{%([sS]*?)%}/g, '",$1,"')
}) .replace(/r|n/g,"");
};
//중간 코드
var _temp = _analyze(document.getElementById(str)?document.getElementById(str).innerHTML: str);//생성기 렌더링 메서드 반환
return {
render : function(mapping){
var _a = [],_v = [],i
for (i in 매핑){
_a.push(i);
_v.push(mapping[i])
}
return (new Function(_a,"var _s=[];" _temp " return _s;")).apply(null,_v).join("");
}
}
};


성능 문제가 1로 제기된 경우 "학술적 문제"를 해결하기 위한 높은 수준의 시도, tmpl이 YayaTemplate보다 느린 이유는 무엇입니까?
문법 구문 분석 YayaTemplate은 html을 자바스크립트로 래핑하는 새로운 방법을 사용하지만 궁극적으로 정규 표현식을 사용하여 표준으로 구문 분석해야 합니다. .JavaScript 구문에서는 정규화 효율성에 큰 차이가 없으며 양측 모두 캐싱 메커니즘을 사용하여 원본 템플릿이 한 번만 구문 분석되도록 합니다. 템플릿 엔진은 결국 데이터를 변수 형식으로 저장합니다. 템플릿이 이를 얻을 수 있도록 클로저를 닫습니다. 먼저 두 당사자의 변수 선언 메커니즘을 비교해 보겠습니다.
YayaTemplate은 매개변수를 전달하는 전통적인 방법을 사용하여 구현됩니다. 데이터 객체를 순회하여 객체의 이름과 값을 분리한 후 객체 멤버 이름을 새 Function의 매개변수 이름(즉, 변수 이름)으로 사용한 다음 함수의 appley 호출 메서드를 사용하여 해당 매개변수를 전달하세요.
tmpl은 JavaScript에서 일반적으로 사용되지 않는 with 문을 사용하여 구현됩니다. 구현은 var 키워드를 생략하여 매우 간단합니다.
tmpl의 성능 문제는 다음과 같습니다. 자바스크립트에서 제공하는 with 문은 객체의 속성에 더 빠르게 접근하기 위해 사용됩니다. 불행하게도 언어에 with 문이 있으면 변수 이름의 어휘 범위 지정을 방지하기 때문에 JavaScript 엔진의 속도가 심각하게 느려집니다.
tmpl 최적화
tmpl이 with 문을 제거하고 기존 매개변수 전달을 사용하면 성능이 즉시 크게 향상됩니다. 실제 테스트를 통해 240,000개 데이터 미만에서 Firefox는 5배, Chrome은 2.4배, Opera 1.84를 향상시킬 수 있습니다. 배, Safari 2.1배, IE6 1.1배, IE9 1.35배로 최종적으로 YayaTemplate과 동률을 이루었습니다.
테스트 주소: http://www.planeart.cn/demo/tmpl/tmpl.html
Tmpl 최적화 버전 최종 코드:



코드 복사 코드는 다음과 같습니다.

/**
* 마이크로 템플릿 엔진 tmpl 0.2
*
* 0.2 업데이트:
* 1. 이스케이프 문자 및 id 판단 버그 수정
* 2. 비효율적인 with 문을 버리고 최고 수준 달성 실행 효율성 3.5배 향상
* 3. 임의의 내부 변수를 사용하여 템플릿 변수와의 충돌 방지
*
* @author John Resig, Tang Bin
* @see http://ejohn.org/ blog/javascript-micro-templating/
* @name tmpl
* @param {String} 템플릿 콘텐츠 또는 템플릿 콘텐츠가 포함된 요소 ID
* @param {Object} 추가 데이터
* @return { String} 구문 분석된 템플릿
*
* @example
* 방법 1: 페이지에 템플릿 삽입
*