adaptive static resource optimization

Post on 24-Feb-2016

50 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Adaptive Static Resource Optimization. David Wei and Changhao Jiang. The AJAX Experience 2009 Sep 15, 2009 Boston, MA. Best practice: from theory to operation?. “Reduce # of HTTP Requests”. Package JS/CSS; Sprite Image. Best practice: from theory to operation?. “Reduce # of HTTP Requests”. - PowerPoint PPT Presentation

TRANSCRIPT

(c) 2009 Facebook, Inc. or its licensors.  "Facebook" is a registered trademark of Facebook, Inc.. All rights reserved. 1.0

Adaptive Static Resource Optimization

The AJAX Experience 2009Sep 15, 2009 Boston, MA

David Wei and Changhao Jiang

Best practice: from theory to operation?

“Reduce # of HTTP Requests”

Package JS/CSS; Sprite Image

Best practice: from theory to operation?

“Reduce # of HTTP Requests”

Package JS/CSS; Sprite Image

Interface & Infrastructure

Operation

1 Optimization must be adaptive

2 Adaptive Packager: Designs

3 Adaptive Packager: Operations

4 Lessons learnt

Agenda

Optimization must be adaptive

Facebook’s day-to-day challenges

• Deep Integration

• Viral Adoption

• Agile Development

Performance optimization has to be adaptive!

Perf optimization must be adaptive• Day 1: Some smart engineers start a project!<Print css tag for feature A>

<Print css tag for feature B>

<Print css tag for feature C>

<print HTML of feature A>

<print HTML of feature B>

<print HTML of feature C>

“Let’s write a new page with features A, B and C!”

• Day 2: Some smart engineers run YSlow and says…<Print css tag for feature A>

<Print css tag for feature B>

<Print css tag for feature C>

<print HTML of feature A>

<print HTML of feature B>

<print HTML of feature C>

“A & B & C are always used; let’s package them together!”

• Day 2: Awesome! <Print css tag for feature

A&B&C>

<print HTML of feature A>

<print HTML of feature B>

<print HTML of feature C>

• Day 3: feature C evolves…<Print css tag for feature A & B & C>

<print HTML of feature A>

<print HTML of feature B>

If (users_signup_for_C()) { <print HTML of feature C>}

• Day 3:<Print css tag for feature A & B & C>

<print HTML of feature A>

<print HTML of feature B>

If (users_signup_for_C()) { <print HTML of feature C>}

A&B are always used, while C is not. ..

• Day 4: feature C is deprecated<Print css tag for feature A & B & C>

<print HTML of feature A>

<print HTML of feature B>

// no one uses C { <print HTML of feature C>}

• Day 4: we start to send unused bits<Print css tag for feature A & B & C>

<print HTML of feature A>

<print HTML of feature B>

// no one uses C { <print HTML of feature C>}

It is hard to remember we should remove C here.

• One months later…<Print css tag for feature A & B & C & D & E & F & G…>

if (F is used) <print HTML of feature F>

<print HTML of feature G>

if (F is not used) { <print HTML of feature E>}

Thousands of dead CSS rules in the package.

• One months later…<Print css tag for feature A & B & C & D & E & F & G…>

if (F is used) <print HTML of feature F>

<print HTML of feature G>

if (F is not used) { <print HTML of feature E>}

Performance optimization has to be adaptive!

Thousands of dead CSS rules in the package.

Adaptive Static Resource OptimizationChallenges:• Deep Integration

• Viral Adoption

• Agile Development

Responses:• Build interface to separate

requirement declaration and delivery of static resources

• Requirement declaration: lives with HTML generation, logged

• Delivery: Globally optimized by analyzing the logged trace

Adaptive Packager: Designs

Interfaces

• Back to Day 1: require_static(A_css); <render HTML of feature

A>

require_static(B_css); <render HTML of feature B>

require_static(C_css);<render HTML of feature C>

<deliver all required CSS>

<print all rendered HTML>

Separate Declaration from actual Delivery

Global Optimization on Delivery

Requirement Declaration lives with HTML

Offline analysisPackager: Global JS/CSS Optimization

Online processrequire_static(A_css); <render HTML of

feature A>

require_static(B_css); <render HTML of feature B>

require_static(C_css); <render HTML of feature C>

<deliver all required CSS>

<print all rendered HTML>

