Низкоуровневая оптимизация JavaScript

Embed Size (px)

Citation preview

JavaScript

ecmascript

while(++a);

-/ label: inc eax jnz label

Global === window

_fn0

_fn1

_fnn

5742 310 52 Opera 10.52 10955 1917 644 firefox 3.6 ie 6410 3210 1200 chrome4 10198 78 59

(function(window) { var document = window.document, documentElement = document.documentElement ; })(window);

(function() { var cachedVar = 1, _cmp = function(a, b){ return a < b; }, _min = Math.min; Class.prototype._fn = function(a, b) { this.array.sort(_cmp); return _min(a, b + cachedVar); }; })();

JavaScript 1.7 let ( cachedVar = 1, _cmp = function(a, b){ return a < b; }, _min = Math.min ) { Class.prototype._fn = function(a, b) { this.array.sort(_cmp); return _min(a, b); }; };

function() { function _self() { arguments.callee.a = 1; _self.a = 1; } } Opera 10.53 firefox 3.6 ie1673 2477 9454 1068 767 NaN

if(Function.canFastSelf) { $jb._fConstC.__fRet = function() { return function _self() { return _self.c; }; }; } else { $jb._fConstC.__fRet = function() { return function() { return arguments.callee.c; }; }; }

a = {} a = new Object() Opera 10.52 firefox 3.6 ie chrome4906 1319 3154 1218 1237 1888 4016 1891

A = [] a = new Array() Opera 10.52 firefox 3.6 ie chrome41144 1234 3214 1284 1627 1875 4136 1938

/{} = n*'' function(){} = n*'' Opera 10.53 firefox 3.6 ie chrome42,4 2,75 6,5 1,9 3 2,75 6,25 2,5

If() switch()switch(a) { if(a === 0) { case 0: break; } else if(a === 1) { case 1: break; } } Opera 10.52 firefox 3.6 ie chrome41089 1171 1572 1988 1575 1832 1682 2582

Switch switch switch!!!Function.prototype._fBind = function(that, args) { var _fn = this, _ret; if(that != null) { _ret = (args != null) ? function(){ return (arguments.length > 0) ? _fn.apply(that, arguments) : _fn.call(that); }; : function(){ return _fn.apply(that, args); } } else { _ret = (args != null) ? function(){ return (arguments.length > 0) ? _fn.apply(this, arguments) : _fn.call(this); }; : function(){ return _fn.apply(this, args); }; } _ret.prototype = _fn.prototype; return _ret; };

Switch switch switch!!!Function.prototype._fBind = function(that, args) { var _fn = this, _ret; switch((that != null) + ((args != null) 0) ? _fn.apply(that, arguments) : _fn.call(that); }; break; case 2: _ret = function(){ return _fn.apply(this, args); }; break; default: _ret = function(){ return (arguments.length > 0) ? _fn.apply(this, arguments) : _fn.call(this); }; } _ret.prototype = _fn.prototype; return _ret; };

Switch switch switch again!!!switch(mod8) { case 7: a[--j] = this[--i]; case 6: a[--j] = this[--i]; case 5: a[--j] = this[--i]; case 4: a[--j] = this[--i]; case 2: a[--j] = this[--i]; case 3: a[--j] = this[--i]; case 1: a[--j] = this[--i]; case 1: a[--j] = this[--i]; case 0: a[--j] = this[--i]; }

^_^ f.style.left = ((d.x = d.r*_sin(d.t += d.dt) + d.x0)|0) - 20 + 'px'; f.style.left = ((d.x = d.x0 = _random()*($A.wWidth - 40) + 20)|0) + 'px'; if((temp = d.x - x)*temp + (temp = d.y - y)*temp < 2601) ( ( this.prototype = Object.create(_constuctor.prototype) ). constructor = this ).superClass = _constuctor;

for(j=0; j< m ; j+ +) -1; while(++ j = 0; jj= m ; while(j--) j= ) ) a = j; a = j; a = j; a = j; Opera 10.52 4958 4920 4013 3763 firefox 3.6 5955 5083 5056 4193 6492 4626 5106 3606 ie chrom e4 10723 8756 9112 7137

