SlideShare une entreprise Scribd logo
1  sur  35
Télécharger pour lire hors ligne
MITIGATING ADVERTISEMENT IMPACT
ON PAGE PERFORMANCE by Ismail Elshareef
Friday, October 22, 2010
ISMAIL
ELSHAREEF
Edmunds, Inc.
@codeish
@EdmundsLabs
Friday, October 22, 2010
EDMUNDS, INC.
Online since 1995
Properties:
150M+ page views/month
Revenue = Ads + Leads
Friday, October 22, 2010
IN 2008 ... A VISION WAS BORN
Friday, October 22, 2010
REDESIGN OBJECTIVES
PERFORMANCE
(Page onLoad in < 1.5 sec)
RICHER CONTENT
(Flash, video, slicker UXD, ...etc)
BETTER REVENUE
(Only positive impact on ad impressions)
Friday, October 22, 2010
OUR DILEMMA
3rd-PARTY CODE PERFORMANCE
UXD
Friday, October 22, 2010
Fast WITHOUT
3rd
Party
Fast WITH 3rd
Party Code
Friday, October 22, 2010
• Fixed width/height
• Easy to late-load
• Sandboxed Code
iFrame JavaScriptOR
• Cannot lazy-load
• Access to DOM
• Richer Content
FORMS OF 3RD
-PARTY CODE
• Disadvantage
• Advantage
Friday, October 22, 2010
MISSION:
CONTROL 3RD
-PARTY JS
Friday, October 22, 2010
INITIAL ATTEMPTS
applies to 3rd
-Party JavaScript Code ONLY
Override document.write
iFrame’n’Copy
Friday, October 22, 2010
INITIAL ATTEMPTS
applies to 3rd
-Party JavaScript Code ONLY
Override document.write
iFrame’n’Copy
WE LEARNED THAT ...
3rd-Party JS Code should be treated as
Friday, October 22, 2010
(I) CAN’T CONTROL IT ALL
(II) SPEED UP WHAT YOU CAN
(Your code and lazy-loadable code)
(III) DEFER THE REST
(All code that cannot be lazy-loaded)
OUR NEWFOUND CREED
Friday, October 22, 2010
JAVASCRIPT
LOADER
Friday, October 22, 2010
3RD
-PARTY
HANDLING
LOGIC
A
Is this an ad?
Is this a JS
ad?
Is this a JS
module?
NO
YES
Create
placeholder
markup
NO
Request JS file
after loader is
included
B
Create iframe
placeholder
markup
YES
NO
Add JS chunk to
Loader loading the
iframe after page
load event
Create
placeholder
markup
Request JS file
after loader is
included
B
Create iFrame
placeholder
markup
Lazy-load iFrame
with JS Loader
YES
DONE
DONE
Friday, October 22, 2010
3RD
-PARTY
JAVASCRIPT
HANDLING
LOGIC
B
JS
Components?
DONE
NO
load in a hidden DIV
YES
.html?
disableallthird
party=yes
.html?
disableallads=
yes
.html?
disableadnum
ber=[int]
YES
is ad?
NO
NO
YES
YES
NO
is ad
position ==
[int]?
YES
YES
<script> is done loading
move content to
placeholder (collapse
when appropriate)
NO NO
Friday, October 22, 2010
HOW DOES THE LOADER WORK?
Friday, October 22, 2010
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
HOW DOES THE LOADER WORK?
Friday, October 22, 2010
<script type="text/javascript">
//<![CDATA[
PAGESETUP = {
timer: {start: (new Date).getTime()},
files: [],
modules: {},
queue: {high:[], normal:[], low:[]},
addModule: function(mod) {
if (PAGESETUP.modules[mod]) {
++PAGESETUP.modules[mod];
} else {
PAGESETUP.modules[mod] = 1;
}
},
execControls: function(start) {
if (!this.merged) {
this.merged = PAGESETUP.queue.high;
this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low);
}
var merged = this.merged;
setTimeout(function() {
var item = merged.shift();
if (merged.length > 0) {
setTimeout(arguments.callee, 10);
}
item.call();
}, 0);
},
addControl: function(fn, priority) {
switch(priority) {
case 'high':
this.queue.high.push(fn);
break;
case 'low':
this.queue.low.push(fn);
break;
case 'normal':
default:
this.queue.normal.push(fn);
break;
}
}
};
//]]>
</script>
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
HOW DOES THE LOADER WORK?
Friday, October 22, 2010
var merged = this.merged;
setTimeout(function() {
var item = merged.shift();
if (merged.length > 0) {
setTimeout(arguments.callee, 10);
}
item.call();
}, 0);
},
addControl: function(fn, priority) {
switch(priority) {
case 'high':
this.queue.high.push(fn);
break;
case 'low':
this.queue.low.push(fn);
break;
case 'normal':
default:
this.queue.normal.push(fn);
break;
}
}
};
//]]>
</script>
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
HOW DOES THE LOADER WORK?
Friday, October 22, 2010
<script type="text/javascript">
//<![CDATA[
PAGESETUP = {
timer: {start: (new Date).getTime()},
files: [],
modules: {},
queue: {high:[], normal:[], low:[]},
addModule: function(mod) {
if (PAGESETUP.modules[mod]) {
++PAGESETUP.modules[mod];
} else {
PAGESETUP.modules[mod] = 1;
}
},
execControls: function(start) {
if (!this.merged) {
this.merged = PAGESETUP.queue.high;
this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low);
}
var merged = this.merged;
setTimeout(function() {
var item = merged.shift();
if (merged.length > 0) {
setTimeout(arguments.callee, 10);
}
item.call();
}, 0);
},
addControl: function(fn, priority) {
switch(priority) {
case 'high':
this.queue.high.push(fn);
break;
case 'low':
this.queue.low.push(fn);
break;
case 'normal':
default:
this.queue.normal.push(fn);
break;
}
}
};
//]]>
</script>
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
HOW DOES THE LOADER WORK?
Friday, October 22, 2010
<script type="text/javascript">
//<![CDATA[
PAGESETUP = {
timer: {start: (new Date).getTime()},
files: [],
modules: {},
queue: {high:[], normal:[], low:[]},
addModule: function(mod) {
if (PAGESETUP.modules[mod]) {
++PAGESETUP.modules[mod];
} else {
PAGESETUP.modules[mod] = 1;
}
},
execControls: function(start) {
if (!this.merged) {
this.merged = PAGESETUP.queue.high;
this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low);
}
var merged = this.merged;
setTimeout(function() {
var item = merged.shift();
if (merged.length > 0) {
setTimeout(arguments.callee, 10);
}
item.call();
}, 0);
},
addControl: function(fn, priority) {
switch(priority) {
case 'high':
this.queue.high.push(fn);
break;
case 'low':
this.queue.low.push(fn);
break;
case 'normal':
default:
this.queue.normal.push(fn);
break;
}
}
};
//]]>
</script>
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
!"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7
HOW DOES THE LOADER WORK?
Friday, October 22, 2010
<script type="text/javascript">
//<![CDATA[
PAGESETUP = {
timer: {start: (new Date).getTime()},
files: [],
modules: {},
queue: {high:[], normal:[], low:[]},
addModule: function(mod) {
if (PAGESETUP.modules[mod]) {
++PAGESETUP.modules[mod];
} else {
PAGESETUP.modules[mod] = 1;
}
},
execControls: function(start) {
if (!this.merged) {
this.merged = PAGESETUP.queue.high;
this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low);
}
var merged = this.merged;
setTimeout(function() {
var item = merged.shift();
if (merged.length > 0) {
setTimeout(arguments.callee, 10);
}
item.call();
}, 0);
},
addControl: function(fn, priority) {
switch(priority) {
case 'high':
this.queue.high.push(fn);
break;
case 'low':
this.queue.low.push(fn);
break;
case 'normal':
default:
this.queue.normal.push(fn);
break;
}
}
};
//]]>
</script>
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
!"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7
HOW DOES THE LOADER WORK?
- Loads global core libs (with YUI libs)
Friday, October 22, 2010
<script type="text/javascript">
//<![CDATA[
PAGESETUP = {
timer: {start: (new Date).getTime()},
files: [],
modules: {},
queue: {high:[], normal:[], low:[]},
addModule: function(mod) {
if (PAGESETUP.modules[mod]) {
++PAGESETUP.modules[mod];
} else {
PAGESETUP.modules[mod] = 1;
}
},
execControls: function(start) {
if (!this.merged) {
this.merged = PAGESETUP.queue.high;
this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low);
}
var merged = this.merged;
setTimeout(function() {
var item = merged.shift();
if (merged.length > 0) {
setTimeout(arguments.callee, 10);
}
item.call();
}, 0);
},
addControl: function(fn, priority) {
switch(priority) {
case 'high':
this.queue.high.push(fn);
break;
case 'low':
this.queue.low.push(fn);
break;
case 'normal':
default:
this.queue.normal.push(fn);
break;
}
}
};
//]]>
</script>
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
!"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7
HOW DOES THE LOADER WORK?
- Loads global core libs (with YUI libs)
- Executes JS chunks in priority in 25 ms intv.
Friday, October 22, 2010
<script type="text/javascript">
//<![CDATA[
PAGESETUP = {
timer: {start: (new Date).getTime()},
files: [],
modules: {},
queue: {high:[], normal:[], low:[]},
addModule: function(mod) {
if (PAGESETUP.modules[mod]) {
++PAGESETUP.modules[mod];
} else {
PAGESETUP.modules[mod] = 1;
}
},
execControls: function(start) {
if (!this.merged) {
this.merged = PAGESETUP.queue.high;
this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low);
}
var merged = this.merged;
setTimeout(function() {
var item = merged.shift();
if (merged.length > 0) {
setTimeout(arguments.callee, 10);
}
item.call();
}, 0);
},
addControl: function(fn, priority) {
switch(priority) {
case 'high':
this.queue.high.push(fn);
break;
case 'low':
this.queue.low.push(fn);
break;
case 'normal':
default:
this.queue.normal.push(fn);
break;
}
}
};
//]]>
</script>
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
!"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7
HOW DOES THE LOADER WORK?
- Loads global core libs (with YUI libs)
- Executes JS chunks in priority in 25 ms intv.
- Has debugging features ?jsflag=full
Friday, October 22, 2010
<script type="text/javascript">
//<![CDATA[
PAGESETUP = {
timer: {start: (new Date).getTime()},
files: [],
modules: {},
queue: {high:[], normal:[], low:[]},
addModule: function(mod) {
if (PAGESETUP.modules[mod]) {
++PAGESETUP.modules[mod];
} else {
PAGESETUP.modules[mod] = 1;
}
},
execControls: function(start) {
if (!this.merged) {
this.merged = PAGESETUP.queue.high;
this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low);
}
var merged = this.merged;
setTimeout(function() {
var item = merged.shift();
if (merged.length > 0) {
setTimeout(arguments.callee, 10);
}
item.call();
}, 0);
},
addControl: function(fn, priority) {
switch(priority) {
case 'high':
this.queue.high.push(fn);
break;
case 'low':
this.queue.low.push(fn);
break;
case 'normal':
default:
this.queue.normal.push(fn);
break;
}
}
};
//]]>
</script>
addModule
execControl
addControl
timer
files
modules
queue
PAGESETUP
!"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7
HOW DOES THE LOADER WORK?
- Loads global core libs (with YUI libs)
- Executes JS chunks in priority in 25 ms intv.
- Has debugging features ?jsflag=full
- Ability to exclude 3rd party code
Friday, October 22, 2010
WHY CREATE OUR OWN LOADER?
Run JS chunks in order of priority
Allow a Debug Mode
Decouple from DOM events
Friday, October 22, 2010
3RD
-PARTY CODE WITH JS LOADER
Lazy-load in desired priority
iFrames JavaScriptOR
Include after Loader include
<iframe id=”ad1” width=”300”
height=”250”>
// add JS chunk to loader
...
...
...
<script src=”loader.js”></script>
// execute JS chunk through loader
</body>
<div id=”ad2”></div>
...
...
...
...
...
<script src=”loader.js”></script>
// Handle JavaScript ads
</body>
Friday, October 22, 2010
With Ads
Without Ads
INSIDELINE.COM STATS
Friday, October 22, 2010
ANOTHER VISION WAS BORN
Friday, October 22, 2010
HTTP REQUESTS
0
50
100
150
200
Homepage New Cars Used Cars
Legacy Site Beta Site
152 135 111
44 72 44
Friday, October 22, 2010
PAGESPEED SCORES
0
22.5
45
67.5
90
PageSpeed
Legacy Site Beta Site
8765
Friday, October 22, 2010
INITIAL RESULTS
17%Total PageViews Per Session
Friday, October 22, 2010
(I) CAN’T CONTROL IT ALL
(II) SPEED UP WHAT YOU CAN
(Your code and lazy-loadable code)
(III) DEFER THE REST
(All code that cannot be lazy-loaded)
AGAIN ... OUR NEWFOUND CREED
Friday, October 22, 2010
WE ARE HIRING!
http://www.edmunds.com/help/about/jobs/
Friday, October 22, 2010
THANK YOU!
ISMAIL ELSHAREEF
Edmunds, Inc.
WE ARE HIRING!
http://www.edmunds.com/help/about/jobs/
@codeish
@EdmundsLabs
Photo Credits:
http://farm3.static.flickr.com/2203/2498445479_064841a97d_o.jpg
http://jcreviews.files.wordpress.com/2010/03/battlestar-galactica.jpg
http://img.wallpaperstock.net:81/crossroads-in-life-wallpapers_10124_1600x1200.jpg
http://upload.wikimedia.org/wikipedia/commons/0/01/Stapler-swingline-red.jpg
Friday, October 22, 2010

