AJAX 클 라 이언 트 응답 속도 향상 분석

이론 적 으로 AJAX 기술 은 사용자 가 조작 하 는 대기 시간 을 어느 정도 줄 이 는 동시에 네트워크 의 데이터 트 래 픽 을 절약 할 수 있다.그러나 실제 상황 은 늘 그렇지 않다.사용 자 는 종종 AJAX 를 사용 한 시스템 응답 속도 가 오히려 낮 아 졌 다 고 불평 한다.필 자 는 AJAX 분야 의 연구 개발 에 다년간 종사 하여 현재 국내 에서 비교적 성숙 한 AJAX 플랫폼-dorado 개발 에 참여 했다.필자 의 경험 에 따 르 면 이런 결 과 를 초래 한 근본 원인 은 AJAX 가 아니다.많은 경우 에 시스템 응답 속도 의 감 소 는 합 리 적 이지 않 은 인터페이스 디자인 과 효율 적 이지 못 한 프로 그래 밍 습관 으로 인해 발생 한다.다음은 AJAX 개발 과정 에서 항상 주의해 야 할 부분 몇 가 지 를 분석 해 보 겠 습 니 다.클 라 이언 트 프로 그래 밍 과 원 격 프로 세 스 를 합 리 적 으로 사용 하여 클 라 이언 트 를 호출 하 는 프로 그래 밍 은 주로 자바 스 크 립 트 를 기반 으로 합 니 다.한편,자바 스 크 립 트 는 해석 형 프로 그래 밍 언어 로 자바 등에 비해 운영 효율 이 약간 떨어진다.또한 자 바스 크 립 트 는 브 라 우 저 와 같은 엄격 한 제 한 된 환경 에서 실 행 됩 니 다.따라서 개발 자 들 은 어떤 논리 가 클 라 이언 트 에서 실 행 될 수 있 는 지 에 대해 명확 한 인식 을 가 져 야 한다.실제 응용 에서 클 라 이언 트 프로 그래 밍 을 어떻게 사용 해 야 하 는 지 는 개발 자의 경험 판단 에 의존한다.이곳 의 많은 문 제 는 단지 예상 할 수 있 는 것 이다.편폭 이 제한 되 어 있 기 때문에 여기 서 우 리 는 대체적으로 다음 과 같은 몇 가지 주의사항 을 요약 한다.가능 한 한 원 격 프로 세 스 호출 을 자주 사용 하지 않도록 한다.예 를 들 어 순환 체 에서 원 격 프로 세 스 호출 을 사용 하지 않도록 한다.가능 하 다 면 가능 한 한 AJAX 방식 의 원 격 프로 세 스 호출(비동기 방식 의 원 격 프로 세 스 호출)을 사용 하 세 요.클 라 이언 트 에 중량급 데이터 조작 을 두 지 않도록 합 니 다.예 를 들 어 대량의 데이터 복사 작업,대량의 데 이 터 를 통 해 완 성 된 계산 등 이다.DOM 대상 에 대한 조작 방식 을 개선 합 니 다.클 라 이언 트 의 프로 그래 밍 에서 DOM 대상 에 대한 조작 은 CPU 시간 을 가장 쉽게 차지 합 니 다.한편,DOM 대상 의 조작 에 있어 서로 다른 프로 그래 밍 방법 간 의 성능 차 이 는 매우 크다.다음은 3 단 실행 결과 가 똑 같은 코드 입 니 다.웹 페이지 에 10x 1000 표를 만 드 는 역할 을 합 니 다.하지만 이들 의 운행 속 도 는 천양지차 다
 