/

0 != 0 bjec t NaN o fals e true fals e true true false

Infinity null undefined true fals e fals e

i = vs.length; while((v = vs[--i])) ; i = -1; while((v = vs[++i])) ;

Object.prototype

A.prototype

B.prototype

Z.prototype

Opera 10.52 firefox 3.6 ie chrome46371 7105 7779 10041 6361 7361 8595 10059

DOM Object(v = a[j]).x = 1; v.y = 1; v.z = v.x;(v = a[j].b).x = 1; v.y = 1; v.z = v.x; v.g = v.x + v.y + v.z; v.g = v.x + v.y + v.z; Opera 10.52 firefox 3.6 ie chrome43278 5669 1572 4758 3385 5246 1682 2292

var Class = function(a0, a1) { this.publicVar = defaultValue; this._fn0 = function() { this.publicVar = 1; }; };

Class.prototype

Class closure a0 a1

classInst .publicVar ._fn0

var classInst = new Class(1, 2); classInst._fn0();

var Class = function(a0, a1) { this.publicVar = defaultValue; }; Class.prototype._fn0 = function() { this.publicVar = 1; }; var classInst = new Class(1, 2); classInst._fn0();

Class.prototype ._fn0

classInst .publicVar

Function.prototype._staticDeriveFrom = function(_constuctor) { var key, dpr = this.prototype, spr = _constuctor.prototype; for(key in spr) { if(spr.hasOwnProperty(key) && !(key in dpr)) dpr[key] = spr[key]; } return this; };

var DerivedClass = function(a0, a1) { Class.call(this, a0, a1); }; DerivedClass._staticDeriveFrom(Class); DerivedClass.prototype._fn1 = function() { Class.prototype._fn0.call(this); }; var derivedClassInst = new DerivedClass(1, 2); derivedClassInst._fn1();

DerivedClass.prototype ._fn0 ._fn1

classInst .publicVar

var Class = function(a0, a1) { this._onMouseMove = this._onMouseMove.bind(this); }; Class.prototype._onMouseMove = function() { };

Class.prototype .onMouseMove

classInst .onMouseMove binded

var classInst = new Class(1, 2); document.onmousemove = classInst._onMouseMove;

for in for(j in a) { if(a.hasOwnProperty(j)) ++k; }2162 2073 4998 2780

j = a.length; while(j--) ++k; Opera 10.53 firefox 3.6 ie chrome41181 1418 1212 1925

.calla = []; a = [] a._fn('b') _fn.call(a, 'b') Opera 10.53 firefox 3.6 ie chrome41236 1641 5247 1476 1546 2436 6549 1834

undefinedtypeof(v) !== 'undefined' v !== undefined v != null 305 313 273 286 431 192 411 361 200 461 581 351

Opera 10.52 firefox 3.6 ie chrome4

undefined Opera 10.52 firefox 3.6 ie chrome4 a['0'] !== undefined typeof(a['0']) !== 'undefined' '0' in a 2320 1911 1863 3346 1926 18813848 2924 2564

5217

3686

3519

undefined (v = a['0']) !== undefined, vtypeof(v = a['0']) !== 'undefined', v('0' in a), a[i] Opera 10.52 3055 2580 2113 firefox 3.6 3798 2456 1925 ie 3655 3005 4505 chrome4 5109 4216 3628

arguments * jump

.each - $('div.a').each( function(v) { $(v).removeClass('a'); } ); jit

// for(var nodes = $('div.a'), i = 0, len = nodes.length; i < len; ++i) $(nodes[i]).removeClass('a');

arguments

.call / .apply_fn.call(that) _fn.apply(that, args) Opera 10.52 firefox 3.6 ie chrome41544 2645 7460 1986 2037 2847 10170 2490

isNaNa !== a _isNaN(a) Opera 10.52 firefox 3.6 ie chrome41175 1052 1142 1920 1175 1061 2674 1972

isFinitea/a === 1 || a === 0_isFinite(a) Opera 10.52 firefox 3.6 ie chrome41532 1218 1372 2026 1280 1050 2734 2164