Contenu connexe

Tendances

Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJSSylvain Zimmer
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Ismael Celis
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitRebecca Murphey
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperJon Kruger
 
jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace PatternDiego Fleury
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End DevsRebecca Murphey
 
Testable, Object-Oriented JavaScript
Testable, Object-Oriented JavaScriptTestable, Object-Oriented JavaScript
Testable, Object-Oriented JavaScriptJon Kruger
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UIRebecca Murphey
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeRebecca Murphey
 
HTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranHTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranRobert Nyman
 
$q and Promises in AngularJS
$q and Promises in AngularJS $q and Promises in AngularJS
$q and Promises in AngularJS a_sharif
 
Django Celery - A distributed task queue
Django Celery - A distributed task queueDjango Celery - A distributed task queue
Django Celery - A distributed task queueAlex Eftimie
 
History of jQuery
History of jQueryHistory of jQuery
History of jQueryjeresig
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 
Electron: From Beginner to Pro
Electron: From Beginner to ProElectron: From Beginner to Pro
Electron: From Beginner to ProChris Griffith
 
HTML5 & The Open Web - at Nackademin
HTML5 & The Open Web -  at NackademinHTML5 & The Open Web -  at Nackademin
HTML5 & The Open Web - at NackademinRobert Nyman
 

