Steve Souders씨가 Velocity 컨퍼런스에 대한 글을 쓰셨습니다. 자신이 좋아하는 컨텐트들을 링크하셨다고 하네요.
from Velocity Conference Videos and Slides
Posted by 행복한고니 트랙백 0 : 댓글 0
Sam Allen씨가 시간의 흐름에 따른 브라우저 성능을 측정했습니다. Sam씨는 브라우저 메모리 프로파일을 만들고 결론을 도출했습니다:
이 프로파일들은 유명 브라우저들의 시간에 따른 메모리 동작 상태를 의미합니다. 절대적인 벤치마크 시간을 제공하지는 않습니다. Firefox 3.0은 메모리 관리가 꽤 괜찮았던 Firefox 2보다 메모리 사용량이 확실히 줄어들었습니다. 아래는 결과 요약입니다.

  • Safari 3.1
    Windows용 Safari는 매우 안좋은 메모리 관리를 보여주었습니다.
  • Firefox 3.0
    이 브라우저는 메모리 사용량이 다른 브라우저에 비해서 꽤 적었습니다. 메모리를 시스템에 잘 반환했으며, 전체적인 그래프 선은 거의 평평했습니다(여기서 밝힌 노력 덕분이 아닌가 싶습니다).
  • Flock (Firefox 2.0 기반)
    Flock은 꽤 좋습니다. 이 브라우저와 Firefox 2.0은 많은 문제를 일으키지 않고 장시간 실행되었습니다. 확장기능이 효율성을 다소 떨어뜨릴 수는 있습니다.
  • Opera 9.5
    Opera의 성능은 Firefox 2.0(Flock)만큼 좋습니다. 그리고 굉장히 긴 세션을 사용하는 것 같았습니다.
  • Internet Explorer 8 Beta 1
    IE도 프로파일에서는 꽤 잘해주었습니다. 비록 데이터의 추세가 증가세에 있어 걱정스럽기는 하지만 말입니다. 하지만, 이 브라우저는 보통의 사용량에서 몇 시간 동안 잘 버텨주었습니다.
사용자 삽입 이미지

from Browser Memory Footprints; Watching with real usage
Posted by 행복한고니 트랙백 0 : 댓글 0

Ernest씨가 Canvas를 이용한 사진 콜라주 이후 다시 Canvas를 이용한 폴리곤 렌더링 성능을 다른 기술들과 비교해 테스트했습니다.

데모를 통해 직접 테스트를 실행해보시거나 저장된 테스트를 볼 수도 있습니다. 이 테스트는 IE에서는 VML, Firefox에서는 SVG, Safari와 리눅스용 Firefox에서는 이미지를 사용하는 Google Maps 인터페이스를 통해 이루어졌습니다.

사용자 삽입 이미지
우선 결과는 놀라웠습니다. Canvas 버전이 두드러지게 빨랐습니다. 하지만, 실제 서비스되는 Google Maps 버전은 사실 폴리곤만 그리는 것보다는 더 많은 처리를 합니다.

우리가 마크업만의 렌더링 시간을 분석한다면, SVG와 VML이 canvas와 canvas+excanvas.js보다 반드시 느린 것은 아닙니다. 성능의 차이는 마크업이 출력되기 전 폴리곤의 구현이 원인입니다.

그것이 실험을 가치없게 만들지는 않습니다. 여러분은 SVG나 VML보다 Canvas보다 빠른 것을 보일 수는 없습니다. 하지만 보다 직접적인 방식을 이용함으로써 현재의 API보다 더 나은 폴리곤 성능을 얻는 가능성을 보여줄 수 있습니다. 렌더링 엔진에 상관없이 사람들은 항상 더 빠른 폴리곤을 원합니다.

from Rendering performance in Canvas compared to SVG and VML
Posted by 행복한고니 트랙백 0 : 댓글 0
Eric Falcao씨가 클라이언트에서 Rails 성능을 간단하게 측정하는 Clientperf를 발표하셨습니다.
측정하는 방법은 페이지 시작과 끝에 자바스크립트를 삽입합니다. 브라우저에서 다운로드, 실행, 렌더링까지 마치고 나면, clientperf는 서버로 보내는 마지막 이미지 요청을 전송합니다. 그 뒤는 식은 죽 먹기죠.
사용자 삽입 이미지

from Clientperf: Simple Client-Side Rails Performance
Posted by 행복한고니 트랙백 0 : 댓글 0

YSlow, Firefox3 지원

2008.07.10 03:19 from [IT] Web Tech
YSlow가 새 버전에서 Firefox3를 지원합니다.

