SlideShare a Scribd company logo
1 of 105
Download to read offline
Extreme
JavaScript
Performance
Thomas Fuchs
@thomasfuchs
DO NOT, EVER,
OPTIMIZE
PREMATURELY
http://tr.im/extremejs
SpiderMonkey
SpiderMonkey
JavaScriptCore
SpiderMonkey
JavaScriptCore
JScript
SpiderMonkey
JavaScriptCore
JScript
V8
#1
avoid function calls
function  methodCall(){
    function  square(n){  return  n*n  };
    var  i=10000,  sum  =  0;
    while(i-­‐-­‐)  sum  +=  square(i);
}
function  inlinedMethod(){  
    var  i=10000,  sum  =  0;
    while(i-­‐-­‐)  sum  +=  i*i;
}
function  methodCall(){
    function  square(n){  return  n*n  };
    var  i=10000,  sum  =  0;
    while(i-­‐-­‐)  sum  +=  square(i);
}
function  inlinedMethod(){  
    var  i=10000,  sum  =  0;
    while(i-­‐-­‐)  sum  +=  i*i;
}
function  methodCall(){
    function  square(n){  return  n*n  };
    var  i=10000,  sum  =  0;
    while(i-­‐-­‐)  sum  +=  square(i);
}
function  inlinedMethod(){  
    var  i=10000,  sum  =  0;
    while(i-­‐-­‐)  sum  +=  i*i;
}
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm,  hmm† 0.128s
0.027s 0.016s
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm,  hmm† 0.128s
0.027s 0.016s
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm,  hmm† 0.128s
0.027s 0.016s
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm,  hmm† 0.128s
0.027s 0.016s
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm,  hmm† 0.128s
0.027s 0.016s
IE8 throws this warning
after 1 second
#2
embrace the
language
function  literals(){
    var  a  =  [],  o  =  {};
}
function  classic(){
    var  a  =  new  Array,  o  =  new  Object;
}
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
>  parseInt(12.5);
12
>  ~~(1  *  "12.5")
12
1 * string coerces the
string into a float,
result = 12.5
double bitwise NOT*
floors the number
>  ~~(1  *  "12.5")
12
*good overview on http://tr.im/bitwise
parseInt() weird  stuff
0.003s 0.002s
0.088s 0.081s
uhm,  hmm† 0.547s
0.109s 0.282s
parseInt() weird  stuff
0.003s 0.002s
0.088s 0.081s
uhm,  hmm† 0.547s
0.109s 0.282s
parseInt() weird  stuff
0.003s 0.002s
0.088s 0.081s
uhm,  hmm† 0.547s
0.109s 0.282s
parseInt() weird  stuff
0.003s 0.002s
0.088s 0.081s
uhm,  hmm† 0.547s
0.109s 0.282s
parseInt() weird  stuff
0.003s 0.002s
0.088s 0.081s
uhm,  hmm† 0.547s
0.109s 0.282s
parseInt() weird  stuff
0.003s 0.002s
0.088s 0.081s
uhm,  hmm† 0.547s
0.109s 0.282s
Firefox is 30x faster
than Safari
#3
loops
var  test  =  '';
for  (var  i  =  0;i<10000;i++)
  test  =  test  +  str;
var  test  =  '',  i  =  10000;
while(i-­‐-­‐)  test  =  test  +  str;
for  loop while  loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
for  loop while  loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
for  loop while  loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
for  loop while  loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
for  loop while  loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
var  test  =  '';
for  (var  i  =  0;i<10000;i++)
  test  =  test  +  str;