Tendances (20)

Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJS
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
 
jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace Pattern
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
Testable, Object-Oriented JavaScript
Testable, Object-Oriented JavaScriptTestable, Object-Oriented JavaScript
Testable, Object-Oriented JavaScript
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UI
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Dojo Confessions
Dojo ConfessionsDojo Confessions
Dojo Confessions
 
Booting Weblogic - OOW14
Booting Weblogic - OOW14Booting Weblogic - OOW14
Booting Weblogic - OOW14
 
HTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranHTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - Altran
 
$q and Promises in AngularJS
$q and Promises in AngularJS $q and Promises in AngularJS
$q and Promises in AngularJS
 
Django Celery - A distributed task queue
Django Celery - A distributed task queueDjango Celery - A distributed task queue
Django Celery - A distributed task queue
 
History of jQuery
History of jQueryHistory of jQuery
History of jQuery
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Electron: From Beginner to Pro
Electron: From Beginner to ProElectron: From Beginner to Pro
Electron: From Beginner to Pro
 
HTML5 & The Open Web - at Nackademin
HTML5 & The Open Web -  at NackademinHTML5 & The Open Web -  at Nackademin
HTML5 & The Open Web - at Nackademin
 

Similaire à Mitigating Advertisement Impact on Page Performance

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup PerformanceJustin Cataldo
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensionserwanl
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutes[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutesGlobant
 
How to create a magento controller in magento extension
How to create a magento controller in magento extensionHow to create a magento controller in magento extension
How to create a magento controller in magento extensionHendy Irawan
 
Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)Eyal Vardi
 
Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3Carlos Brando
 