새 버전의 기능:
  • Firefox 3와 Firebug 1.2 베타 지원
  • 자바스크립트 최소화 개선 및 단순한 체크
  • 인라인과 외부 CSS 혹은 JS의 색을 다르게 표시
  • 컴포넌트 범례의 색상과 표시부 개선
  • 동일한 호스트이름을 가지고 포트만 다른 사이트들을 분리된 DNS lookup으로 세던 버그 수정
  • 자잘한 버그와 스타일 개선
from YSlow now has Firefox 3 support
Posted by 행복한고니 트랙백 0 : 댓글 0
6월 23일에 Velocity 퍼포먼스 컨퍼런스가 있었습니다. 거기서 Bill Scott씨가 Jiffy라는 새로운 Firebug 플러그인을 발표하셨습니다. 이 플러그인은 새 탭에 자세한 성능 측정 데이터를 보여줍니다.
사용자 삽입 이미지

Bill씨는 또한 이 툴을 사용하여 사용자 경험 성능을 측정하는 방법에 대해 상세한 포스팅을 하신 적이 있습니다.

from Jiffy Firebug Plugin: Fine grained calculation of performance timings
Posted by 행복한고니 트랙백 0 : 댓글 0
Pageflakes.com의 Omar AL Zabir씨가 ensure에 대해 포스팅했습니다. ensure는 그가 작성한 JavaScript 라이브러리로, JavaScript, HTML, CSS를 요청하고 그 후 코드를 실행하게 할 수 있는 간편한 함수를 제공합니다.

Ensure는 특정 코드에 의존적인 어떠한 코드를 실행하고자 할 때 관련된 JavaScript와 HTML 코드 조각이 브라우저에 이미 브라우저 DOM 에 로딩되어 있을 것임을 보증해줍니다.

예제입니다:
[code:js]
ensure( { js: "Some.js" }, function() {
    SomeJS(); // The function SomeJS is available in Some.js only
});
또한 여러개의 JavaScript, html, CSS 파일을 지정할 수 있습니다.
[code:js]
ensure( { js: ["blockUI.js","popup.js"], html: ["popup.html", "blockUI.html"], css: ["blockUI.css", "popup.css"] }, function() {
    BlockUI.show();
    PopupManager.show();
});
Omar씨의 말씀입니다:
풍부한 클라이언트측 효과(애니메이션, 검증, 메뉴, 팝업)를 가진 웹 사이트와 Ajax 웹사이트는 같은 페이지에서 브라우저가 전달하는 큰 용량의 JavaScript, HTML, CSS가 필요합니다. 그러므로 풍부한 웹페이지의 초기 로딩 시간은 필요한 컴포넌트를 다운로드하는 시간만큼 명백히 계속 증가하고 있습니다. 게다가, 모든 가능한 컴포넌트를 전송하는 것은 페이지를 무겁게 하고 액션에 대한 브라우저의 응답을 둔하게 합니다. 때때로 풀다운 메뉴가 걸려있거나 팝업이 천천히 나타나거나 윈도우 스크롤이 둔하거나 하는 등의 것을 본 적이 있으실 겁니다.

해결책은 모든 가능한 HTML, JavaScript, CSS를 초기에 모두 전송하는 대신 필요할 때만 읽어들이는 것입니다. 예를 들어, 사용자가 메뉴바에 마우스를 올리면, 풀다운 메뉴 내부에 나타날 메뉴 HTML 뿐만 아니라 풀다운 메뉴 효과에 필요한 JavaScript 와 CSS도 다운로드하는 것입니다. 비슷하게 클라이언트측 검증(validation)이라면, 사용자가 "전송(submit)" 버튼을 클릭할 때, 클라이언트 검증 라이브러리와 관련된 경고 HTML 코드와 CSS를 전송하는 것입니다. 요청이 오면 페이지를 보여주는 Ajax 사이트라면, 사용자가 Ajax 호출을 할 경우에만 Ajax 라이브러리를 읽어들이는 것입니다. 즉, 복잡한 페이지의 전체 HTML, CSS, JavaScript를 작은 조각으로 나누는 것으로 초기 전송량을 확실히 줄일 수 있습니다. 그러므로 초기 페이지는 정말 빨라지고 여러분에게 빠르고 부드러운 브라우징 경험을 제공합니다.
동작 방법에 대해서 자세하게 작성된 글도 있습니다. 이는 또한 리소스를 다운로드 할 때에 대한 최근의 성능 제안과 관련이 있습니다(때때로 요청시에 로딩하느라 기다리는 것을 원하지 않을 수도 있습니다).

from ensure: on demand resources
Posted by 행복한고니 트랙백 0 : 댓글 0
사용자 삽입 이미지
Tom Trenka 씨가 문자열 성능에 관한 그의 최근 글IE에 관해 더 깊이 탐구Array.join의 신화를 무너뜨리는 글을 썼습니다.

