Scaling A/B testing
on Netflix.com with
welcome
Alex Liu
@stinkydofu @mjr578
Micah Ransdell
a/b testing
data-driven
product development
Test 1
A
B
Test 1
A
B
C
D
E
F
G
Test 1
A
B
C
D
E
F
G
Test 2
A
B
C
D
E
F
G
Test 3
A
B
C
D
E
F
G
Test 4
A
B
C
D
E
F
G
Test 5
A
B
C
D
E
F
G
Test 6
A
B
C
D
E
F
G
Test 7
A
B
C
D
E
F
G
Test 1
A
B
C
D
E
F
G
Test 2
A
B
C
D
E
F
G
Test 3
A
B
C
D
E
F
G
Test 4
A
B
C
D
E
F
G
Test 5
A
B
C
D
E
F
G
Test 6
A
B
C
D
E
F
G
Test 7
A
B
C
D
E
F
G
2,097,152
unique experiences across
seven tests
hundreds
of new A/B tests per year
984545041164535
824477853104281
030346308437926
36618855...
2,105 566 685
CSS JSTemplates
2.5 million
unique css/js packages
per push cycle
<html/>
<link/>
<script/>
problem:
conditional dependencies
➔ Iterate Quickly
➔ Complex Concepts, Minimal Code
➔ Give the Power to the People
Why Node?
➔Templating
Packaging
Bonus Round
Templating
Payment
Test
Testing the addition of
Direct Debit
Payment
Test
Testing the addition of
Direct Debit
Payment
Test
Testing the addition of
Direct Debit
Payment
Test
Testing the addition of
Direct Debit
Payment
Test
Testing the addition of
Direct Debit
payment template
Control Cell 2 Cell 3 Cell 4 Cell 5
if if ifif if
payment templatepayment template
Control Cell 2 Cell 3 Cell 4 Cell 5
if if ifif if
payment template
Control Cell 2 Cell 3 Cell 4 Cell 5
if if ifif if
payment_method_cc payment_method_dd
payment templatepayment template
Control Cell 2 Cell 3 Cell 4 Cell 5
if if ifif if
payment_method_cc payment_method_dd
payment template
Control Cell 2 Cell 3 Cell 4 Cell 5
payment_method_cc payment_method_dd
if if if if if
payment template
Control Cell 2 Cell 3 Cell 4 Cell 5
payment_method_cc payment_method_dd
if if if if if
payment
template
Control Cell 2 Cell 3 Cell 4 Cell 5
payment_method_cc payment_method_dd
?
payment
template
Control Cell 2 Cell 3 Cell 4 Cell 5
payment_method_cc payment_method_dd
payment_method.json
payment
template
Control Cell 2 Cell 3 Cell 4 Cell 5
payment_method_cc payment_method_dd
payment_method.json
require(‘nf-template-resolver’)
Resolver Rules
Template Resolver
Mappings
require(‘nf-template-loader’)
Resolver
Template
Inclusion
Template Loader
Template
Cache
➔ Developers can combine rules
➔ Improves template legibility
➔ Increases template reuse
Benefits
Templating
➔Packaging
Bonus Round
Packaging
everything
is a module
app.js
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
app.js
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
685
files...?
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
oldSearch newSearch
dep1 dep2 dep3 dep4 dep5 dep6
sub-dep sub-dep sub-dep sub-dep sub-dep sub-dep sub-depsub-dep
app.js
problem:
conditional dependencies
RequestBuild
require(‘nf-include-when’)
oldSearch.js
newSearch.js
anatomy of a rule
require(‘nf-asset-registry’)
app.js
app.js
oldSearch.js
newSearch.js
jquery
registry
what’s in the
registry?
nf-include-when
require(‘nf-packager’)
Step 1: Get the full
dependency tree for the
requested package from the
registry.
Step 2: Run the rules.
Step 3: Filter out all deps
that resolved false.
Step 3: Filter out all deps
that resolved false.
Step 3: Filter out all deps
that resolved false.
✓
✓
Step 4: Filter out all
extraneous sub-deps.
Step 5: Concatenate the
files.
registry
javascript / css
Build
Request registry
rulespackage
➔ Leverage build time tools
➔ Leverage the server when you can
➔ Divide and conquer with modules
Take aways
Templating
Packaging
➔Bonus Round
Bonus Round
be creative
with the registry
dependency
counting
dependency
pruning
file
sizes
CSS modules
@import
CSS
analysis
and now, the
coolest part...
templates
mappings
css
javascript
templates
mappings
css
javascript
templates
mappings
css
javascript
UI Bundle
UI BundleUI Bundle
UI Bundle
UI Bundle
UI BundleUI Bundle
UI BundleUI Bundle UI Bundle
anytime
deploy UI bundles
we never touch
the file system
< 5ms
average response time
➔ Static analysis FTW
➔ Independent UI deployments
➔ Requests never touch the file system
➔ Fast package response times
Wins
final thoughts
learn by doing
move faster
fail fast
I have not failed.
I’ve just found 10,000 ways
that won’t work.”
Thomas Edison
“
simplify
thank you
questions?
Alex Liu
@stinkydofu @mjr578
Micah Ransdell

Netflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.js