var  test  =  '',  i  =  10000;
while(i-­‐-­‐)  test  =  test  +  str;
3 expressions in “for”
1 expression in “while”
(when i equals 0, expression will be false)
function  normalLoop(){
    var  i=60,  j=0;
    while(i-­‐-­‐)  j++;
}
function  unrolledLoop(){
    var  j=0;
    j++;  j++;  j++;  j++;  j++;  j++;  
    j++;  j++;  j++;  j++;  j++;  j++;
    j++;  j++;  j++;  j++;  j++;  j++;
    j++;  j++;  j++;  j++;  j++;  j++;
    j++;  j++;  j++;  j++;  j++;  j++;
    j++;  j++;  j++;  j++;  j++;  j++;
    j++;  j++;  j++;  j++;  j++;  j++;
    j++;  j++;  j++;  j++;  j++;  j++;
    j++;  j++;  j++;  j++;  j++;  j++;
    j++;  j++;  j++;  j++;  j++;  j++;
}
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
#4
cache globals
function  uncached(){
    var  i  =  10000;
    while(i-­‐-­‐)  window.test  =  'test';
}
function  cached(){
    var  w  =  window,  i  =  10000;
    while(i-­‐-­‐)  w.test  =  'test';
}
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
Safari is 20x faster
than Firefox
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
Now IE works with >1s durations. WTF?
#5
expression tuning
var  b  =  false,  n  =  99;
function(){
    return  n*n  &&  b;
}
function(){
    return  b  &&  n*n;
}
var  b  =  false,  n  =  99;
function(){
    return  n*n  &&  b;
}
function(){
    return  b  &&  n*n;
} b is false,
so n*n doesn’t need
to get evaluated
not  tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
not  tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
not  tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
not  tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
not  tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
>>>  var  n  =  1;
undefined
>>>  if(true  &&  (n=2))  ...;
>>>  n
2
>>>  if(true  ||  (n=3))  ...;
>>>  n
2
not a pure engine optimization,
the execution actually stops
here, n=2 needs to
be evaluated,
so n is set to 2
here it doesn’t
(expression must
be true), so n is
NOT set to 3
#6
what not to use
function(){
    var  obj  =  {  prop:  'test',  str:  ''  };
    with(obj){  
        var  i  =  10000;
        while(i-­‐-­‐)  str  +=  prop;
        return  str;
    }
}
function(){
    var  obj  =  {  prop:  'test',  str:  ''  },  i  =  10000;
    while(i-­‐-­‐)  obj.str  +=  obj.prop;
    return  obj.str;
}
with(obj){  p  } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
with(obj){  p  } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
with(obj){  p  } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
with(obj){  p  } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
with(obj){  p  } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
var  a  =  0;
function(){
    try{
        a  +=  1;
    }  catch(e)  {}
}
function(){
    a  +=  1;
}
try/catch no  try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
try/catch no  try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
try/catch no  try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
try/catch no  try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
try/catch no  try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Modern JavaScript
engines have JIT
compilers, which don’t
support certain
features well
Avoid stuff
that’s not
available in
ECMA-262
5th Edition
“strict” mode,
see John’s blog
post
Avoid stuff
that’s not
available in
ECMA-262
5th Edition
“strict” mode,
see John’s blog
post
http://tr.im/ecma262
alert((function(){return"alert
(("+arguments.callee.toString()
.replace(/s/g,"")+")());";})());
alert((function(){return"alert
(("+arguments.callee.toString()
.replace(/s/g,"")+")());";})());
(function(){  return  2  *  3;  }).toString();
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  6;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  2  *  3;  }
function  ()  {  return  6;  } WTF?
More in
http://jsrocks.com
More in
http://jsrocks.com
DO NOT, EVER,
OPTIMIZE
PREMATURELY
Q&A
And thanks!
http://javascriptrocks.com/
@thomasfuchs on twitter

More Related Content

What's hot

django Forms in a Web API World
django Forms in a Web API Worlddjango Forms in a Web API World
django Forms in a Web API WorldTareque Hossain
 
Dangling DNS records takeover at scale
Dangling DNS records takeover at scaleDangling DNS records takeover at scale
Dangling DNS records takeover at scaleChandrapal Badshah
 
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...Frans Rosén
 
Rouault imbert alpc_rpc_pacsec
Rouault imbert alpc_rpc_pacsecRouault imbert alpc_rpc_pacsec
Rouault imbert alpc_rpc_pacsecPacSecJP
 
Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]
Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]
Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]Jaeman An
 