Tom씨는 여러 버전의 IE와 다양한 크기의 데이터를 사용해 수많은 테스트를 했습니다.

결론
IE7에서는 성능 개선을 위해 우선 해야할 것으로, 우리는 더이상 대규모 문자열 연산을 다룰 때의 대체 방안 사용에 대해 고려할 필요가 없습니다; 대체 상황에서 Array.join을 사용하는 것은 같은 상황에서 += 를 사용하는 것에 비해 두드러진 이득을 주지는 못합니다. 게다가 IE6에서의 차이는 특정 버전을 위해 따로 코드를 작성하지 않아도 될만큼 미미한 것입니다.

이러한 종류의 연산에서 문자열 대신 배열 사용을 고려해야할 유일한 때는 추가할 조각들이 매우 크다고(65546 bytes 이상) 느껴질 경우입니다; 이런 일을 하는 것은 Dan Pupius씨가 객체 할당과 JScript 가비지 컬렉터에 대한 그의 분석에서 말한 바와 같은 GC 문제를 초래합니다.

그로부터, 우리는 Internet Explorer에서의 프로그래밍 기술을 발전시킬 수 있었고, 단순한 반복과 한번에 한 곳에 밀어넣는 일보다는 가능한 많은 인자를 가진 Builder.append라 부르는게 더 나을 것 같습니다.

또한 작게 시작하는 것이 좋습니다; 문자열 연산을 구조화 하세요 그러면 대규모 문자열 연산은 최소화 될 것입니다. 이 경우에, 문자열 세트를 조립하기 위해 임시 버퍼를 사용하고 이들을 보다 매우 큰 문자열에 덧붙이는 것이 작은 조각들을 늘 큰 문자열에 붙이는 것보다 더 좋습니다.

그리고 늘 그렇듯이, 반복 규모의 최소화는 JScript의 성능을 향상시키는데 도움이 될 것입니다.


더 자세한 결과를 살펴보실 수도 있습니다.

from String Performance in IE: Array.join vs += continued
Posted by 행복한고니 트랙백 0 : 댓글 0
최근의 글 "겸손한 Script를 통한 게으른 로딩 기능"은 HEAD 태그에 script 엘리먼트를 추가함으로써 JavaScript 스크립트 파일을 게으르게 로딩하는 법을 논의했습니다.

제대로 동작하기는 하지만, 이미 읽은 스크립트를 다시 읽는 것을 방지하기위해 읽힌 스크립트를 추적하는 것도 고려해야하고, 함수를 호출하기 전에 의존성있는 스크립트가 다 읽혔는지 보증해줄 방법으로 콜백을 지원하는 것도 중요합니다.
[code:js]
/**
*  Script lazy loader 0.5
*  Copyright (c) 2008 Bob Matsuoka
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*/
 
var LazyLoader = {}; //namespace
LazyLoader.timer = {};  // contains timers for scripts
LazyLoader.scripts = [];  // contains called script references
LazyLoader.load = function(url, callback) {
        // handle object or path
        var classname = null;
        var properties = null;
        try {
                // make sure we only load once
                if ($A(LazyLoader.scripts).indexOf(url) == -1) {
                        // note that we loaded already
                        LazyLoader.scripts.push(url);
                        var script = document.createElement("script");
                        script.src = url;
                        script.type = "text/javascript";
                        $$("head")[0].appendChild(script);  // add script tag to head element
                      
                        // was a callback requested
                        if (callback) {   
                                // test for onreadystatechange to trigger callback
                                script.onreadystatechange = function () {
                                        if (script.readyState == 'loaded' || script.readyState == 'complete') {
                                                callback();
                                        }
                                }                           
                                // test for onload to trigger callback
                                script.onload = function () {
                                        callback();
                                        return;
                                }
                                // safari doesn't support either onload or readystate, create a timer
                                // only way to do this in safari
                                if ((Prototype.Browser.WebKit && !navigator.userAgent.match(/Version\/3/)) || Prototype.Browser.Opera) { // sniff
                                        LazyLoader.timer[url] = setInterval(function() {
                                                if (/loaded|complete/.test(document.readyState)) {
                                                        clearInterval(LazyLoader.timer[url]);
                                                        callback(); // call the callback handler
                                                }
                                        }, 10);
                                }
                        }
                } else {
                        if (callback) { callback(); }
                }
        } catch (e) {
                alert(e);
        }
}
전체 소스와 예제 프로젝트 다운로드

읽힌 스크립트 추적
게으른 로더는 보통 실행할 특정 스크립트를 위해 필요한 스크립트를 지정하는 "require" 형태의 함수를 사용합니다. 라이브러리 스크립트들이 종종 한 개 이상의 script에 의해 호출되기 때문에, 저는 불필요한 리로딩을 방지하기 위해 페이지에서 어떤 스크립트가 이미 읽혔는지 추적하는 기능을 제 게으른 로더에 넣는 것이 중요하다고 생각했습니다.

