GoogleがWeb全体のスピードアップにいよいよ本格的に着手, 一社だけではできないと強調
ãããªã³ã¯ã®ãã£ãã
http://code.google.com/intl/ja/speed/articles/optimizing-javascript.html
ãæ¥æ¬èªãã¨æã£ããæ¥æ¬èªãããªãã£ãã»ã»ã»ã»ã
ããã¼ãæå¤ã¨ã¨ãããæååã«ã¤ãã¦ã¯ãå ¨ç¶ç¥ãããã£ãã
Closureã£ã¦ä¾¿å©ã ãããããã俺ã£ã¦ä½¿ã£ã¦ãã¸ã£ã³ãã¿ãããªæ°ã«ãªããããã¤ãã¤ã使ã£ã¡ãããã ãã©ãé«ã³ã¹ããªã®ãã»ã»ã»ã»ãåçã
ã¨ãããã¨ã§ãè¶
é©å½ç¿»è¨³ãã©ã£ãã®èª°ããæ¸ãã¦ãããã
åãã
èè
: Google Chromeã®ã¨ã³ã¸ã㢠Gregory Baker, Software Engineer on GMail & Erik Arvidsson
æ¨å¥¨ãããçµé¨ï¼JavaScriptã®å®è·µçãªç¥è
ã¯ã©ã¤ã¢ã³ããµã¤ãã®ã¹ã¯ãªããã¯ãWebã¢ããªãåçã«ã§ãã¾ããããã®ãã©ã¦ã¶ã®å®è£
ã¯éå¹çã«ãªãããããããã©ã¼ãã³ã¹ã¯ã¯ã©ã¤ã¢ã³ãã«ãã£ã¦ç°ãã¾ããã¡ãã£ã¨ããJavaScriptã®å®è¡å¹çãä¸ããæ¹æ³ã«ã¤ãã¦è°è«ãã¾ãã
æååã«ã¤ãã¦
æååã®çµåã¯I.E6/7ã®ã¬ãã¼ã¸ã³ã¬ã¯ã·ã§ã³æã®ããã©ã¼ãã³ã¹å¤§ããªåé¡ãèµ·ããã¾ããI.E8ã¯ãã®åé¡ã«åãçµãã§ãã¾ããæååã®çµåã®åé¡ã¯ã¯IE8ã¨ä»ã®IE以å¤ã®(Chromeã¨ã)ã®ãã©ã¦ã¶ã§ã¯ãã¾ãå·®ã¯ãªããªãã¾ããã¨ãã£ã¦ãããã¾ã®å¤ãã®ã¦ã¼ã¶ã¼ãI.E6/7ã使ã£ã¦ãã¦ãããã¯æååãä½æããæã«ååæ°ãã¤ããå¿ è¦ãããã¨ãããã¨ã§ãã
ãµã³ãã«ã§ãã
var veryLongMessage = 'This is a long string that due to our strict line length limit of' + maxCharsPerLine + ' characters per line must be wrapped. ' + percentWhoDislike + '% of engineers dislike this rule. The line length limit is for ' + ' style purposes, but we don't want it to have a performance impact.' + ' So the question is how should we do the wrapping?';
ä¸è¨ã®æååçµåã®ä»£ããã«ãé åã®joinã使ã£ã¦ã¿ã¾ãããã
var veryLongMessage = ['This is a long string that due to our strict line length limit of', maxCharsPerLine, ' characters per line must be wrapped. ', percentWhoDislike, '% of engineers dislike this rule. The line length limit is for ', ' style purposes, but we don't want it to have a performance impact.', ' So the question is how should we do the wrapping?' ].join();
åæ§ã«ãã«ã¼ããifããªã©ã§æååçµåãè¡ãã®ã¯ãéå¹ç
ééã£ãä¾ï¼(éä¸ã«ã¼ãã§æååçµåãããã)
var fibonacciStr = 'First 20 Fibonacci Numbers'; for (var i = 0; i < 20; i++) { fibonacciStr += i + ' = ' + fibonacci(i) + ''; }
æ£ããä¾ï¼(é åã«pushãã¦ãã£ã¦ãæå¾ã«joinã§çµåããã)
var strBuilder = ['First 20 fibonacci numbers:']; for (var i = 0; i < 20; i++) { strBuilder.push(i, ' = ', fibonacci(i)); } var fibonacciStr = strBuilder.join('');
Helper Functionã§ä½æãããã¼ãã®çµæãç¨ãã¦æååãä½æããå ´å
ãã³ãã©ãªã«ä½¿ãããé·ãæååãæ ¼ç´ããå¤æ°ã使ãã®ãé¿ããããã«ãé åã¨ããããç¨ã«ä½æããé¢æ°ã§é·ãæååãä½æãã¾ãããã
ãã¨ãã°ãä¸è¨ã®buildMenuItemHtml_ã¨ããã¡ã½ããã¯ãçµåããããã®æååãããããã¨ä½ã£ã¦ããããã®ã¨ãã¦ãä¸ã®ããããã ã¨ãæååãçµåããããã«ãã®æååãå é¨çã«æã¤ã³ãã«ãªã£ã¦ãã¾ãã¾ããã¾ãã
var strBuilder = []; for (var i = 0; i < menuItems.length; i++) { strBuilder.push(this.buildMenuItemHtml_(menuItems[i])); } var menuHtml = strBuilder.join();
ããã
var strBuilder = []; for (var i = 0; i < menuItems.length; i++) { this.buildMenuItem_(menuItems[i], strBuilder); } var menuHtml = strBuilder.join();
ã£ã¦ãã¦ããã¨ãçµåã®ããã«ä½¿ãç¡é§ãªå
é¨çãªæååã¯å¿
è¦ããã¾ããã
ClassãMethodã®å®ç¾©
次ã®æ¹æ³ã¯ããããªãããæ¹ã§ããbaz.Barãnewãããã³ã«ãæ°ããé¢æ°ã¨ã¯ãã¼ã¸ã£ãfooã®å®ç¾©ã®ããã«ä½æããã¦ãã¾ãã¾ãã
baz.Bar = function() { // constructor body this.foo = function() { // method body }; }
好ã¾ããæ¹æ³ã¯ã
baz.Bar = function() { // constructor body }; baz.Bar.prototype.foo = function() { // method body };
ã¨ãã£ã¦ãprototypeã«fooãå®ç¾©ãã¦ãã¾ããã¨ã§ãã
ãã®æ¹æ³ã ã¨ãbaz.Barããããä½ã£ã¦ããã£ãä¸ã¤ã®fooãä½æãããã ãã§ããã¯ãã¼ã¸ã£ã«è³ã£ã¦ã¯ä¸ã¤ãä½ããã¾ããã
ã¤ã³ã¹ã¿ã³ã¹ã®ã¡ã³ãå¤æ°ã®åæåã«ã¤ãã¦
ã¤ã³ã¹ã¿ã³ã¹å¤æ°ã®å®£è¨ã¨åæåãprototypeã«ããã®å¤æ°ãæ°å¤ã ã£ããæååã ã£ããnullã ã£ããã®åãä¸ç·ã«ç½®ãã¦ããã¾ããã*1ãããã¯ã³ã³ã¹ãã©ã¯ã¿ãå¼ã°ããæ¯ã«å®è¡ãããã ããªåæåãé¿ãããã¨ã«ãªãã¾ãã
ã¨ãã£ã¦ããããã¯ãåæå¤ãnewããã¨ãã®å¼æ°ã«ä¾åããªãå ´åã«æå³ãããã¾ãã
ãã¨ãã°ã
foo.Bar = function() { this.prop1_ = 4; this.prop2_ = true; this.prop3_ = []; this.prop4_ = 'blah'; };
ã¨ãããããã
foo.Bar = function() { this.prop3_ = []; }; foo.Bar.prototype.prop1_ = 4; foo.Bar.prototype.prop2_ = true; foo.Bar.prototype.prop4_ = 'blah';
ã¨ãã¦ããã¾ãããã
ã¯ãã¼ã¸ã£ã«ã¯æ°ãä»ãã¦
ã¯ãã¼ã¸ã£ã¯å¼·åã§ä¾¿å©ãªJavaScriptã®æ©è½ã§ãããããã¤ãã®æ¬ ç¹ãããã¾ãã
- ã¡ã¢ãªãªã¼ã¯ã®æã大ããªåå
- ã¯ãã¼ã¸ã£ãä½ãã¨ã(ã¯ãã¼ã¸ã£ãæããªã)å é¨é¢æ°ãä½ãããé ããªãã¾ããããã¦ãStaticãªé¢æ°ã®åå©ç¨ã®æ¹ãããã©ã¼ãã³ã¹çã«ã¯ããªãå¾ã§ãã
ãã¨ãã°ã
static function. For example: function setupAlertTimeout() { var msg = 'Message to alert'; window.setTimeout(function() { alert(msg); }, 100); }
ã¯ã次ã®ã¹ã¯ãªããããé ãã§ãã
function setupAlertTimeout() { window.setTimeout(function() { var msg = 'Message to alert'; alert(msg); }, 100); }
ã¨ãã£ã¦ãããã®ã¹ã¯ãªããã¯æ¬¡ã®ã¹ã¯ãªããããé ãã§ãã
function alertMsg() { var msg = 'Message to alert'; alert(msg); } function setupAlertTimeout() { window.setTimeout(alertMsg, 100); }
å½ç¶ã§ãããã¯ãã¼ã¸ã£ã¯å¤æ°ã®ã¹ã³ã¼ãé åãé層åãã¾ãããã®é層åãããç·¨éé åããã©ã¦ã¶ã¯è§£éããã§ãã¯ããå¿ è¦ãããã¾ãã(ãããã³ã¹ããæããã®ã§ã)
ãã¨ãã°ã
var a = 'a'; function createFunctionWithClosure() { var b = 'b'; return function () { var c = 'c'; a; b; c; }; } var f = createFunctionWithClosure(); f();
fãã³ã¼ã«ãããæã«ãå¤æ°aã¯bããé ãã¨ããã«ãããbã¯cã®å¤æ°é åãããé ãã¨ããã«ããããã§ãã
I.Eã®ããã¼ããã«ã¤ãã¦ã®æ
å ±ã¯ãhttp://blogs.msdn.com/ie/archive/2007/01/04/ie-jscript-performance-recommendations-part-3-javascript-code-inefficiencies.aspx ãåèã«ãã¦ãã ããã
withã¯é¿ãã
ã³ã¼ãä¸ã«withã使ãã®ã¯ããã¾ããããããã¯ã¹ã³ã¼ãé åãå¤æ´ããã®ã§ãå
¨ä½ã®ããã©ã¼ãã³ã¹ã«è² è·ãããã¾ããä»ã®å¤æ°é åãè¦ã«è¡ãæã«é«ãã³ã¹ããæããåå ã«ãªãã¾ãã
ãã©ã¦ã¶ã®ã¡ã¢ãªãªã¼ã¯ãé¿ãã
Webã¢ããªã«ã¨ã£ã¦ãã©ã¦ã¶ã®ã¡ã¢ãªãªã¼ã¯ã¯å
±éããåé¡ã§ãããã©ã¼ãã³ã¹ã«å¤å¤§ãªå½±é¿ãä¸ãã¾ãããã©ã¦ã¶ã®ã¡ã¢ãªã®ä½¿ç¨éãå¢ãã¦ããã¨ãã¦ã¼ã¶ã¼ã®ãã½ã³ã³å
¨ä½ã®ã·ã¹ãã ãå«ãã¦ãã£ããã«ãªã£ã¦è¡ãã¾ãããã£ã¨ãããããã±ã¼ã¹ã¯ãC++ã«ãã£ã¦å®è£
ããããã©ã¦ã¶ã®DOMã¨JavaScriptã®DOMã®å¾ªç°åç
§ã«ãã£ã¦å¼ãèµ·ãããã¾ãã(e.g. between the JavaScript script engine and Internet Explorer's COM infrastructure, or between the JavaScript engine and Firefox XPCOM infrastructure).
Eventãã³ãã©ãä»ããéã«ã¯ãããç¨ã®Eventã·ã¹ãã ã使ãã¾ããã
ãããã循ç°åç §ã¯ããDOMè¦ç´ --> eventãã³ãã© --> ã¯ãã¼ã¸ã£ã®ã¹ã³ã¼ã --> DOMãå ¥ã£ã¦ã ãã¨ãããã¤ã§ããè¦ç´ ã«ã¤ãã¦ã¯ãここのMSDNのブログエントリã§è©³ããã§ãããã®åé¡ãé¿ããããã«ãããç¥ãããã¹ããããEventãã³ãã©ãä»ããEventã·ã¹ãã ã使ãã¾ãããããã¨ãã°ãGoogle doctypeãDojoãJQueryã§ãã
ä»ãå ããã¨ãã¤ã³ã©ã¤ã³ã§ä½ã£ãã¤ãã³ããã³ãã©(<input onclick=ã¿ãããª)ã¯ãI.Eã«ããã¦å¥ã®ã¿ã¤ãã®ãªã¼ã¯ãèµ·ããå¯è½æ§ãããã¾ããããã¯å¾ªç°åç
§ã§ã¯ãªããå
é¨ã®ãã³ãã©ãªã«ä½¿ç¨ãããå¿åã¹ã¯ãªãããªãã¸ã§ã¯ãã«ãããªã¼ã¯ã§ãã詳ããã¯ããã®ãI.Eのリークパターンについての理解と解決方法ã«ãããDOM Insertion Order Leak Modelããèªãã§ããã®JavaScript Kit tutorialã試ãã¦ã¿ã¦ãã ããã
Expandoããããã£ãé¿ãã
Expandoããããã£ã¨ããã®ã¯ãJavaScriptã«ãã£ã¦DOMã«ä»ããããèªç±ãªããããã£ã®ãã¨ã§ããDOMã«ãã¨ãã¨åå¨ããªãããããã£ãå ¨ãã¨ã©ã¼ãèµ·ãããã¨ãªãJavaScriptããä»ä¸ã§ãã¾ããããããããã循ç°åç §ã®åå ã«ãªãã¾ããExpandoããããã£ã¯ãé常ã¡ã¢ãªãªã¼ã¯ã¯èµ·ããã¾ãããããããå¶çºçã«ããã¦ç°¡åã«ãªã¼ã¯ãèµ·ããã¾ãã
ãã¿ã¼ã³ã¨ãã¦ã¯ãDOMè¦ç´ --> Expandoãããã㣠--> ä½ãåªä»ããObject --> DOMè¦ç´ ãã¨ããæãã§ãããããé¿ããæ¹æ³ã¯ãã使ããªããã¨ã«ã¤ãã¾ãããããã©ããã¦ãã¤ãããããªããããªããã£ããªã¿ã¤ãã®ãã®ã®ã¿ã使ãããã«ãã¦ãã ãããããªããã£ãã§ãªãå¤ã使ç¨ããå ´åã¯ããã®DOMãè¦ããªããªã£ããæ示çã«Expandoããããã£ãæ¶ããã¨ã§ãããI.Eのリークパターンについての理解と解決方法ã«ãããDOM Insertion Order Leak Modelãã®ãCircular Referencesãã«è©³ããã§ãã
*1:rather than refernceã£ã¦ä½ï¼