XSS - Do you know EVERYTHING?
XSS - Do you know EVERYTHING?XSS - Do you know EVERYTHING?
XSS - Do you know EVERYTHING?Yurii Bilyk
 
Velocity 2015 linux perf tools
Velocity 2015 linux perf toolsVelocity 2015 linux perf tools
Velocity 2015 linux perf toolsBrendan Gregg
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具Shengyou Fan
 
Caching solutions with Redis
Caching solutions   with RedisCaching solutions   with Redis
Caching solutions with RedisGeorge Platon
 
What’s wrong with WebSocket APIs? Unveiling vulnerabilities in WebSocket APIs.
What’s wrong with WebSocket APIs? Unveiling vulnerabilities in WebSocket APIs.What’s wrong with WebSocket APIs? Unveiling vulnerabilities in WebSocket APIs.
What’s wrong with WebSocket APIs? Unveiling vulnerabilities in WebSocket APIs.Mikhail Egorov
 
Android MvRx Framework 介紹
Android MvRx Framework 介紹Android MvRx Framework 介紹
Android MvRx Framework 介紹Kros Huang
 
Using the New Network Load Balancer with Amazon ECS - AWS Online Tech Talks
Using the New Network Load Balancer with Amazon ECS - AWS Online Tech TalksUsing the New Network Load Balancer with Amazon ECS - AWS Online Tech Talks
Using the New Network Load Balancer with Amazon ECS - AWS Online Tech TalksAmazon Web Services
 
Redis vs Infinispan | DevNation Tech Talk
Redis vs Infinispan | DevNation Tech TalkRedis vs Infinispan | DevNation Tech Talk
Redis vs Infinispan | DevNation Tech TalkRed Hat Developers
 
A Hacker's perspective on AEM applications security
A Hacker's perspective on AEM applications securityA Hacker's perspective on AEM applications security
A Hacker's perspective on AEM applications securityMikhail Egorov
 

What's hot (20)

django Forms in a Web API World
django Forms in a Web API Worlddjango Forms in a Web API World
django Forms in a Web API World
 
Express node js
Express node jsExpress node js
Express node js
 
Dangling DNS records takeover at scale
Dangling DNS records takeover at scaleDangling DNS records takeover at scale
Dangling DNS records takeover at scale
 
01 Php Introduction
01 Php Introduction01 Php Introduction
01 Php Introduction
 
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
 
Rouault imbert alpc_rpc_pacsec
Rouault imbert alpc_rpc_pacsecRouault imbert alpc_rpc_pacsec
Rouault imbert alpc_rpc_pacsec
 
Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]
Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]
Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]
 
XSS - Do you know EVERYTHING?
XSS - Do you know EVERYTHING?XSS - Do you know EVERYTHING?
XSS - Do you know EVERYTHING?
 
Velocity 2015 linux perf tools
Velocity 2015 linux perf toolsVelocity 2015 linux perf tools
Velocity 2015 linux perf tools
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具
 
Caching solutions with Redis
Caching solutions   with RedisCaching solutions   with Redis
Caching solutions with Redis
 
What’s wrong with WebSocket APIs? Unveiling vulnerabilities in WebSocket APIs.
What’s wrong with WebSocket APIs? Unveiling vulnerabilities in WebSocket APIs.What’s wrong with WebSocket APIs? Unveiling vulnerabilities in WebSocket APIs.
What’s wrong with WebSocket APIs? Unveiling vulnerabilities in WebSocket APIs.
 
Android MvRx Framework 介紹
Android MvRx Framework 介紹Android MvRx Framework 介紹
Android MvRx Framework 介紹
 
Expressjs
ExpressjsExpressjs
Expressjs
 