이 예제에서, 저는 LazyLoader.script 배열을 만들었습니다. 각각의 스크립트가 호출되면서 이 스크립트의 src는 이미 읽힌 스크립트의 배열에 있는지 테스트되고, 만약 존재한다면 리로드하지 않고 콜백을 실행합니다. 이는 어떤 스크립트라도 필요할 때마다 손실없이 호출할 수 있도록 해줍니다.

콜백 지원
더 중요한 추가사항은 콜백의 지원입니다. 제 경험상, 콜백이 로딩 프로세스에 묶여있지 않는 한 사용할 수 있는 상태에 있는 스크립트를 보장해주는 것은 이만한 게 없습니다. 안타깝게도 대부분의 브라우저들은 onload 이벤트를 조금씩 다른 방식으로 다룹니다. 제가 제공하는 예제는 Firefox, Safari, IE에서 동작합니다.

콜백 지원의 가장 기본적인 로직은 클로져가 게으른 로더에 전달되는 것입니다. 그러면 함수는 script가 로딩되면서 발생하는 이벤트에 묶입니다. FF와 Safari 3는 "onload" 이벤트를 지원합니다. IE는 onreadystatechange 이벤트를 제공하며, state가 'loaded'나 'complete' 상태인지 체크하는 부분이 더 필요합니다('loaded', 'complete' 는 캐시 여부에 따름).

Safari2와 Opera에서의 콜백 지원은 "onload"나 "onreadystatechange"와 같은 script  이벤트를 지원하지 않기때문에 요령이 필요합니다. 이들 브라우저에는, document.readyState가 "loaded"인지 "complete"인지 체크할 간격이 매우 짧은 스크립트가 필요합니다. 준비가 되고 나면, 반복 스크립트를 중단하고 콜백을 실행합니다(저는 각각의 script를 따로 체크했습니다만, 우리가 체크하는 것이 개별  script가 아니라 document객체라 개별 체크가 꼭 필요한 것인지는 잘 모르겠습니다).

로더 호출
로더 호출은 간단합니다. 이 구현물은 네임스페이스를 사용한 정적 함수입니다. 콜백이 없는 예제를 보시죠:
[code:js]
LazyLoader.load('js/myscript1.js');
아래는 콜백이 있는 예제입니다.
[code:js]
LazyLoader.load('js/myscript2.js', function(){
    var myobj = new MyObject('myobj');
});
두번째 예제에서, MyObject의 "myobj" 인스턴스는 js/myscript.2js가 로딩된 뒤에 생성됩니다. 콜백 함수를 이용해서 연쇄 로더를 만들 수도 있습니다.

결론
저는 근 1년간 이 기술을 사용해오면서 좋을 결과를 얻었습니다. 우리는 같은 "레이아웃" 을 공유하는 특정 페이지들에서만 필요한 객체와 함수들의 매우 거대한 라이브러리를 사용합니다. 이 기술은 우리에게 적합하고 분명한 스크립트만 호출하도록 해줍니다(HEAD 태그에서. 페이지의 body에 script 참조를 포함하는 것과 대조적입니다). 우리는 이 함수를 스크립트의 의존성이 명확한 "require" 함수를 동시에 호출할 때도 사용할 수 있습니다.

스크립트 로더는 또한 폼 기반 스크립트를 동시에 로딩할 때에도 매우 잘 동작합니다. 서버 사이드 변수에서 만큼이나 스크립트 객체를 참조하고 HTML 폼을 바인딩하는데 이 기술을 사용합니다. 여기에 대해서는 나중에 다루도록 하겠습니다.

from A Technique For Lazy Script Loading
Posted by 행복한고니 트랙백 0 : 댓글 0
"innerHTML 이 DOM보다 35배 빠르다."

"DOM 메소드는 !"

항상 있는 논쟁이지만, 뒷받침할만한 통계치를 찾기는 힘듭니다.

Backbase의 Laurens Holst 씨가 벤치마크를 작성해서 이 문제에 대해 상세히 살펴보았습니다.
사람들은 innerHTML 사용에 대한 논쟁으로, 위의 글을 인용하며 성능에 대해 말하고 있습니다. 저는 그가 발견한 것과 제가 발견한 것의 차이가 나는 원인이 무엇인지 살펴봐야겠다고 생각했습니다. 제가 앞으로 지적하겠지만 그 벤치마크는 innerHTML에 호의적으로 매우 많이 편향된 결함이 있다는 것이 밝혀졌습니다.
  1. 컨텐트를 전혀 escape 처리하지 않았다
  2. 선택적인 HTML 사용
  3. XML이 HTML 보다 훨씬 빠르다