/* 1 - : 41 */
var table = document.createElement("TABLE");
document.body.appendChild(table);
for(var i = 0; i < 1000; i++){
var row = table.insertRow(-1);
for(var j = 0; j < 10; j++){
var cell = objRow.insertCell(-1);
cell.innerText = "( " + i + " , " + j + " )";
}
}
/* 2 - : 7.6 */
var table = document.getElementById("TABLE");
document.body.appendChild(table);
var tbody = document.createElement("TBODY");
table.appendChild(tbody);
for(var i = 0; i < 1000; i++){
var row = document.createElement("TR");
tbody.appendChild(row);
for(var j = 0; j < 10; j++){
var cell = document.createElement("TD");
row.appendChild(cell);
cell.innerText = "( " + i + " , " + j + " )";
}
}
/* 3 - : 1.26 */
var tbody = document.createElement("TBODY");
for(var i = 0; i < 1000; i++){
var row = document.createElement("TR");
for(var j = 0; j < 10; j++){
var cell = document.createElement("TD");
cell.innerText = "( " + i + " , " + j + " )";
row.appendChild(cell);
}
tbody.appendChild(row);
}
var table = document.getElementById("TABLE");
table.appendChild(tbody);
document.body.appendChild(table);
이곳 의'테스트 코드 1'과'테스트 코드 2'사이 의 차 이 는 표 셀 을 만 들 때 서로 다른 API 방법 을 사용 한 것 이다.한편,'테스트 코드 2'와'테스트 코드 3'의 차 이 는 처리 순서 가 약간 다르다 는 데 있다.'테스트 코드 1'과'테스트 코드 2'사이 의 이렇게 큰 성능 차 이 는 분석 할 수 없다.현재 알 고 있 는 것 은 insertRow 와 insertCell 은 DHTML 에서 표 특유 의 API 이 고 createElement 와 appendChild 는 W3C DOM 의 원생 API 이다.전 자 는 후자 에 대한 포장 이 어야 한다.그러나 DOM 의 네 이 티 브 API 가 항상 대상 특유 의 API 보다 우수 하 다 는 결론 을 내 릴 수 는 없다.어떤 API 를 자주 호출 해 야 할 때 그 성능 표현 에 대해 기본 적 인 테스트 를 하 는 것 을 권장 합 니 다.'테스트 코드 2'와'테스트 코드 3'사이 의 성능 차 이 는 주로 그들의 구축 순서 가 다 르 기 때문이다.'테스트 코드 2 는 가장 바깥쪽 의대상 을 먼저 만 든 다음 순환 중 에과
를 순서대로 만 드 는 것 입 니 다.'테스트 코드 3'의 방법 은 먼저 메모리 에서 내부 에서 밖으로 전체 표를 구축 한 다음 에 웹 페이지 에 추가 하 는 것 이다.이렇게 하 는 목적 은 가능 한 한 브 라 우 저가 페이지 레이아웃 을 다시 계산 하 는 횟수 를 줄 이 는 것 이다.웹 페이지 에 대상 을 추가 할 때마다 브 라 우 저 는 페이지 의 컨트롤 레이아웃 을 다시 계산 하려 고 시도 합 니 다.따라서 우리 가 먼저 메모리 에 구조 할 대상 을 모두 만 든 다음 웹 페이지 에 한꺼번에 추가 할 수 있다 면.그러면 브 라 우 저 는 레이아웃 재 계산 을 한 번 만 할 것 입 니 다.한 마디 로 늦 을 수록 append Child 가 좋다 는 거 야.운영 효율 을 높이 기 위해 서 는 이미 존재 하 는 컨트롤 을 페이지 에서 제거 한 다음 구조 가 완 료 된 후에 다시 페이지 에 놓 는 것 도 고려 할 수 있다.문자열 의 누적 속 도 를 높이 기 위해 AJAX 를 사용 하여 정 보 를 제출 할 때,나 는 종종 비교적 큰 문자열 을 XmlHttp 를 통 해 POST 제출 을 완성 해 야 할 수도 있다.비록 이런 큰 정 보 를 제출 하 는 방법 은 우아 해 보이 지 않 지만,때때로 우 리 는 이런 수요 에 직면 해 야 할 수도 있다.자 바스 크 립 트 에서 문자열 에 대한 누적 속 도 는 어 떻 습 니까?우리 먼저 아래 의 이 실험 을 하 자.길이 가 30000 인 문자열 을 누적 합 니 다
 
/* 1 - : 14.325 */
var str = "";
for (var i = 0; i < 50000; i++) {
str += "xxxxxx";
}
이 코드 는 14.325 초 걸 렸 고 결 과 는 이상 적 이지 않 았 다.지금 우 리 는 코드 를 다음 과 같은 형식 으로 바 꿉 니 다
 