RegExp s.replace(/\s/g, ''); var re = new RegExp(/\s/); s.replace(re, ''); Opera 10.52 firefox 3.6 ie chrome43838 7014 13600 7853 2054 2211 7070 2395

-> _parseFloat(a) +a 1*a a - 0 695 403 464 435 Opera 10.52 firefox 3.6 531 416 402 391 ie 1212 380 401 391 chrome4 1039 744 791 823

a>>0 a&-1 _floor(a) 1909 Opera 10.53 1386 1370 1371 1606 1567 1575 1762 firefox 3.6 1211 1213 1231 4287 ie chrome4 2652 2501 2544 3313 a|0

a.toString() String(a) StringC(a) '' + a 478 446 413 281 Opera 10.52 firefox 3.6 594 1100 961 304 ie 1833 1652 1472 1042 chrome4 633 893 737 566

'1'.slice() Object.('1').slice()

. RegExp.test switchre = new RegExp(/^link|tbody$/); re.test(a) case 'link': case 'tbody': Opera 10.52 firefox 3.6 ie chrome42161 3167 7572 4548 1723 1726 2402 3118

String char accessP.charAt O.charAt P.substr O.substr P.slice O.slice P[] O[] split[] 1403 1336 1344 1373 1350 1401 1084 1059 1069 Opera 10.52 firefox 3.6 1871 1967 2161 2345 2238 2399 1014 1139 1015 ie n/s 7510 10810 7720 11310 7710 11120 n/s 1400 chrome4 2210 2439 2262 2473 2250 2427 2189 2324 1986

if(String.nativeDirectCharAccess) { _fn = new Function( _fn._argsString(), _fn._body().slice(1, -1).replace(/\.\s*charAt\s*\ (([^\)]*)\)/g, '[$1]'); }

.slice ( ie)s.slice(0, 8000); s.slice(0, 5000); Opera 10.53 firefox 3.6 ie chrome4388 510 5818 557 345 528 4256 594

var p = ~(~s.indexOf('a') || ~s.indexOf('b') || ~s.indexOf('c') || ~oldP); var p = s.lastIndexOf('a') >>> 0; // fix for opera code.replace( /\s(.*?)\s*=(.*?)>>>\s*0/g, 'if(($1 = $2) < 0) $1 = 4294967295;' );

String.prototype.__mulNumber = function(n, prefix) { n |= 0; prefix += ""; var str = "" + this; while(n) { if(n&1) prefix += str; n >>= 1; str += str; } return prefix; };

var failCount = -1; while(p < sLen) { if(s.substr(p, matchMultyLen) === matchMulty) { p += matchMultyLen; matchMultyLen = 1)); } else { matchMultyLen = matchLen; matchMulty = match; failCount = -1; } } }

var s = $h.getElementsByTagName('script')[0], checkerBody = ''; if('readyState' in s) { checkerBody += "var rs = v.readyState; \ if(rs === 'loaded' || rs === 'complete')\ return true; \ else\ return false;"; } if($w.opera) { checkerBody += "if(v.text != null) return true;"; } checkerBody += "return null;";

String.prototype.trim = function() { return (this.lenght < 100) ? this.__trim1() : this.__trim2(); }; String.prototype.trim = ($w.opera) ? function(){...} : function(){...};

arg0 0 _fn0 0,0 500 100 _fn1 arg0 _fn0 2500 _fn2 +inf

_fn2

1000

_fn3

_fn1

arg1

json/xml Debug = /

Release = . . *

$jb.Prepocessor(new $jb.Prepocessor). _define('_IS_FINITE($V)', $jb._preprocessingTextBegin(function(){ ($V&$V) !== 0 || $V === 0 })._preprocessingTextEnd() );

General PreProcessor#define _IS_FINITE($V) ($V&$V) !== 0 || $V === 0 #end

Twitter: https://twitter.com/bga_ Email: mailto:[email protected] jabber/gtalk: [email protected]

, 3 , ! . , (copy/paste) , . Trebuchet.