그는 다시 새 브라우저를 이용해서 벤치마크를 실행하고, 아래와 같은 결과를 얻었습니다.
사용자 삽입 이미지


from JavaScript HTML Construction Benchmark on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0
사용자 삽입 이미지
SquirrelFish는 예전에 포스팅한 적이 있는 새로운 WebKit의 JavaScript 엔진입니다. 그리고 이 녀석에 대한 공식 발표가 나왔습니다.

SquirrelFish에 대한 설명(아예 컴파일러와 엔진에 대한 약간은 low-level의 이야기입니다)을 하고 있으며, M. Anton Ertl 교수와 David Gregg 교수 등과 Lua 프로그래밍 언어의 개발자들이 연구한 효율적인 가상 머신 분야에 대한 최근 연구를 설계에 많이 반영했다고 합니다.

또한 왜 그렇게 빨라질 수 있었는지에 대한 상세 설명도 곁들여졌는데, 컴파일러에 관심있으신 분이라면 한번 읽어볼만할 것 같습니다.

끝으로 이것은 단지 시작을 뿐이라며 앞으로 더 빨라질 것이라고 하는군요.
사용자 삽입 이미지

from SquirrelFish: Details on the new on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0
사용자 삽입 이미지
워드프레스 팀에서 어마어마한 작업을 하고 있다고 합니다. 이미 꽤 진행이 된 것 같은데, Google Gears를 이용해서 워드프레스가 오프라인에서도 동작하도록 하고 있답니다.

James 씨의 글에 따르면 이와 같은 Gears 지원이 몇몇 기쁜 선물을 가져다 줄 것이라고 합니다. 예를 들면, 남아프리카처럼 속도가 좋지 않은 곳에서는 상당한 속도 향상 효과를 볼 수 있다는 것이 그의 주장입니다(우리나라 상황과는 별 상관없겠네요.. 남아프리카라니...).

Dion씨는 이 같은 움직임에 대해서 Gears팀을 자랑스러워하는 한편, Gears가 오프라인만이 아닌 그 이상이라고 말했습니다. Gears는 웹 개발 모델의 간극을 채우기 위해 노력 중이고, HTML5 기능을 브라우저에서 사용할 수 있도록 하고 있다고 합니다. 그 외에도 재밌는 요소는 많죠. 내장 데이터베이스, 로컬 서버 스토리지, 데스크톱 API 등등.

뭐... 여하튼 재밌는 소식이네요. 국내에선 어디서 가장 먼저 Gears를 도입하게 될지 기대됩니다.

from Speed Up! with Wordpress and Gears on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0
WebKit에 SquirrelFish 라는 코드네임을 사용하는 새로운 JavaScript 엔진이 생겼습니다.

성능 벤치마크를 보면 여러 테스트에서 눈에 띄게 향상된 것을 보실 수 있습니다.

테스트 결과에 의하면 평균적으로 4배 정도의 개선이 이루어졌으며(Safari 3.1과 비교), 몇몇 접근 테스트에서 12.6x 배의 최고치를, 문자열 해제부분에서 1.63x의 최저치를 기록했습니다.

브라우저들의 성능이 개선되고 있다는 얘기가 속속 들려오니 관련업에 종사하는 사람으로 기분이 좋네요(이제 IE6는 버려주셨으면... T^T)

from SquirrelFish: WebKit has a new, fast, JavaScript engine on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 4
Sean Christmann씨가 HTML, Flex, Silverlight, Swing, 그 밖에 포팅이 가능한 다른 것들을 벤치마킹할 수 있는GUIMark소개했습니다.

Sean씨는 Bubblemark를 보고, 다른 방식의 벤치마크를 생각하셨습니다. UI 엘리먼트를 주로 벤치마킹 했다고 하는데요, 벡터 재묘사, 알파 투명, 텍스트 재배치, 비트맵 모션 등이 이에 포함됩니다. 이 벤치마크에 대한 좀 더 저수준의 기술적인 내용, 렌더링 엔진의 동작 방식, 도 보실 수 있습니다.

물론, 실제로 동작하는 HTML 버전을 실행해보실 수도 있습니다.

결과가 조금 이상한데, Mac OS X와 Windows사이에 너무 큰 차이가 납니다. Ajax 응용프로그램에서는 Mac이 우세하네요! (근데 결론을 읽으면 이래저래 Windows가 훨씬 더 우세했다고 전하고 있습니다. 특히 Flash의 렌더링 속도에서 깜짝 놀랐다고 하는군요).

from GUIMark: Another Web application benchmark on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0

Andrea Giammarchi씨가 크로스 브라우징을 지원하는 네이티브 array wrapper를 작성했습니다:

