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