Usage Pattern logs

Packaging algorithm

“Optimal” packages

Packager: Usage Pattern Logs

Usage Pattern logs

Page Load

1 2 3 4 5 … 100000

Page Count

10 M

1 M

100 K

20 K

10 K

1K

A.css (1 KB)

1 1 1 1 1 1

B.css (1 KB)

1 1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1 1

E.css (700B)

1 1 1

F.css (400B)

1 1

G.css (600B)

1 1 1 1 1

Packager: Cost/Benefit Model▪ To package two files A & B:

▪ “Cost”: for page requests that only uses A, we waste the bytes of B, vice versa

▪ “Benefit”: for page requests that uses both A and B: we save one round trip

▪ Bytes / Bandwidth ~ Latency

▪ “Profit” to be maximized: Benefit

– Cost

Page Load

1 2 3 4 5 … 100000

Page Count

10 M

1 M

100 K

20 K

10 K

1K

A.css (1 KB)

1 1 1 1 1 1

B.css (1 KB)

1 1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1 1

E.css (700B)

1 1 1

F.css (400B)

1 1

G.css (600B)

1 1 1 1 1

Page Load

1 2 3 4 5 … 100000

Page Count

10 M

1 M

100 K

20 K

10 K

1K

A.css (1 KB)

1 1 1 1 1 1

B.css (1 KB)

1 1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1 1

E.css (700B)

1 1 1

F.css (400B)

1 1

G.css (600B)

1 1 1 1 1

Packager: Cost/Benefit Model▪ Assume: latency = 40ms, and bandwidth = 1 Mbps▪ A+B: 40ms * 11.131M

No cost, pure gain. Definitely package

Page Load

1 2 3 4 5 … 100000

Page Count

10 M

1 M

100 K

20 K

10 K

1K

A.css (1 KB)

1 1 1 1 1 1

B.css (1 KB)

1 1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1

E.css (700B)

1 1 1

F.css (400B)

1 1

G.css (600B)

1 1 1 1 1

Packager: Cost/Benefit Model▪ Assume: latency = 40ms, and bandwidth = 1 Mbps▪ B+C: 40ms * 11.1M – 300B / 1Mbps *

0.031M

Benefit larger than cost OK to package

Page Load

1 2 3 4 5 … 100000

Page Count

10 M

1 M

100 K

20 K

10 K

1K

A.css (1 KB)

1 1 1 1 1 1

B.css (1 KB)

1 1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1

E.css (700B)

1 1 1

F.css (400B)

1 1

G.css (600B)

1 1 1 1 1

Packager: Cost/Benefit Model▪ Assume: latency = 40ms, and bandwidth = 1 Mbps▪ B+D: 40ms * 1K – 2K / 1Mbps * 11.13M

Cost larger than benefit Don’t package

Packager: Algorithms

Packaging algorithm

Page Load

1 2 3 4 5 … 100000

Page Count

10 M

1 M

100 K

20 K

10 K

1K

A.css (1 KB)

1 1 1 1 1 1

B.css (1 KB)

1 1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1

E.css (700B)

1 1 1

F.css (400B)

1 1

G.css (600B)

1 1 1 1 1

▪ Greedy algorithm▪ Simulated

Annealing▪ Clustering

algorithms▪ …

Packager: Optimal packages

Usage Pattern logs

Packaging algorithm

“Optimal” packages

Page Load

1 2 3 4 5 … 100000

Page Count

10 M

1 M

100 K

20 K

10 K

1K

A.css (1 KB)

1 1 1 1 1 1

B.css (1 KB)

1 1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1

E.css (700B)

1 1 1

F.css (400B)

1 1

G.css (50B)

1 1 1 1 1

▪ Pkg 1: A, B, C▪ Pkg 2: E, F, G

Adaptive Static Resource OptimizationAdaptive Packaging / Spriting• Cross-feature optimizations (e.g. search + ads)

• Adaptive to change of user behaviors and code developments

• Same methodology works for image spriting

Adaptive Static Resource OptimizationAdaptive progressive rendering• flush the commonly used JS/CSS/Images to the browsers,

before the page is generated at the server

• Browser downloads JS/CSS in parallel with page generation at server side

Adaptive Progressive RenderingAdaptive progressive rendering• Progressive rendering: flush the commonly used