올해에 몇번이나 JavaScript Ninja들이 성능 손실이 없으면서도 강력한 메소드를 가진 라이브러리를 만들기 위해 네이티브 Array의 확장을 시도했었는지 모르겠습니다. 제가 마침내 Internet Explorer 8에서 크기 잠금을 제거하고 모든 다른 브라우저에서의 문제점을 해결할 방법을 찾아냈습니다.

그가 완성한 Stack 클래스입니다:

[code:js]
/**
* Choose a name for subclassed Array
*/
Stack = (function(){ // (C) Andrea Giammarchi - Mit Style License

    /**
     * Your personal Array constructor
     */
    function Stack(length){
        if(arguments.length === 1 && typeof length === "number")
            this.length = -1 <length && length === length <<1>> 1 ? length : this.push(length);
        else if(arguments.length)
            this.push.apply(this, arguments);
    };

    // Solution 1:
    //      Declaration of generic function
    //      with an array as prototype
    function Array(){};
    Array.prototype = [];

    // Solution 2:
    //      use the prototype chain to inherit
    //      Array constructor and its native prototype
    Stack.prototype = new Array;

    // Solution 3:
    //      overwrite inherited length with zero value
    Stack.prototype.length = 0;

    // Solution 4:
    //      redeclare toString method in this way
    //      to let JScript core feel better
    Stack.prototype.toString = function(){
        return  this.slice(0).toString();
    };

    /**
     * Return and assign subclassed Array
     */
    Stack.prototype.constructor = Stack;
    return  Stack;

})();

from Stack : A native Array wrapper that works on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0
사용자 삽입 이미지

David Mandelin씨가 Tracehydra에 대한 글을 썼습니다. Tracehydra는 Spidermonkey의 JS 파서와 Tamarin Tracing VM을 연결해주는 방법에 대한 아이디어입니다(아직 구현된 것은 아니라는 거죠). 그렇게 함으로써 어떤 "이점(Profit)"을 얻게된다고 하는데, 이 경우의 "이점"은 "JavaScript를 아주 빠르게 실행"할 수 있다는 것입니다.

아시다시피 Spidermonkey는 현재 사용되고 있는 JS 파서이고, Tamaring은 어도비에서 ActionScript VM 코드를 기증함으로써 성능이 비약적으로 향상될 것이라 기대되고 있는 새로운 JS 엔진입니다.

Tracehydra가 하는 일은 정확히는 Spidermonkey의 bytecode를 Tamarin IL(IL은 바이트코드와 약간 비슷한 개념의 내부적으로 변환된 매개 언어라고 보시면 됩니다)로 변환해줌으로써 Tamarin Tracing VM에서 이를 사용할 수 있도록 한다는 것입니다. 그를 위해서 다음과 같은 간단한 ActionScript의 예를 들어, 코드→bytecode→IL 로의 변환에 대해 자세히 작성해두었습니다.

from Having a Tamarin trace a Spidermonkey on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0
Thierry Schellenbach씨가 자신의 Prototype 응용프로그램에서 console.profile() / console.profileEnd()를 실행해본 후에 Prototype 응용프로그램에서의 JavaScript 성능 향상팁에 대한 글을 작성했습니다.

요점은 단순합니다:
  • $$와 이벤트 바인딩에 주의할 것
  • 다른 Prototype 메소드에 주의할 것(innerHTML과 element.update() 간데는 40배나 차이가 난다는 보고가 있습니다)
  • document.createElement 대신 innerHTML 을 이용해서 작성할 것
  • for in 루프 대신 for 루프를 사용할 것
  • 문자열 합치기에 += 대신 Array.join 을 사용할 것[각주:1]
  • 변수와 함수를 캐시할 것
  • eval의 사용을 제한할 것
  • Try Catch 구문의 사용을 제한할 것
  • DOM을 다룰 때는 엘리먼트 밖에서 DOM을 변경하고 다시 집어넣을 것(DOM 안에서 변화시키면 브라우저가 그 때마다 화면을 다시 그리려고 시도해서 느려질 수 있습니다)
시간 같은 요소가 더 추가되어 성능 측정이 되면 좋을 것 같습니다. 반론을 기다린다고 하는군요 ;)

from Some more JavaScript performance tips on Ajaxian
  1. 사실 이 부분은 IE에만 해당하는 것 같습니다. IE가 스트링 버퍼를 제대로 다루지 못해서 += 를 계속할 때와 Array.join 을 사용할 때의 속도차이가 많이 나는 것입니다. 다른 브라우저에서는 반복되는 += 를 알아서 잘 최적화 해주기 때문에 크게 속도차가 나지 않습니다 [본문으로]
Posted by 행복한고니 트랙백 0 : 댓글 0