Using the New Network Load Balancer with Amazon ECS - AWS Online Tech Talks
Using the New Network Load Balancer with Amazon ECS - AWS Online Tech TalksUsing the New Network Load Balancer with Amazon ECS - AWS Online Tech Talks
Using the New Network Load Balancer with Amazon ECS - AWS Online Tech Talks
 
Nodejs presentation
Nodejs presentationNodejs presentation
Nodejs presentation
 
Redis vs Infinispan | DevNation Tech Talk
Redis vs Infinispan | DevNation Tech TalkRedis vs Infinispan | DevNation Tech Talk
Redis vs Infinispan | DevNation Tech Talk
 
hacking with node.JS
hacking with node.JShacking with node.JS
hacking with node.JS
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
A Hacker's perspective on AEM applications security
A Hacker's perspective on AEM applications securityA Hacker's perspective on AEM applications security
A Hacker's perspective on AEM applications security
 

Viewers also liked

Using jsPerf correctly
Using jsPerf correctlyUsing jsPerf correctly
Using jsPerf correctlyMathias Bynens
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionPaul Irish
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax ApplicationsJulien Lecomte
 
iOS Coding Best Practices
iOS Coding Best PracticesiOS Coding Best Practices
iOS Coding Best PracticesJean-Luc David
 
Know yourengines velocity2011
Know yourengines velocity2011Know yourengines velocity2011
Know yourengines velocity2011Demis Bellot
 
An Educators Guide to Podcasting and Broadcasting by @TeacherCast
An Educators Guide to Podcasting and Broadcasting by @TeacherCastAn Educators Guide to Podcasting and Broadcasting by @TeacherCast
An Educators Guide to Podcasting and Broadcasting by @TeacherCastJeffrey Bradbury
 
India’s women bankers at the helm
India’s women bankers at the helmIndia’s women bankers at the helm
India’s women bankers at the helmeTailing India
 
Modelo kata de competencia digital. isdi
Modelo kata de competencia digital. isdiModelo kata de competencia digital. isdi
Modelo kata de competencia digital. isdiFátima Gallo Martínez
 
ガチでビジネス DALIを使った照明制御
ガチでビジネス DALIを使った照明制御ガチでビジネス DALIを使った照明制御
ガチでビジネス DALIを使った照明制御Takahiro Nakahata
 
Samad Oraee - Learn More About Foot Pain
Samad Oraee - Learn More About Foot PainSamad Oraee - Learn More About Foot Pain
Samad Oraee - Learn More About Foot PainSamad Oraee
 
Texto sobre la Consulta Previa/Conamaq-Cidob
Texto sobre la Consulta Previa/Conamaq-CidobTexto sobre la Consulta Previa/Conamaq-Cidob
Texto sobre la Consulta Previa/Conamaq-Cidobsomossur
 
Boletín 08/03/2017
Boletín 08/03/2017Boletín 08/03/2017
Boletín 08/03/2017Openbank
 
Come creare e gestire campagne Google AdWords per E-Commerce | La settimana d...
Come creare e gestire campagne Google AdWords per E-Commerce | La settimana d...Come creare e gestire campagne Google AdWords per E-Commerce | La settimana d...
Come creare e gestire campagne Google AdWords per E-Commerce | La settimana d...Ruben Vezzoli
 

Viewers also liked (18)

Using jsPerf correctly
Using jsPerf correctlyUsing jsPerf correctly
Using jsPerf correctly
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
 
iOS Coding Best Practices
iOS Coding Best PracticesiOS Coding Best Practices
iOS Coding Best Practices
 
Know yourengines velocity2011
Know yourengines velocity2011Know yourengines velocity2011
Know yourengines velocity2011
 
An Educators Guide to Podcasting and Broadcasting by @TeacherCast
An Educators Guide to Podcasting and Broadcasting by @TeacherCastAn Educators Guide to Podcasting and Broadcasting by @TeacherCast
An Educators Guide to Podcasting and Broadcasting by @TeacherCast
 