준비하세요 Angular js 2.0
준비하세요 Angular js 2.0준비하세요 Angular js 2.0
준비하세요 Angular js 2.0Jeado Ko
 
HTML5 e CSS3 (slides della sessione tenuta al DIMI di Udine)
HTML5 e CSS3 (slides della sessione tenuta al DIMI di Udine) HTML5 e CSS3 (slides della sessione tenuta al DIMI di Udine)
HTML5 e CSS3 (slides della sessione tenuta al DIMI di Udine) Gabriele Gigliotti
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade ServerlessKatyShimizu
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade ServerlessKatyShimizu
 
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...PHP Conference Argentina
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your AppLuca Mearelli
 
Modern frontend development with VueJs
Modern frontend development with VueJsModern frontend development with VueJs
Modern frontend development with VueJsTudor Barbu
 
Pengenalan AngularJS
Pengenalan AngularJSPengenalan AngularJS
Pengenalan AngularJSEdi Santoso
 

Similaire à Mitigating Advertisement Impact on Page Performance (20)

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 
JavaScript Refactoring
JavaScript RefactoringJavaScript Refactoring
JavaScript Refactoring
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutes[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutes
 
How to create a magento controller in magento extension
How to create a magento controller in magento extensionHow to create a magento controller in magento extension
How to create a magento controller in magento extension
 
Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)
 
Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3
 