/* 2 - : 0.359 */
var str = "";
for (var i = 0; i < 100; i++) {
var sub = "";
for (var j = 0; j < 500; j++) {
sub += "xxxxxx";
}
str += sub;
}
이 코드 는 0.359 초 걸 립 니 다!같은 결과,우리 가 만 든 것 은 작은 문자열 을 먼저 조립 한 다음 에 더 큰 문자열 로 조립 하 는 것 이다.이 방법 은 문자열 을 조합 한 후기 에 메모리 복사 데 이 터 를 효과적으로 줄 일 수 있다.이 원 리 를 알 게 된 후에 우 리 는 위의 코드 를 한층 더 분해 한 후에 테스트 를 진행 할 수 있다.아래 코드 는 0.140 초 밖 에 걸 리 지 않 습 니 다
 
/* 3 - : 0.140 */
var str = "";
for (var i1 = 0; i1 < 5; i1++) {
var str1 = "";
for (var i2 = 0; i2 < 10; i2++) {
var str2 = "";
for (var i3 = 0; i3 < 10; i3++) {
var str3 = "";
for (var i4 = 0; i4 < 10; i4++) {
var str4 = "";
for (var i5 = 0; i5 < 10; i5++) {
str4 += "xxxxxx";
}
str3 += str4;
}
str2 += str3;
}
str1 += str2;
}
str += str1;
}
하지만 위의 이런 방법 이 가장 좋 은 것 은 아 닐 수도 있 습 니 다!만약 우리 가 제출 해 야 할 정보 가 XML 형식 이 라면(사실 절대 다수의 경우,우 리 는 제출 할 정 보 를 XML 형식 으로 조립 할 수 있다),우 리 는 더욱 효율 적 이 고 우아 한 방법 을 찾 을 수 있다.DOM 대상 을 이용 하여 문자열 을 조립 할 수 있다.다음 단계 에서 950015 길이 의 문자열 을 조립 하 는 데 0.890 초 밖 에 걸 리 지 않 습 니 다
 
/* DOM - : 0.890 */
var xmlDoc;
if (browserType == BROWSER_IE) {
xmlDoc = new ActiveXObject("Msxml.DOMDocument");
}
else {
xmlDoc = document.createElement("DOM");
}
var root = xmlDoc.createElement("root");
for (var i = 0; i < 50000; i++) {
var node = xmlDoc.createElement("data");
if (browserType == BROWSER_IE) {
node.text = "xxxxxx";
}
else {
node.innerText = "xxxxxx";
}
root.appendChild(node);
}
xmlDoc.appendChild(root);
var str;
if (browserType == BROWSER_IE) {
str = xmlDoc.xml;
}
else {
str = xmlDoc.innerHTML;
}
DOM 대상 의 메모리 유출 을 피 하 는 것 은 IE 에서 DOM 대상 의 메모리 유출 은 개발 자 들 이 무시 하 는 문제 이다.그러나 그것 이 가 져 온 결 과 는 매우 심각 하 다!이 는 IE 의 메모리 사용량 이 지속 적 으로 증가 하고 브 라 우 저의 전체 운행 속도 가 현저히 떨어진다.일부 유출 이 심 한 웹 페이지 에 대해 서 는 몇 번 만 새로 고침 하면 운행 속도 가 배로 떨어진다.비교적 흔히 볼 수 있 는 메모리 누 출 모델 은'순환 참조 모델','폐쇄 함수 모델'과'DOM 삽입 순서 모델'이 있 는데 앞의 두 가지 누 출 모델 에 대해 우 리 는 웹 페이지 분석 시 인용 을 해제 하 는 방식 으로 피 할 수 있다.한편,'DOM 삽입 순서 모델'에 대해 서 는 기 존의 프로 그래 밍 습관 을 바 꾸 는 방식 으로 피해 야 한다.메모리 누 출 모델 에 대한 더 많은 소 개 는 Google 을 통 해 빠르게 찾 아 볼 수 있 으 며 본 고 는 너무 많은 설명 을 하지 않 습 니 다.단,여기 서 웹 메모리 유출 을 찾 고 분석 할 수 있 는 작은 도 구 를 추천 합 니 다.Drip,현재 의 새로운 버 전 은 0.5 입 니 다.다운로드 주 소 는?http://outofhanwell.com/ieleak/index.php。 복잡 한 페이지 의 세그먼트 로 딩 과 초기 화 는 시스템 에서 확실히 복잡 하고 IFrame 의 인터페이스 를 사용 하기 불편 하 므 로 세그먼트 로 딩 을 실시 할 수 있 습 니 다.예 를 들 어 여러 페이지 탭 의 인터페이스 에 대해 우 리 는 먼저 여러 페이지 탭 의 기본 페이지 를 다운로드 하고 초기 화 한 다음 에 AJAH(asynchronous JavaScript and HTML)기술 을 이용 하여 다른 탭 의 내용 을 비동기 적 으로 불 러 올 수 있다.이렇게 하면 인터페이스 가 가장 먼저 사용자 에 게 보 여줄 수 있다 는 것 을 보증 할 수 있다.전체 복잡 한 인터페이스의 적재 과정 을 사용자 의 조작 과정 에 분산 시키다.GZIP 을 이용 하여 네트워크 트 래 픽 을 압축 하 는 것 은 위 에서 언급 한 이러한 코드 급 의 개량 을 제외 하고 우 리 는 GZIP 을 이용 하여 네트워크 트 래 픽 을 효과적으로 낮 출 수 있다.현재 흔히 볼 수 있 는 주류 브 라 우 저 는 GZIP 알고리즘 을 모두 지원 합 니 다.우 리 는 소량의 코드 만 작성 하면 GZIP 을 지원 할 수 있 습 니 다.예 를 들 어 J2EE 에서 우 리 는 Filter 에서 아래 코드 를 통 해 클 라 이언 트 브 라 우 저가 GZIP 알고리즘 을 지원 하 는 지 판단 한 다음 에 필요 에 따라 java.util.zip.GZIPOutputStream 을 이용 하여 GZIP 의 출력 을 실현 할 수 있다
 