JS/CSS/Images to the browsers, before the page is generated at the server

Adaptive progressive renderingWhat are the common JS / CSS should we flush?

Usage Pattern logs

Page Load

home

profile

home

profile

photo

Page Count

10 M 1 M 100 K

20 K 10 K

A.css (1 KB)

1 1 1 1 1

B.css (1 KB)

1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1

E.css (700B)

1 1

F.css (400B)

1 1

G.css (600B)

1 1 1

Adaptive progressive renderingSum on the page name:

Page Load

home

profile

home

profile

photo

Page Count

10 M 1 M 100 K

20 K 10 K

A.css (1 KB)

1 1 1 1 1

B.css (1 KB)

1 1 1 1 1

C.css (300B)

1 1 1

D.css (2 KB)

1

E.css (700B)

1 1

F.css (400B)

1 1

G.css (600B)

1 1 1

Page Load

home

profile

photo

Page Count

10.1 M

1.02 M

10 K

A.css (1 KB)

10.1M

1.02M

10K

B.css (1 KB)

10.1M

1.02M

10K

C.css (300B)

10.1M

1M

D.css (2 KB)

10M

E.css (700B)

0.02M

10K

F.css (400B)

0.02M

10K

G.css (600B)

10M 0.02M

10K

Adaptive progressive renderingRemove the rare usages

Page Load

home

profile

photo

Page Count

10.1 M

1.02 M

10 K

A.css (1 KB)

10.1M

1.02M

10K

B.css (1 KB)

10.1M

1.02M

10K

C.css (300B)

10.1M

1M

D.css (2 KB)

10M

E.css (700B)

0.02M

10K

F.css (400B)

0.02M

10K

G.css (600B)

10M 0.02M

10K

Page Load

home

profile

photo

A.css (1 KB)

Y Y Y

B.css (1 KB)

Y Y Y

C.css (300B)

Y Y

D.css (2 KB)

Y

E.css (700B)

Y

F.css (400B)

Y

G.css (600B)

Y Y

Adaptive Static Resource OptimizationAdaptive progressive rendering• More than 500 msec gain for home page end-to-end time

• Adaptive to the change of popular resources

• Need to solve issues with redirections, HTTP-only cookie and buffers

Adaptive Packager: Operations

Update frequency

• Too slow: fail to adapt to usage changes• Too fast: invalidate caches• Usually weekly• Can be smarter

Resources for new features

• No usage logs available• Developers to estimate the initial usage

pattern• Update packages one day after release, if

necessary

Deployment statussince Nov 2008• Rebalance weekly based on previous week’s

usage pattern (>100K unique usage patterns)• Javascript and CSS packaging only (image soon)

Scalable with developmentJS/CSS Code base: Nov 2008 -> Sep 2009

Date # of JS files

# of JS bytes

# of pkg at a

home.php

# of bytes at a

home.php

Nov 2008 461 4.4 MB 29 629 KB

Sep 2009 1045 6.8 MB 19 487 KB

Date # CSS files # of CSS bytes

# of pkg at a

home.php

# of bytes at a

home.php

Nov 2008 487 1.7 MB 24 69 KB

Sep 2009 938 1.8 MB 14 48 KB

Adaptive to new usages# of JS/CSS Packages served in the past month

Experiment: Adaptive Image SpritingThe puzzle of image spriting:• Thousands of virtual gifts with static images, which to

sprite?

Experiment: Adaptive Image SpritingThe puzzle of image spriting:• The answer is…

Lessons learnt

Regression detection can be trickier

“The page has 5KB more Javascripts!”

• Regression introduced by Packager?

• Or, by the code?

When data go wrong

“All models are wrong.Some models are useful.”• Not all users have 1Mbps and 40ms RTT

connections

• A/B Testing to find an optimal model

• Customized packaging for user groups• Per browser groups: ~5% improvements• Locale / IP Prefix might yield better performance

Human errors are possibleAutomatic analysis is preferable:require_static(A_css); //forgot to remove the

require_static

require_static(B_css); <render HTML of feature B>

require_static(C_css); <render HTML of feature C>

<deliver all required CSS>

<print all rendered HTML>

Summary▪ Performance optimization must be adaptive▪ Good interface helps optimization▪ Trace-based analysis is powerful▪ Always monitor the optimization effect

Thank you!

top related