준비하세요 Angular js 2.0
준비하세요 Angular js 2.0준비하세요 Angular js 2.0
준비하세요 Angular js 2.0
 
Angular 1.5 & ES6
Angular 1.5  & ES6Angular 1.5  & ES6
Angular 1.5 & ES6
 
HTML5 e CSS3 (slides della sessione tenuta al DIMI di Udine)
HTML5 e CSS3 (slides della sessione tenuta al DIMI di Udine) HTML5 e CSS3 (slides della sessione tenuta al DIMI di Udine)
HTML5 e CSS3 (slides della sessione tenuta al DIMI di Udine)
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
 
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
 
Modern frontend development with VueJs
Modern frontend development with VueJsModern frontend development with VueJs
Modern frontend development with VueJs
 
Pengenalan AngularJS
Pengenalan AngularJSPengenalan AngularJS
Pengenalan AngularJS
 

Dernier

SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 

Dernier (20)

SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 

Mitigating Advertisement Impact on Page Performance

  • 1. MITIGATING ADVERTISEMENT IMPACT ON PAGE PERFORMANCE by Ismail Elshareef Friday, October 22, 2010
  • 3. EDMUNDS, INC. Online since 1995 Properties: 150M+ page views/month Revenue = Ads + Leads Friday, October 22, 2010
  • 4. IN 2008 ... A VISION WAS BORN Friday, October 22, 2010
  • 5. REDESIGN OBJECTIVES PERFORMANCE (Page onLoad in < 1.5 sec) RICHER CONTENT (Flash, video, slicker UXD, ...etc) BETTER REVENUE (Only positive impact on ad impressions) Friday, October 22, 2010
  • 6. OUR DILEMMA 3rd-PARTY CODE PERFORMANCE UXD Friday, October 22, 2010
  • 7. Fast WITHOUT 3rd Party Fast WITH 3rd Party Code Friday, October 22, 2010
  • 8. • Fixed width/height • Easy to late-load • Sandboxed Code iFrame JavaScriptOR • Cannot lazy-load • Access to DOM • Richer Content FORMS OF 3RD -PARTY CODE • Disadvantage • Advantage Friday, October 22, 2010
  • 10. INITIAL ATTEMPTS applies to 3rd -Party JavaScript Code ONLY Override document.write iFrame’n’Copy Friday, October 22, 2010
  • 11. INITIAL ATTEMPTS applies to 3rd -Party JavaScript Code ONLY Override document.write iFrame’n’Copy WE LEARNED THAT ... 3rd-Party JS Code should be treated as Friday, October 22, 2010
  • 12. (I) CAN’T CONTROL IT ALL (II) SPEED UP WHAT YOU CAN (Your code and lazy-loadable code) (III) DEFER THE REST (All code that cannot be lazy-loaded) OUR NEWFOUND CREED Friday, October 22, 2010
  • 14. 3RD -PARTY HANDLING LOGIC A Is this an ad? Is this a JS ad? Is this a JS module? NO YES Create placeholder markup NO Request JS file after loader is included B Create iframe placeholder markup YES NO Add JS chunk to Loader loading the iframe after page load event Create placeholder markup Request JS file after loader is included B Create iFrame placeholder markup Lazy-load iFrame with JS Loader YES DONE DONE Friday, October 22, 2010
  • 15. 3RD -PARTY JAVASCRIPT HANDLING LOGIC B JS Components? DONE NO load in a hidden DIV YES .html? disableallthird party=yes .html? disableallads= yes .html? disableadnum ber=[int] YES is ad? NO NO YES YES NO is ad position == [int]? YES YES <script> is done loading move content to placeholder (collapse when appropriate) NO NO Friday, October 22, 2010
  • 16. HOW DOES THE LOADER WORK? Friday, October 22, 2010
  • 18. <script type="text/javascript"> //<![CDATA[ PAGESETUP = { timer: {start: (new Date).getTime()}, files: [], modules: {}, queue: {high:[], normal:[], low:[]}, addModule: function(mod) { if (PAGESETUP.modules[mod]) { ++PAGESETUP.modules[mod]; } else { PAGESETUP.modules[mod] = 1; } }, execControls: function(start) { if (!this.merged) { this.merged = PAGESETUP.queue.high; this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low); } var merged = this.merged; setTimeout(function() { var item = merged.shift(); if (merged.length > 0) { setTimeout(arguments.callee, 10); } item.call(); }, 0); }, addControl: function(fn, priority) { switch(priority) { case 'high': this.queue.high.push(fn); break; case 'low': this.queue.low.push(fn); break; case 'normal': default: this.queue.normal.push(fn); break; } } }; //]]> </script> addModule execControl addControl timer files modules queue PAGESETUP HOW DOES THE LOADER WORK? Friday, October 22, 2010
  • 19. var merged = this.merged; setTimeout(function() { var item = merged.shift(); if (merged.length > 0) { setTimeout(arguments.callee, 10); } item.call(); }, 0); }, addControl: function(fn, priority) { switch(priority) { case 'high': this.queue.high.push(fn); break; case 'low': this.queue.low.push(fn); break; case 'normal': default: this.queue.normal.push(fn); break; } } }; //]]> </script> addModule execControl addControl timer files modules queue PAGESETUP HOW DOES THE LOADER WORK? Friday, October 22, 2010
  • 20. <script type="text/javascript"> //<![CDATA[ PAGESETUP = { timer: {start: (new Date).getTime()}, files: [], modules: {}, queue: {high:[], normal:[], low:[]}, addModule: function(mod) { if (PAGESETUP.modules[mod]) { ++PAGESETUP.modules[mod]; } else { PAGESETUP.modules[mod] = 1; } }, execControls: function(start) { if (!this.merged) { this.merged = PAGESETUP.queue.high; this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low); } var merged = this.merged; setTimeout(function() { var item = merged.shift(); if (merged.length > 0) { setTimeout(arguments.callee, 10); } item.call(); }, 0); }, addControl: function(fn, priority) { switch(priority) { case 'high': this.queue.high.push(fn); break; case 'low': this.queue.low.push(fn); break; case 'normal': default: this.queue.normal.push(fn); break; } } }; //]]> </script> addModule execControl addControl timer files modules queue PAGESETUP HOW DOES THE LOADER WORK? Friday, October 22, 2010
  • 21. <script type="text/javascript"> //<![CDATA[ PAGESETUP = { timer: {start: (new Date).getTime()}, files: [], modules: {}, queue: {high:[], normal:[], low:[]}, addModule: function(mod) { if (PAGESETUP.modules[mod]) { ++PAGESETUP.modules[mod]; } else { PAGESETUP.modules[mod] = 1; } }, execControls: function(start) { if (!this.merged) { this.merged = PAGESETUP.queue.high; this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low); } var merged = this.merged; setTimeout(function() { var item = merged.shift(); if (merged.length > 0) { setTimeout(arguments.callee, 10); } item.call(); }, 0); }, addControl: function(fn, priority) { switch(priority) { case 'high': this.queue.high.push(fn); break; case 'low': this.queue.low.push(fn); break; case 'normal': default: this.queue.normal.push(fn); break; } } }; //]]> </script> addModule execControl addControl timer files modules queue PAGESETUP !"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7 HOW DOES THE LOADER WORK? Friday, October 22, 2010
  • 22. <script type="text/javascript"> //<![CDATA[ PAGESETUP = { timer: {start: (new Date).getTime()}, files: [], modules: {}, queue: {high:[], normal:[], low:[]}, addModule: function(mod) { if (PAGESETUP.modules[mod]) { ++PAGESETUP.modules[mod]; } else { PAGESETUP.modules[mod] = 1; } }, execControls: function(start) { if (!this.merged) { this.merged = PAGESETUP.queue.high; this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low); } var merged = this.merged; setTimeout(function() { var item = merged.shift(); if (merged.length > 0) { setTimeout(arguments.callee, 10); } item.call(); }, 0); }, addControl: function(fn, priority) { switch(priority) { case 'high': this.queue.high.push(fn); break; case 'low': this.queue.low.push(fn); break; case 'normal': default: this.queue.normal.push(fn); break; } } }; //]]> </script> addModule execControl addControl timer files modules queue PAGESETUP !"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7 HOW DOES THE LOADER WORK? - Loads global core libs (with YUI libs) Friday, October 22, 2010
  • 23. <script type="text/javascript"> //<![CDATA[ PAGESETUP = { timer: {start: (new Date).getTime()}, files: [], modules: {}, queue: {high:[], normal:[], low:[]}, addModule: function(mod) { if (PAGESETUP.modules[mod]) { ++PAGESETUP.modules[mod]; } else { PAGESETUP.modules[mod] = 1; } }, execControls: function(start) { if (!this.merged) { this.merged = PAGESETUP.queue.high; this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low); } var merged = this.merged; setTimeout(function() { var item = merged.shift(); if (merged.length > 0) { setTimeout(arguments.callee, 10); } item.call(); }, 0); }, addControl: function(fn, priority) { switch(priority) { case 'high': this.queue.high.push(fn); break; case 'low': this.queue.low.push(fn); break; case 'normal': default: this.queue.normal.push(fn); break; } } }; //]]> </script> addModule execControl addControl timer files modules queue PAGESETUP !"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7 HOW DOES THE LOADER WORK? - Loads global core libs (with YUI libs) - Executes JS chunks in priority in 25 ms intv. Friday, October 22, 2010
  • 24. <script type="text/javascript"> //<![CDATA[ PAGESETUP = { timer: {start: (new Date).getTime()}, files: [], modules: {}, queue: {high:[], normal:[], low:[]}, addModule: function(mod) { if (PAGESETUP.modules[mod]) { ++PAGESETUP.modules[mod]; } else { PAGESETUP.modules[mod] = 1; } }, execControls: function(start) { if (!this.merged) { this.merged = PAGESETUP.queue.high; this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low); } var merged = this.merged; setTimeout(function() { var item = merged.shift(); if (merged.length > 0) { setTimeout(arguments.callee, 10); } item.call(); }, 0); }, addControl: function(fn, priority) { switch(priority) { case 'high': this.queue.high.push(fn); break; case 'low': this.queue.low.push(fn); break; case 'normal': default: this.queue.normal.push(fn); break; } } }; //]]> </script> addModule execControl addControl timer files modules queue PAGESETUP !"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7 HOW DOES THE LOADER WORK? - Loads global core libs (with YUI libs) - Executes JS chunks in priority in 25 ms intv. - Has debugging features ?jsflag=full Friday, October 22, 2010
  • 25. <script type="text/javascript"> //<![CDATA[ PAGESETUP = { timer: {start: (new Date).getTime()}, files: [], modules: {}, queue: {high:[], normal:[], low:[]}, addModule: function(mod) { if (PAGESETUP.modules[mod]) { ++PAGESETUP.modules[mod]; } else { PAGESETUP.modules[mod] = 1; } }, execControls: function(start) { if (!this.merged) { this.merged = PAGESETUP.queue.high; this.merged = this.merged.concat(PAGESETUP.queue.normal).concat(PAGESETUP.queue.low); } var merged = this.merged; setTimeout(function() { var item = merged.shift(); if (merged.length > 0) { setTimeout(arguments.callee, 10); } item.call(); }, 0); }, addControl: function(fn, priority) { switch(priority) { case 'high': this.queue.high.push(fn); break; case 'low': this.queue.low.push(fn); break; case 'normal': default: this.queue.normal.push(fn); break; } } }; //]]> </script> addModule execControl addControl timer files modules queue PAGESETUP !"#$%&'(')&*+,'*-'./010"#$%&',("$#+,&0'2.'3.0&%.4305*$.4305*$6/",7!."#$%&'7 HOW DOES THE LOADER WORK? - Loads global core libs (with YUI libs) - Executes JS chunks in priority in 25 ms intv. - Has debugging features ?jsflag=full - Ability to exclude 3rd party code Friday, October 22, 2010
  • 26. WHY CREATE OUR OWN LOADER? Run JS chunks in order of priority Allow a Debug Mode Decouple from DOM events Friday, October 22, 2010
  • 27. 3RD -PARTY CODE WITH JS LOADER Lazy-load in desired priority iFrames JavaScriptOR Include after Loader include <iframe id=”ad1” width=”300” height=”250”> // add JS chunk to loader ... ... ... <script src=”loader.js”></script> // execute JS chunk through loader </body> <div id=”ad2”></div> ... ... ... ... ... <script src=”loader.js”></script> // Handle JavaScript ads </body> Friday, October 22, 2010
  • 28. With Ads Without Ads INSIDELINE.COM STATS Friday, October 22, 2010
  • 29. ANOTHER VISION WAS BORN Friday, October 22, 2010
  • 30. HTTP REQUESTS 0 50 100 150 200 Homepage New Cars Used Cars Legacy Site Beta Site 152 135 111 44 72 44 Friday, October 22, 2010
  • 31. PAGESPEED SCORES 0 22.5 45 67.5 90 PageSpeed Legacy Site Beta Site 8765 Friday, October 22, 2010
  • 32. INITIAL RESULTS 17%Total PageViews Per Session Friday, October 22, 2010
  • 33. (I) CAN’T CONTROL IT ALL (II) SPEED UP WHAT YOU CAN (Your code and lazy-loadable code) (III) DEFER THE REST (All code that cannot be lazy-loaded) AGAIN ... OUR NEWFOUND CREED Friday, October 22, 2010
  • 35. THANK YOU! ISMAIL ELSHAREEF Edmunds, Inc. WE ARE HIRING! http://www.edmunds.com/help/about/jobs/ @codeish @EdmundsLabs Photo Credits: http://farm3.static.flickr.com/2203/2498445479_064841a97d_o.jpg http://jcreviews.files.wordpress.com/2010/03/battlestar-galactica.jpg http://img.wallpaperstock.net:81/crossroads-in-life-wallpapers_10124_1600x1200.jpg http://upload.wikimedia.org/wikipedia/commons/0/01/Stapler-swingline-red.jpg Friday, October 22, 2010