Al-Huda CIBE- 4th African Islamic Finance Summit
Al-Huda CIBE- 4th African Islamic Finance SummitAl-Huda CIBE- 4th African Islamic Finance Summit
Al-Huda CIBE- 4th African Islamic Finance Summit
 
Job interview techniques
Job interview techniques Job interview techniques
Job interview techniques
 
India’s women bankers at the helm
India’s women bankers at the helmIndia’s women bankers at the helm
India’s women bankers at the helm
 
Compliance
ComplianceCompliance
Compliance
 
Obama chronicles the book
Obama chronicles the bookObama chronicles the book
Obama chronicles the book
 
Modelo kata de competencia digital. isdi
Modelo kata de competencia digital. isdiModelo kata de competencia digital. isdi
Modelo kata de competencia digital. isdi
 
Turing machine
Turing  machine Turing  machine
Turing machine
 
ガチでビジネス DALIを使った照明制御
ガチでビジネス DALIを使った照明制御ガチでビジネス DALIを使った照明制御
ガチでビジネス DALIを使った照明制御
 
Samad Oraee - Learn More About Foot Pain
Samad Oraee - Learn More About Foot PainSamad Oraee - Learn More About Foot Pain
Samad Oraee - Learn More About Foot Pain
 
Texto sobre la Consulta Previa/Conamaq-Cidob
Texto sobre la Consulta Previa/Conamaq-CidobTexto sobre la Consulta Previa/Conamaq-Cidob
Texto sobre la Consulta Previa/Conamaq-Cidob
 
Boletín 08/03/2017
Boletín 08/03/2017Boletín 08/03/2017
Boletín 08/03/2017
 
Come creare e gestire campagne Google AdWords per E-Commerce | La settimana d...
Come creare e gestire campagne Google AdWords per E-Commerce | La settimana d...Come creare e gestire campagne Google AdWords per E-Commerce | La settimana d...
Come creare e gestire campagne Google AdWords per E-Commerce | La settimana d...
 

More from Thomas Fuchs

Zepto and the rise of the JavaScript Micro-Frameworks
Zepto and the rise of the JavaScript Micro-FrameworksZepto and the rise of the JavaScript Micro-Frameworks
Zepto and the rise of the JavaScript Micro-FrameworksThomas Fuchs
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
I Can't Believe It's Not Flash
I Can't Believe It's Not FlashI Can't Believe It's Not Flash
I Can't Believe It's Not FlashThomas Fuchs
 
Prototype & Scriptaculous
Prototype  & ScriptaculousPrototype  & Scriptaculous
Prototype & ScriptaculousThomas Fuchs
 
Adventures In JavaScript Testing
Adventures In JavaScript TestingAdventures In JavaScript Testing
Adventures In JavaScript TestingThomas Fuchs
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails IntroductionThomas Fuchs
 
Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Thomas Fuchs
 

More from Thomas Fuchs (9)

Zepto and the rise of the JavaScript Micro-Frameworks
Zepto and the rise of the JavaScript Micro-FrameworksZepto and the rise of the JavaScript Micro-Frameworks
Zepto and the rise of the JavaScript Micro-Frameworks
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
I Can't Believe It's Not Flash
I Can't Believe It's Not FlashI Can't Believe It's Not Flash
I Can't Believe It's Not Flash
 
Prototype & Scriptaculous
Prototype  & ScriptaculousPrototype  & Scriptaculous
Prototype & Scriptaculous
 
Textorize
TextorizeTextorize
Textorize
 
Adventures In JavaScript Testing
Adventures In JavaScript TestingAdventures In JavaScript Testing
Adventures In JavaScript Testing
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails Introduction
 
Twistori Tech
Twistori TechTwistori Tech
Twistori Tech
 
Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)
 

Extreme JavaScript Performance