Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
for(initial;condition;loop statement){statements}можно после loop statement поставить запятую и расположить все операторы из statements через запятую(вместо точки с запятой) — экономим 2 байта(фигурные скобки)if(i.length>0) смело заменяем на if(i.length)тоже 2 байтаможно после loop statement поставить запятую и расположить все операторы из statements через запятую(вместо точки с запятой) — экономим 2 байта(фигурные скобки)
if(i.length>0)
смело заменяем на
if(i.length)
тоже 2 байта
в коде дважды встречается [0,0,0,0,0,0] — логично вынести в отдельную переменную, даст еще 11 байт
опережая будущих комментаторов: замену a.charAt(0) на a[0] делать не стоит, т.к. ведет к потере ie6
— нет, это массив, он должен быть разным в каждом случаекопию массива можно получить, к примеру, так: g.slice()
g = [0,0,0,0,0,0]; // исходный массив
v = [g][0]; // делаем копию
g = [1,0,0,0,0,0]; // меняем исходный
v; // [0,0,0,0,0,0]— верно, но это подходит только для простых случаев (без например ифов внутри).
if (i.length) {
a = "z" + i;
console.log(a, i);
}
i.length && (a = "z" + i, console.log(a, i));
for (i = 0; i < 20; i++, a = 'z' + i, i % 2 && console.log(a, i))
a.substr(1,a.length-1);заменяем наa.slice(1);typeof this.x == «undefined» => this.x === undefined.
Ещё в функциях из одного ифа отлично использовать тернарник.
if(typeof a.module!=q)наif(a.module)иif(typeof this.v==q)наif(!this.v)if(typeof variable != "function")доif(!variable.call)если верить тесту от 2001 года то проблем не возникнет в ie6 и mozilla 1.0rc1, а вот opera 6.01 может подкачать :)var l="length";
str[l];var a = [];
for ( var i in someEnum ) {
a[ i ] = 0;
}var a = [ 0, 0, 0 ];eval(function(p,a,c,k,e,r){e=function©{return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e©]=k[c]||e©;k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e©+'\\b','g'),k[c]);return p}('!A(){O a={},b=a.10=A(a){6.o=6.11=a;6.D=0;6.p=6.12=[];6.q=6.13=[];6.r=[];6.s=[];6.t=[];d.F(6);f.F(6);6.u=[];6.g(g)},c=14,d=[],e=0,f=[],g=[0,0,0,0,0,0],h=A(a,b,c){i.F([a,b||0,c]);I.15(k,"*")},i=[],j="16",k=j+(V 17).18(),l=A(a,b){9(a.19==I&&a.1a==k)9(i.B){b=i.P();b[0].1b(b[1],b[2])}},m=A(a,b,c){9(a.K(0,7).W()!=j+"://"&&a.K(0,8).W()!=j+"s://")a=b.K(0,b.1c("/")+1)+a;c=a;1d{a=c;c=a.1e(/[\\w\\.~]*\\/\\.\\.\\//,"")}J(c!=a);C a},n=A(a,c){c=u(a);9(!c){c=V b(a);h(A(){9(!e)o()})}C c},o=A(){Q=R=0;e=f.S()||0;9(e)e.a()},p=A(){},q="1f",r="1g",s=a.1h=A(a,b,c){9(H b!=v)b=p;9(H c!=v)c=p;O d=1;9(H a=="1i"){d=0;a=[a]}O e=a.B,f=A(){9(!--e)b()},g=0,h=A(a){9(!g){g=1;t(i);c(a)}},i=[],j="",k,l=0;E(;l<a.B;k=n(j),i.F(k.l(f,h)))j=a[l++];C d?i:i[0]},t=a.1j=A(a,b){9(H a.L!=q){a.L.m(a);C}E(b=0;b<a.B;b++)a[b].L.m(a[b])},u=a.1k=A(a,b){E(b=0;b<d.B;b++)9(d[b].o==a)C d[b];C M},v="A";9(H X==q){X=a}I.1l("1m",l,1);a.1n={1o:0,1p:1,1q:2,1r:3,1s:4,1t:5};a.1u=A(){C d};a.Y=A(){C g};b.1v={Y:A(){9(H 6.v==q)6.g(6.v=[0,0,0,0,0,0]);C 6.v},a:A(a,b){6.h(1);a=6.o,b=6;9(a[0]=="/")a=a.K(1,a.B-1);6.w=Z.1w®;6.w.1x="1y/1z"+r;6.w.1A=a;6.w.N=A(){e.c()};6.x=1B(A(){e.b(b.o)},c);Z.1C("1D").1E(0).1F(6.w)},b:A(a,b){9(6.D==M)C;J(6.s.B)h(6.s.P(),0,[a]);J(6.p.B){b=6.p.S();h(b.b,b,[a])}6.f();9(6==e){6.n();o()}},c:A(){6.y=Q;6.z=R;6.n();h(o);9(!6.j())6.f();G 9(6.k())6.d();G 6.h(2)},d:A(){6.h(3);h(A(a){9(6.y)6.y();9(6.j()){6.h(4);J(6.r.B)6.r.P()();E(a=0;a<6.p.B;a++)9(6.p[a].D==2&&6.p[a].k())6.p[a].d()}G 6.e()},6)},e:A(){6.h(5);h(A(){9(6.z)6.z();9(6.j())6.d();G 6.f()},6)},f:A(a,b){6.h(M);J(6.q.B){a=6.q.S();E(b=0;b<a.p.B;b++)9(a.p[b]==6){a.p.T(b,1);U}9(!a.j())9(a.D==2)h(a.f,a);G 9(a.D==4)a.e()}E(b=0;b<d.B;b++)9(d[b]==6){d.T(b,1);U}6.y=6.z=6.u=6.r=6.s=0},g:A(a,b){E(b=0;b<6.u.B;)9(6.u[b++]==a)C;6.u.F(a);a[6.D]++;E(b=0;b<6.q.B;)6.q[b++].g(a)},h:A(a,b,c){b=6.D,c=0;6.D=a;E(;c<6.u.B;c++){6.u[c][b]--;9(6.D!==M)6.u[c][6.D]++}},i:A(a,b){E(b=0;b<6.p.B;b++)9(6.p[b].o==a||6.p[b].i(a))C 1;C 0},j:A(){C 6.t.B||6.p.B},k:A(a){E(a=0;a<6.q.B;)9(6.q[a++].D!=4)C 0;C 1},l:A(a,b,c){c={L:6};6.t.F©;9(6.D==4){9(a)h(a)}G{9(a)6.r.F(a);9(b)6.s.F(b)}C c},m:A(a,b){E(b=0;b<6.t.B;b++)9(6.t[b]==a){6.t.T(b,1);U}9(!6.j())9(6.D==2)6.f();G 9(6.D==4)6.e()},n:A(){1G(6.x);6.w.1H.1I(6.w);6.w=6.w.N=6.x=0;1J 6.w}};9(!I.N)I.N=A(){s("/1K.1L")};1M=A(a,b,c,d){b=e,c=0;9(!b)C;a=m(a,b.o);9(b.i(a))b.b(a);G{d=n(a);d.p.F(b);b.q.F(d);E(;c<b.u.B;)d.g(b.u[c++])}};Q=R=0}()',62,111,'||||||this|||if|||||||||||||||||||||||||||function|length|return|state|for|push|else|typeof|window|while|substr|module|null|onload|var|shift|init|uninit|pop|splice|break|new|toLowerCase|kernel|getStatistics|document|Module|path|children|parents|3e3|postMessage|http|Date|getTime|source|data|apply|lastIndexOf|do|replace|undefined|script|require|string|release|getModule|addEventListener|message|moduleStates|created|parsing|waiting|initializing|ready|uninitializing|getModulesList|prototype|createElement|type|text|java|src|setTimeout|getElementsByTagName|head|item|appendChild|clearTimeout|parentNode|removeChild|delete|main|js|include'.split('|'),0,{}))Finally, a few users noticed that we no longer provide a “packed” version of jQuery (a version of jQuery run through Dean Edwards’ Packer with Base62 encoding turned on). We did this for a couple reasons:
Packed scripts are significantly harder to debug (even harder than minifed scripts).
Packed scripts aren’t able to run on all platforms without issue (such as Adobe AIR and Caja-capable environments).
But most importantly: Packed scripts are slower for the user than what you would get from using just minification. This may seem counter-intuitive since a packed script’s file size is smaller than a minified script but the final load time ends up being much higher (due to the decompression step it must go through). We have some data regarding the loading performance of minified scripts vs. packed scripts, for those that are interested.
The minifed copy of jQuery that we provide, run through the YUI Compressor, should be the optimal form of jQuery to use in a production environment (served using gzipping, if possible).
kernel._getAbsolute = function( path, childPath ) {
// concatinating path with the child's path (without the filename)
// path starting from "http://" or "https://" treated as absolute
if ( path.substr( 0, 7 ).toLowerCase() != "http://" &&
path.substr( 0, 8 ).toLowerCase() != "https://" ) {
path = childPath.substr( 0, childPath.lastIndexOf("/") + 1 )
+ path;
}
// resolving (clearing) up-dir sequences such as "foo/../"
var newPath = path;
do {
path = newPath;
newPath = path.replace( /[\w\.~]*\/\.\.\//, "" );
} while ( newPath != path );
return path;
}
var ... , http = "http" ...
kernel._getAbsolute = function( path, childPath, newPath ) {
// concatinating path with the child's path (without the filename)
// path starting from "http://" or "https://" treated as absolute
if ( path.substr( 0, 7 ).toLowerCase() != http + "://" &&
path.substr( 0, 8 ).toLowerCase() != http + "https://" ) {
path = childPath.substr( 0, childPath.lastIndexOf("/") + 1 )
+ path;
}
// resolving (clearing) up-dir sequences such as "foo/../"
newPath = path;
do {
path = newPath;
newPath = path.replace( /[\w\.~]*\/\.\.\//, "" );
} while ( newPath != path );
return path;
}
"http://""https://"
,x="http"x+"://"x+"s://"
kernel._getAbsolute = function( path, childPath ) {
// concatinating path with the child's path (without the filename)
// path starting from "http://" or "https://" treated as absolute
if (!/^https?:\/\//.test(path)) {
path = childPath.replace(/[^\/]+$/, '') + path;
}
// resolving (clearing) up-dir sequences such as "foo/../"
var prevPath;
while (prevPath != path){
prevPath = path;
path = path.replace( /[\w\.~]*\/\.\.\//, "" );
}
return path;
}
// оригинал
// Original Size: 558 bytes (334 bytes gzipped)
// Compiled Size: 226 bytes (187 bytes gzipped)
kernel._getAbsolute=function(a,c){a.substr(0,7).toLowerCase()!="http://"&&a.sub
str(0,8).toLowerCase()!="https://"&&(a=c.substr(0,c.lastIndexOf("/")+1)+a);var
b=a;do a=b,b=a.replace(/[\w\.~]*\/\.\.\//,"");while(b!=a);return a};
// ваша оптимизация
// Original Size: 571 bytes (342 bytes gzipped)
// Compiled Size: 229 bytes (187 bytes gzipped)
x="http";kernel._getAbsolute=function(a,c,b){a.substr(0,7).toLowerCase()!=x+":/
/"&&a.substr(0,8).toLowerCase()!=x+"s://"&&(a=c.substr(0,c.lastIndexOf("/")+1)+
a);b=a;do a=b,b=a.replace(/[\w\.~]*\/\.\.\//,"");while(b!=a);return a};
// моя оптимизация
// Original Size: 450 bytes (296 bytes gzipped)
// Compiled Size: 153 bytes (147 bytes gzipped)
kernel._getAbsolute=function(a,c){/^https?:\/\//.test(a)||(a=c.replace(/[^\/]+$
/,"")+a);for(var b;b!=a;)b=a,a=a.replace(/[\w\.~]*\/\.\.\//,"");return a};
kernel.Module.prototype._parse = function() {
this._setState( this._states.parsing );
var path = this.path;
if ( path.charAt(0) == "/" ) {
path = path.substr( 1, path.length - 1 );
}
this._script = document.createElement("script");
this._script.type = "text/javascript";
this._script.src = path;
this._script.onload = function() {
kernel._activeModule._finalizeParsing();
}
var me = this;
this._invalidTimeout = setTimeout(
function() {
kernel._activeModule._invalidate( me.path );
},
kernel._invalidateTimeout
);
document.getElementsByTagName("head").item(0).appendChild(this._script);
}
// скомпилированный closure вариант
// Original Size: 592 bytes (321 bytes gzipped)
// Compiled Size: 509 bytes (292 bytes gzipped)
kernel.Module.prototype._parse=function(){this._setState(this._states.parsing);v
ar a=this.path;a.charAt(0)=="/"&&(a=a.substr(1,a.length-1));this._script=documen
t.createElement("script");this._script.type="text/javascript";this._script.src=a
;this._script.onload=function(){kernel._activeModule._finalizeParsing()};var b=t
his;this._invalidTimeout=setTimeout(function(){kernel._activeModule._invalidate(
b.path)},kernel._invalidateTimeout);document.getElementsByTagName("head").item(0
).appendChild(this._script)};
// ваша оптимизация
// Compiled Size: 333 bytes (241 bytes gzipped)
x="script";kernel.Module.prototype._parse=function(a,b){this.h(1);a=this.o;b=thi
s;a[0]=="/"&&(a=a.substr(1,a.length-1));this.w=document.createElement(x);this.w.
type="text/java"+x;this.w.src=a;this.w.onload=function(){e.c()};this.x=setTimeou
t(function(){e.b(b.o)},c);document.getElementsByTagName("head").item(0).appendCh
ild(this.w)};
// Насчет замены "script"
// было:
"script""text/javascript"
// cтало:
,x="script"x"text/java"+x
// вы ничего не выиграли и не проиграли, сколько было, столько и осталось
// Немного перепишем функцию
kernel.Module.prototype._parse = function() {
var me = this;
var script = me._script = document.createElement("script");
script.type = "text/javascript";
script.src = me.path.replace(/^\/(.*).$/, '$1');
script.onload = function() {
me._finalizeParsing();
}
me._setState( STATE_PARSING );
me._invalidTimeout = setTimeout(
function() {
me._invalidate( me.path );
},
INVALIDATE_TIMEOUT
);
document.getElementsByTagName("head")[0].appendChild(script);
}
// получаем
// Original Size: 453 bytes (304 bytes gzipped)
// Compiled Size: 371 bytes (278 bytes gzipped)
// А если проделать ваши замены
// Compiled Size: 283 bytes (223 bytes gzipped)
kernel.Module.prototype._parse=function(){var a=this,b=a.w=document.createElemen
t("script");b.type="text/javascript";b.src=a.o.replace(/^\/(.*).$/,"$1");b.onloa
d=function(){e.c()};a.h(1);a.x=setTimeout(function(){e.b(a.o)},c);document.getEl
ementsByTagName("head")[0].appendChild(b)};
!function(){
function extend(a, b){
for (var key in b)
a[key] = b[key];
}
var STATE_CREATED = 0;
var STATE_PARSING = 1;
// etc
var Module = function(){};
Module.prototype = {
property: value,
method: function(){
this.setState(STATE_PARSING);
}
// ...
};
var _kernel = {
Module: Module,
property: value,
method: function(){
}
// ...
};
extend(kernel, _kernel);
}()
(function () {
var a = function () {};
a.prototype = {
property: value,
method: function () {
this.setState(1)
}
};
(function (a, b) {
for (var c in b) a[c] = b[c]
})(kernel, {
Module: a,
property: value,
method: function () {}
})
})();
=========================
+32 bytes
/* orginal */
function (a, b) {
if (this.state == null) return;
while (this.s.length)
h(this.s.shift(), 0, [a]);
while (this.p.length) {
b = this.p.pop();
h(b.b, b, [a])
}
this.f();
if (this == e) {
this.n();
o()
}
}
/* optimized */
function (path) {
if (this.state) {
var item;
while (item = this.s.shift()) {
h(item, null, [path]);
}
while (item = this.p.pop()) {
h(item.b, item, [path]);
}
this.f();
if (this == e) {
this.n();
o();
}
}
}
/* orginal */
function(a,b){if(this.state==null)return;while(this.s.length)h(this.s.shift(),0,
[a]);while(this.p.length){b=this.p.pop();h(b.b,b,[a])}this.f();if(this==e){this.
n();o()}};
/* optimized */
function(b){if(this.state){for(var a;a=this.s.shift();)h(a,null,[b]);for(;a=this
.p.pop();)h(a.b,a,[b]);this.f();this==e&&(this.n(),o())}};
=========================
+27 bytes
/* orginal */
for (var a = 0; a < this.p.length; a++)
if (this.p[a].state == 2 && this.p[a].k())
this.p[a].d()
/* optimized */
for (var a = 0, x; x = this.p[a++];)
if (x.state == 2 && x.k())
x.d()
/* original */
for(var a=0;a<this.p.length;a++)this.p[a].state==2&&this.p[a].k()&&this.p[a].d();
/* optimized */
for(var a=0,x;x=this.p[a++];)x.state==2&&x.k()&&x.d();
==========================
+28 bytes
/* original */
function f(a, b) {
for (b = 0; b < this.p.length; b++)
if (this.p[b].o == a || this.p[b].i(a))
return 1;
return 0
}
/* optimized */
function f(a) {
for (var i = 0, obj; obj = this.p[i++];)
if (obj.o == a || obj.i(a))
return 1;
}
/* original */
function f(b,a){for(a=0;a<this.p.length;a++)if(this.p[a].o==b||this.p[a].i(b))re
turn 1;return 0};
/* optimized */
function f(b){for(var c=0,a;a=this.p[c++];)if(a.o==b||a.i(b))return 1};
получение двух новых строк (substr), два приведения к нижнему регистру (toLowerCase), два сравнения (==).действительно никуда не годится
Во-первых, ваше решение показало лучший результат только в одном браузере, что нельзя назвать успехомie6/7,fx6 — в два раза быстрее, чем rx
Во-вторых, ваше решение определяет что на 4-й или 5-й позиции есть подстрока "://", что неверно, так как в оригинале проверялось, что перед этой подстрокой должна быть подстрока «http» или «https», а у вас это не проверяется.отталкиваемся все же от задачи: в оригинале этого не требуется — нам всего лишь надо знать, абсолютный путь или относительный, приведенный мною код с этим полностью справляется
var l="length",p="push",s="state",m="module",...
this.u.push(a) -> this.u[p](a)
if(this.y)this.y();this.y&&this.y();
Маньячная минимизация (в погоне за байтом)