[HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js
description
Transcript of [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js
![Page 1: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/1.jpg)
Scaling A/B testing on Netflix.com with
_________Alex Liu @stinkydofu
![Page 2: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/2.jpg)
data driven product development
![Page 3: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/3.jpg)
![Page 4: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/4.jpg)
![Page 5: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/5.jpg)
![Page 6: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/6.jpg)
![Page 7: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/7.jpg)
A
B
C
D
E
F
G
A
B
C
D
E
F
G
A
B
C
D
E
F
G
A
B
C
D
E
F
G
A
B
C
D
E
F
G
A
B
C
D
E
F
G
A
B
C
D
E
F
G
Test 1 Test 2 Test 3 Test 4 Test 5 Test 6 Test 7
![Page 8: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/8.jpg)
2,097,152 unique experiences across seven tests
![Page 9: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/9.jpg)
hundreds of new A/B tests per year
![Page 10: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/10.jpg)
433518929550349486086117218185493567650…72061153709996
![Page 11: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/11.jpg)
2105 566 685templates CSS JS
![Page 12: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/12.jpg)
2.5M unique packages every week
![Page 13: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/13.jpg)
<html/> <link/> <script/>
![Page 14: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/14.jpg)
problem: conditional dependencies
![Page 15: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/15.jpg)
![Page 16: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/16.jpg)
▶ Templating ▶ Packaging ▶ Bonus Round
![Page 17: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/17.jpg)
Templating
![Page 18: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/18.jpg)
![Page 19: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/19.jpg)
payment.dust<div id="payments"> <input id="first-name"><input id="last-name"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="card-number"><input id="security-code"> <select name="month"></select><select name="year"></select> <checkbox id="agree-to-terms"/> <button>Start Your Trial</button> </div>
![Page 20: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/20.jpg)
![Page 21: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/21.jpg)
![Page 22: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/22.jpg)
<input id=“first-name"><input id=“last-name"> {@inTest id="10" cell=“2a"} <div class="payment-types"> <div id="CC"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id=“card-number"><input id=“security-code”> </div> <div id="DD"> <span class=“payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="CPF"><input id="bank-name"> <input id="branch-number"><input id="account-number"> <input id="digit"> </div> </div> {/@inTest} {@inTest id="10" cell=“3"} <div class="payment-types"> <div id="CC"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id=“card-number"><input id=“security-code”> </div> <div id="DD"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="CPF"><input id="bank-name"> <input id="branch-number"><input id="account-number"> <input id="digit"> </div> </div> {/@inTest} {@inTest id="10" cell=“4"} <div class="payment-types"> <div id="CC"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id=“card-number"><input id=“security-code”> </div> <div id="DD"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="CPF"><input id="bank-name"> <input id="branch-number"><input id="account-number"> <input id="digit"> </div> </div> {/@inTest} {@inTest id="10" cell=“5"} <div class="payment-types"> <div id="CC"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id=“card-number"><input id=“security-code”> </div> <div id="DD"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="CPF"><input id="bank-name"> <input id="branch-number"><input id="account-number"> <input id="digit"> </div> </div> {/@inTest} <checkbox id="agree-to-terms"></checkbox> <button>Start Your Trial</button> </div>
![Page 23: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/23.jpg)
payment.dust
if ifif if if
Control Cell 2 Cell 3 Cell 4 Cell 5
![Page 24: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/24.jpg)
<div class="payment-types"> <div id="CC"> {> payment_type_cc /} </div> <div id="DD"> {> payment_type_dd /} </div> </div>
![Page 25: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/25.jpg)
payment.dust
Control Cell 2 Cell 3 Cell 4 Cell 5
payment_type_cc.dust payment_type_dd.dust
if ifif if if
![Page 26: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/26.jpg)
payment.dust
Control.dust
payment_type_cc.dust payment_type_dd.dust
Cell3.dustCell2.dust Cell4.dust Cell5.dust
if ifif if if
![Page 27: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/27.jpg)
<div id="payments"> <input id="first-name"> <input id="last-name">
{> payment_method /}
<input type="checkbox" id="terms"> <button>Start Your Trial</button> </div>
![Page 28: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/28.jpg)
payment.json
payment.dust
?
Control.dust Cell3.dustCell2.dust Cell4.dust Cell5.dust
payment_type_cc.dust payment_type_dd.dust
![Page 29: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/29.jpg)
payment.json{ "rules": [], "templateName": "control" }, { "rules": ["PaymentTest(2)"], "templateName": "payment_cell2" }, { "rules": ["PaymentTest(3)"], "templateName": "payment_cell3" }, { "rules": ["PaymentTest(4)"], "templateName": "payment_cell4" }, { "rules": ["PaymentTest(5)"], "templateName": "payment_cell5" }
![Page 30: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/30.jpg)
require('nf-rule-infrastructure')
![Page 31: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/31.jpg)
var Rule = require('nf-rule-infrastructure'), PaymentTest;
PaymentTest = new Rule('PaymentTest', function(context, params, cb) { var test = context.abtests.get(10); cb(test && test.cell(params.id)); });
module.exports = PaymentTest;
anatomy of a rule
![Page 32: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/32.jpg)
require('nf-template-resolver')
![Page 33: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/33.jpg)
payment.dust dustjs partial
![Page 34: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/34.jpg)
resolver payment.json (mappings)
rule
![Page 35: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/35.jpg)
rules
control.dust
cell2.dust
cell3.dust
![Page 36: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/36.jpg)
payment.dust dustjs resolver
![Page 37: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/37.jpg)
<input id=“first-name"><input id=“last-name"> {@inTest id="10" cell=“2a"} <div class="payment-types"> <div id="CC"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id=“card-number"><input id=“security-code”> </div> <div id="DD"> <span class=“payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="CPF"><input id="bank-name"> <input id="branch-number"><input id="account-number"> <input id="digit"> </div> </div> {/@inTest} {@inTest id="10" cell=“3"} <div class="payment-types"> <div id="CC"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id=“card-number"><input id=“security-code”> </div> <div id="DD"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="CPF"><input id="bank-name"> <input id="branch-number"><input id="account-number"> <input id="digit"> </div> </div> {/@inTest} {@inTest id="10" cell=“4"} <div class="payment-types"> <div id="CC"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id=“card-number"><input id=“security-code”> </div> <div id="DD"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="CPF"><input id="bank-name"> <input id="branch-number"><input id="account-number"> <input id="digit"> </div> </div> {/@inTest} {@inTest id="10" cell=“5"} <div class="payment-types"> <div id="CC"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id=“card-number"><input id=“security-code”> </div> <div id="DD"> <span class="payment-logos"> <img src="logo1.png"><img src="logo2.png"> <img src="logo3.png"><img src="logo4.png"> </span> <input id="CPF"><input id="bank-name"> <input id="branch-number"><input id="account-number"> <input id="digit"> </div> </div> {/@inTest} <checkbox id="agree-to-terms"></checkbox> <button>Start Your Trial</button> </div>
![Page 38: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/38.jpg)
<div id="payments"> <input id="first-name"> <input id="last-name">
{> payment_method /}
<input type="checkbox" id="terms"> <button>Start Your Trial</button> </div>
![Page 39: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/39.jpg)
Wins▶ combine rules ▶ improve template legibility ▶ increase template reuse
![Page 40: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/40.jpg)
▶ Templating ▶ Packaging ▶ Bonus Round
![Page 41: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/41.jpg)
Packaging
![Page 42: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/42.jpg)
everything is a module
![Page 43: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/43.jpg)
![Page 44: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/44.jpg)
![Page 45: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/45.jpg)
oldSearch
app.js
newSearch
dep1 dep2 dep3 dep4 dep5
sub-dep sub-depsub-dep sub-dep sub-dep sub-dep
![Page 46: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/46.jpg)
oldSearch
app.js
newSearch
dep1 dep2 dep3 dep4 dep5
sub-dep sub-depsub-dep sub-dep sub-dep sub-dep
![Page 47: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/47.jpg)
app.js
import jquery from 'jquery'; import oldSearch from 'oldSearch'; import newSearch from 'newSearch';
export ...
![Page 48: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/48.jpg)
oldSearch
app.js
newSearch
dep1 dep2 dep3 dep4 dep5
sub-dep sub-depsub-dep sub-dep sub-dep sub-dep
![Page 49: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/49.jpg)
![Page 50: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/50.jpg)
685 files…?
2.5M packages…?
![Page 51: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/51.jpg)
oldSearch
app.js
newSearch
dep1 dep2 dep3 dep4 dep5
sub-dep sub-depsub-dep sub-dep sub-dep sub-dep
![Page 52: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/52.jpg)
problem: conditional dependencies
![Page 53: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/53.jpg)
![Page 54: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/54.jpg)
requestbuild
![Page 55: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/55.jpg)
require('nf-include-when')
![Page 56: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/56.jpg)
/* * @includewhen rule.notInNewSearch */
oldSearch.js
![Page 57: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/57.jpg)
/* * @includewhen rule.inNewSearch */
newSearch.js
![Page 58: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/58.jpg)
var Rule = require('nf-rule-infrastructure'), inNewSearch;
inNewSearch = new Rule('inNewSearch', function(context, cb) { var test = context.abtests.get(1534); cb(test && test.cell(1)); });
module.exports = inNewSearch;
anatomy of a rule
![Page 59: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/59.jpg)
require('nf-asset-registry')
![Page 60: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/60.jpg)
import jquery from 'jquery'; import oldSearch from 'oldSearch'; import newSearch from 'newSearch';
export ...
app.js
![Page 61: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/61.jpg)
newSearch.js
jquery
oldSearch.js
app.js
registry
![Page 62: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/62.jpg)
"app.js": { "deps": [ "jquery", "oldSearch.js", "newSearch.js", ], "depsFull": [ "jquery", "oldSearchDep2.js", "oldSearchDep1.js", "oldSearch.js", "newSearchDep2.js", "newSearchDep1.js", "newSearch.js" ] }
![Page 63: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/63.jpg)
"newSearch.js": { "rule": "inNewSearch", "deps": [ "jquery", "newSearchDep2.js", "newSearchDep1.js", ], "depsFull": [ "jquery", "newSearchSubDep3.js", "newSearchSubDep2.js" "newSearchSubDep1.js" "newSearchDep2.js", "newSearchDep1.js" ] }
nf-include-when
![Page 64: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/64.jpg)
require('nf-packager')
![Page 65: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/65.jpg)
var packager = require('nf-packager'), includeWhen = require('nf-include-when'), registries = require('nf-asset-registry');
function getScriptUrl() return packager.getPackageDefinition('app.js', registries, includeWhen); }
![Page 66: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/66.jpg)
"app.js": { "deps": [ "jquery", "oldSearch.js", "newSearch.js", ], "depsFull": [ "jquery", "oldSearchDep2.js", "oldSearchDep1.js", "oldSearch.js", "newSearchDep2.js", "newSearchDep1.js", "newSearch.js" ], "fileSize": "4.41 kB", "fileSizeFull": "120.52 kB" }
Step 1: Get the full dependency tree for the requested package from the registry.
![Page 67: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/67.jpg)
[ "jquery", /* no rule */ "oldSearchDep2.js", /* no rule */ "oldSearchDep1.js", /* no rule */ "oldSearch.js", /* rules.notInNewSearch */ "newSearchDep2.js", /* no rule */ "newSearchDep1.js”, /* no rule */ "newSearch.js" /* rules.inNewSearch */ ]
Step 2: Determine which files have rules.
![Page 68: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/68.jpg)
[ "jquery", /* no rule */ "oldSearchDep2.js", /* no rule */ "oldSearchDep1.js", /* no rule */ "oldSearch.js", /* rules.notInNewSearch */ "newSearchDep2.js", /* no rule */ "newSearchDep1.js”, /* no rule */ "newSearch.js" /* rules.inNewSearch */ ]
Step 3: Run the rules. Filter out all deps that resolved false.
✓
![Page 69: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/69.jpg)
[ "jquery", /* no rule */ "oldSearchDep2.js", /* no rule */ "oldSearchDep1.js", /* no rule */ "oldSearch.js", /* rules.notInNewSearch */ "newSearchDep2.js", /* no rule */ "newSearchDep1.js”, /* no rule */ "newSearch.js" /* rules.inNewSearch */ ]
Step 4: Filter out all extraneous sub deps.
✓
![Page 70: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/70.jpg)
Step 5: Concatenate the files.
[ "jquery", /* no rule */ "newSearchDep2.js", /* no rule */ "newSearchDep1.js”, /* no rule */ "newSearch.js" /* rules.inNewSearch */ ]
![Page 71: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/71.jpg)
buildjavascript
registry
![Page 72: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/72.jpg)
request registry
rulespackager
![Page 73: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/73.jpg)
Wins▶ leverage build time tools ▶ leverage the server ▶ divide and conquer with modules
![Page 74: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/74.jpg)
▶ Templating ▶ Packaging ▶ Bonus Round
![Page 75: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/75.jpg)
Bonus Round
![Page 76: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/76.jpg)
be creative with the registry
![Page 77: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/77.jpg)
"account/bb/models/ratingHistoryModel.js": { "rule": null, "deps": [...], "depsFull": [...], "depsCount": { "underscore": 2, "backbone": 1, "jquery": 2, "common/requirejs-plugins.js": 4, "requirejs-text": 4, "utils/contextData.js": 1, "common/nfNamespace.js": 1 }, "hash": "dd23b163", "fileSize": "1.21 kB", "fileSizeFull": "173.04 kB" }
dependency counting
dependency pruning
file sizes
![Page 78: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/78.jpg)
@import (reference) "/common/_nf_defs.less"; @import (reference) "/member/memberCore.less"; @import (reference) "/components/menu.less"; @import (reference) "/components/breadcrumbs.less";
@import modules
![Page 79: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/79.jpg)
"account/containerResponsive.css": { "rule": null, "deps": [...], "depsFull": [...], "depsCount": [...], "hash": "65a431f3", "fileSize": "709 B", "fileSizeFull": "709 B", "css": { "selectors": 8, "declarationBlocks": 6, "declarations": 17, "mediaQueries": 3 } }
css analysis
![Page 80: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/80.jpg)
the
best part
![Page 81: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/81.jpg)
"cache": { "account/pin.js": "define('account/pin.js', ['member/memberC…", "account/bb/models/changePlanModel.js": "define('account/b…", "account/bb/models/ratingHistoryModel.js": "define('account…", "account/bb/models/viewingActivityModel.js": "define('account…", "account/bb/views/changePlanView.js": "define('account/bb/vi…", "account/bb/views/changePlanView.js": "define('account/bb/vi…", "account/bb/views/emailSubView.js": "define('account/bb/views…", "account/bb/views/viewingActivityView.js": "define('account…", "common/UITracking.js": "define('common/UITracking.js, ['me…", "common/UITrackingOverlay.js": "define('common/UITrackingOve…", … … …
![Page 82: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/82.jpg)
css
mappings
javascript
templates templates
mappings
javascript
css
![Page 83: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/83.jpg)
templates
mappings
javascript
css
UI Bundle
![Page 84: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/84.jpg)
![Page 85: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/85.jpg)
deploy UI bundles
anytime
![Page 86: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/86.jpg)
never touch the file system
![Page 87: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/87.jpg)
< 5ms package response times
![Page 88: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/88.jpg)
Wins▶ static analysis FTW ▶ independent UI deployments ▶ requests never touch the fs ▶ fast package response times
![Page 89: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/89.jpg)
Our Learnings
![Page 90: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/90.jpg)
learn by doing
![Page 91: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/91.jpg)
fail fastmove faster
![Page 92: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/92.jpg)
“I have not failed.I’ve just found 10,000 waysthat won’t work.”
Thomas Edison
![Page 93: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/93.jpg)
simplify
![Page 94: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/94.jpg)
![Page 95: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/95.jpg)
Alex Liu @stinkydofu
thank you
![Page 96: [HTML5DevConf2014] Scaling AB Testing on Netflix.com with Node.js](https://reader036.fdocuments.net/reader036/viewer/2022062514/559324721a28ab4d118b457a/html5/thumbnails/96.jpg)
Alex Liu @stinkydofu
questions?