Steve Souders씨가 또 다른 통찰력있는 글을 작성했습니다. 초기 탑재량 분산 - 즉, 페이지나 응용프로그램을 처음 로딩하면서 읽어들이는 JavaScript의 분량을 분산하자는 글입니다.

Steve 씨는 우선 브라우저가 페이징을 렌더링하는 것에 JavaScript가 어떻게 영향을 끼치는지 간단히 설명했습니다:

Ajax와 DHTML의 사용이 늘어난다는 것은 오늘날의 웹 페이지들이 이전보다 더 많은 JavaScript를 지니고 있다는 것을 의미합니다. 미국의 상위 10개 웹 사이트들은 평균 252K의 JavaScript를 포함하고 있습니다(표1 참고). JavaScript는 페이지를 느리게 합니다. 브라우저가 JavaScript를 다운로드하거나 실행하려는 순간에는 다른 어떤 병렬 다운로드도 하지 않습니다. 또한, 외부 스크립트 아래쪽은 그 스크립트가 완전히 다운로드되어 실행되기 전까지 렌더링되지 않습니다. 외부 스크립트가 캐시된 경우라 하더라도 실행 시간은 여전히 사용자의 체감시간을 느리게 하고 점진적인 렌더링을 방해합니다.

그는 Alexa 상위 10개 사이트를 뽑아서 호출된 함수를 기준으로 onload 이벤트가 발생하기전에 실행되는 코드가 얼마나 많은지 조사했습니다. 결과는 아래와 같습니다:

표 1 미국 상위 10개 웹사이트의 JavaScript 사용 크기

표 1 미국 상위 10개 웹사이트의 JavaScript 사용 크기

이게 왜 문제인지 이해하기 쉬워졌습니다. 코드를 한 파일에 집어넣는 단순함과 (Steve씨가 반박한) 논란이 될만한 캐시 효과 체감과 같은 여러 요인들이 있습니다. Steve씨는 이렇게 했습니다:

큰 단위의 JavaScript를 나누는 것을 찾는 작업은 쉬운 일이 아니었습니다. Microsoft Research의 프로젝트인 Doloto는 이 작업을 자동화하려고 시도합니다. Doloto는 공개되어있진 않지만, 문서에서 그들 시스템에 대해 잘 설명하고 있습니다. (다가올 Velocity 컨퍼런스에서 Doloto에 대한 개발자의 이야기도 들을 수 있습니다)
Doloto가 취한 접근방식은 필요시에 추가적으로 JavaScript를 다운로드하는 스텁(stub) 함수들을 사용하는 것이었습니다. 이것은 사용자가 추가적인 코드가 필요한 어떤 행동을 했을 때 기다려야하는 결과를 초래할 것입니다. 페이지가 렌더링 된 이후에 바로 추가 JavaScript를 로딩하는 것이 더 빠르게 보일 것입니다.

from Split the Initial Payload; Why are we sending all JavaScript down in one go on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0

자식 선택자child selector는 "table td tr.className"과 같이 노드의 계층 구조를 포함하도록 작성된 CSS 선택자를 말합니다. 이러한 자식 선택자가 그냥 단순하게 클래스 이름만 쓰는 것보다 더 느릴까요?

Jim Barraud씨는 "느리다"라고 했는데, Jim 씨의 글을 읽은 Jon Sykes씨는 아무래도 이를 데이터로 증명해야 마음이 편했나봅니다.

그의 결론을 볼까요?

자식 선택자가 주요한 성능 문제라는 것은 확실합니다.

맞는 말이긴 하지만, 누군가 말한 그대로 믿기보다는 일종의 증명을 하고 싶었습니다. 그래서 지난 이틀간 이 문제를 재연하기 위한 두 가지 접근 방식을 시도해보았습니다.

첫번째는 벤치마킹으로서는 근본적인 문제가 있는 워낙 쓸모없는 아이디어였습니다.

그래서 저는 새로운 접근방식을 취했습니다. 이 방식은 몇몇 유효하고 꽤 흥미로운 결과를 반환하는 듯 보였습니다. 특히, Safari 와 Firefox 3와 관련해 이들이 자식 선택자와 성능에 어떻게 반응하는지에 대해서 말이죠.

테스트 결과는 IE6, IE7, Safari3 에서 직접적인 클래스 선언보다 자식 선택자를 사용하는 것이 느리다고 말합니다. Safari3가 자식 선택자에 가장 많은 영향을 받았습니다. Firefox는 약간의 영향을, 그리고 Firefox3는 전혀 영향을 받지 않는 것처럼 보였습니다.

이 실험은 매우 극단적입니다. 보통은 한 페이지에 20,000 개나 되는 클래스 선언을 정의하거나 그들 모두가 4단계의 자식 선택자일리는 없습니다.