/* GZIP */
private static String getGZIPEncoding(HttpServletRequest request) {
String acceptEncoding = request.getHeader("Accept-Encoding");
if (acceptEncoding == null) return null;
acceptEncoding = acceptEncoding.toLowerCase();
if (acceptEncoding.indexOf("x-gzip") >= 0) return "x-gzip";
if (acceptEncoding.indexOf("gzip") >= 0) return "gzip";
return null;
}
일반적으로 GZIP 은 HTML,JSP 에 대한 압축 비 는 80%에 달 할 수 있 고 이 로 인해 발생 하 는 서버 와 클 라 이언 트 의 성능 손실 은 거의 무시 할 수 있다.다른 요 소 를 결합 하여 GZIP 을 지원 하 는 사 이 트 는 우리 에 게 인터넷 트 래 픽 의 50%를 절약 할 수 있다.따라서 GZIP 의 사용 은 네트워크 환경 이 특별히 좋 지 않 은 응용 에 현저 한 성능 향상 을 가 져 다 줄 수 있다.Http 의 감시 도구 인 Fiddler 를 사용 하면 웹 페이지 가 GZIP 을 사용 한 전후의 통신 데 이 터 량 을 편리 하 게 감지 할 수 있 습 니 다.(Fiddler 의 다운로드 주 소 는?http://www.fiddlertool.com/fiddler/)웹 응용의 성능 최적화 에 관 한 것 은 사실 매우 큰 화제 이다.본 고 는 편폭 이 제한 되 어 있 기 때문에 그 중의 몇 가지 세부 사항 만 언급 할 수 있 을 뿐 이런 세부 적 인 최적화 방식 을 모두 에 게 전면적으로 보 여줄 수 없다.본 고 는 모두 가 웹 응용,특히 클 라 이언 트 성능 최적화 에 대한 충분 한 중 시 를 불 러 일 으 킬 수 있 기 를 기대한다.서버 프로 그래 밍 기술 은 이미 여러 해 동안 잘 알려 져 있 기 때문에 서버 에서 성능 을 발굴 하 는 잠재력 은 이미 크 지 않다.클 라 이언 트 의 방법 개선 은 놀 라 운 성능 향상 을 얻 을 수 있다.

좋은 웹페이지 즐겨찾기