사용자 삽입 이미지

(주 : child selector, child 셀렉터, 자식 셀렉터, 자식 선택자 등의 많은 명칭을 놓고 고민했습니다. 아직 널리 쓰이는 말이 없기에 이왕이면 우리말로 바꾸려는 노력이 필요하지 않을까 생각해서 자식 선택자라고 번역했습니다. 똑같은 의미의 '자식'을 의미하는 자식 노드라는 말이 이미 쓰이고 있기 때문에 그렇게 써도 괜찮지 않을까라고 생각해서 선택한 어휘입니다만 어색하기는 하네요 ^^a)

from CSS Child Selector Performance on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 4

사용자 삽입 이미지
Tom Trenka씨가 여러 브라우저에 걸쳐 JavaScript 성능 분석을 상세히 설명했습니다. 이는 매우 중요한 작업이며, 저에게는 사람들이 pool을 사용하려하고 새로운 VM 기술이 나타나면 어떤 것이 성능에 나쁜지 찾으려하던 JVM 시절을 떠올리게 합니다. 꼼수를 너무 많이 사용하면 새 버전이 꼼수가 아닌 일반적인 작업을 최적화함에 따라 결국엔 좋지않은 상태가 될 수도 있습니다.

Eugene Lazutkin씨가 언어의 문자열에 대해 아주 잘 설명해주셨습니다:

많은 현대 언어들(특히 함수형 언어들)은 메모리 보존memory conservation, 캐시 지역화cache localization 등의 많은 문제를 해결하는 "불변 객체immutable object" 패러다임을 도입했습니다. 아이디어는 간단합니다: 객체가 불변이라면, 그것은 레퍼런스(포인터나 핸들)에 의해 나타내지고, 레퍼런스를 전달하는 것은 객체를 값으로 전달하는 것과 동일합니다 — 객체가 불변이라면, 값은 변하지 않습니다 => 이 객체를 가리키는 포인터는 원래와 같은 값을 만들면서 레퍼런스를 해제합니다. 이것은 객체를 복제하지 않고 레퍼런스만 복제할 수 있다는 의미입니다. 그리고 그들 모두는 같은 객체를 가리킬 것입니다. 객체를 바꾸려면 뭘 해야할까요? 가장 유명한 해결책은 기록시 복사(Copy-on-write, 이하 COW)하는 것입니다. COW 원칙하에서, 우리는 객체에 대한 포인터(레퍼런스, 핸들)를 가지고, 그것이 가리키는 객체를 복사하고, 포인터의 값을 변경해 이제 포인터는 복사된 객체를 가리키게 되었습니다. 그리고, 우리의 변형 알고리듬을 진행했습니다. 여전히 다른 모든 레퍼런스는 동일합니다.

JavaScript는 문자열을 위한 모든 "불변 객체"를 수행하지만, 간단한 트릭을 사용하고 있어서 문자열의 COW는 수행하지 않습니다. 문자열을 수정할 방법은 없습니다. 모든 문자열은 언어 명세와 함께 나온 표준 라이브러리의 힘으로 불변성을 가지고 있습니다. 예를 들어, str.replace("a","b") 는 str 을 전혀 수정하지 않고, 치환되거나 그렇지 않은 다른 문자열을 반환합니다. 제가 추측한 패턴을 찾을 수 없다면 원래 문자열의 포인터를 반환합니다. 문자열의 모든 “변형“ 연산은 실제로는 원래의 문자열은 변경되지 않도록 남겨둔 채 새 객체를 반환합니다: replace, concat, slice, substr, split 그리고 조금 성격이 다른 anchor, big, bold 등등조차 그렇습니다.

Tom씨가 그가 진행한 부분에 대해 상세히 설명해주셨습니다:

  • Round 1: 네이티브 연산 측정.
  • Round 2: 버퍼링 기술의 유형 비교.
  • Round 3: dodox.string.Builder에 결과 적용.

몇가지 놀랄만한 것이 있는데, Tom씨가 정리했습니다:

  • 모든 브라우저의 네이티브 문자열 연산은 다른 언어로부터 차용한 기술들이 거의 필요없는 수준까지 최적화되었습니다.
  • Array.join 이 여전히 Internet Explorer에서는 가장 빠른 방법인 것 같습니다; += 이나 String.prototype.concat.apply(””, arguments) 는 다른 모든 브라우저에서는 가장 좋은 방법입니다.
  • Firefox는 dynamic/변수를 통해 인자의 멤버에 접근하는데 분명히 이슈가 있었습니다.

Erik Arvidsson씨가 push()를 사용하는 이유를 알려주셨습니다: IE6 and it’s really bad GC.

IE 8 / FF 3 에서의 결과도 기대하겠습니다.

from Everything you wanted to know about String performance on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0