Daniel Espeset @danielespeset 24
idea
code
release
idea
code
release?
A/B test
idea
prototype
release
A/B test
validate
A/B test
refine
2005 2010 2012
Shamelessly stolen
from Dan McKinley
mcfunley.com/data-driven-products-now
Evolution of
Continuous
Experimentation
Slide 25
Slide 25 text
Daniel Espeset @danielespeset 25
• Engineers are trusted and have massive access
• The production codebase is constantly changing
• That codebase is filled with experiments
TL;DR
Slide 26
Slide 26 text
Daniel Espeset @danielespeset 26
Slide 27
Slide 27 text
Daniel Espeset @danielespeset 27
Our frontend is made up of
300
different “pages”
Slide 28
Slide 28 text
Daniel Espeset @danielespeset 28
At any given time we
may be running dozens
of experiments per page
Slide 29
Slide 29 text
Daniel Espeset @danielespeset 29
4,096
212
=
Slide 30
Slide 30 text
Daniel Espeset @danielespeset 30
212
300
x = 1.2 M
Slide 31
Slide 31 text
Daniel Espeset @danielespeset 31
Reasoning about our
frontend can be hard
Slide 32
Slide 32 text
Daniel Espeset @danielespeset 32
Deleting code is often scary
Slide 33
Slide 33 text
Daniel Espeset @danielespeset 33
Testing changes is difficult
Slide 34
Slide 34 text
34
Frontend Infrastructure
Slide 35
Slide 35 text
Daniel Espeset @danielespeset 35
source code
deploy
build system
Slide 36
Slide 36 text
Daniel Espeset @danielespeset 36
source code production build
deploy
build system
Slide 37
Slide 37 text
Daniel Espeset @danielespeset 37
Frontend
Infrastructure
Slide 38
Slide 38 text
38
Builda [Build Assets]
Slide 39
Slide 39 text
Daniel Espeset @danielespeset
•
• Wraps RequireJS AMD compiler
• Parallelizes work across CPU cores
• Serves fully compiled assets on development VMS
39
Builda [Build Assets]
Slide 40
Slide 40 text
Daniel Espeset @danielespeset 40
Techniques for serving built assets in dev
• Build on the fly in response to HTTP requests for asset files
Slide 41
Slide 41 text
Daniel Espeset @danielespeset 41
Techniques for serving built assets in dev
• Build on the fly in response to HTTP requests for asset files
• Watch FS for any changes and rebuild everything
Slide 42
Slide 42 text
Daniel Espeset @danielespeset 42
Techniques for serving built assets in dev
• Build on the fly in response to HTTP requests for asset files
• Watch FS for any changes and rebuild everything
• Watch FS for any changes and only rebuild affected targets
Slide 43
Slide 43 text
Daniel Espeset @danielespeset 43
Techniques for serving built assets in dev
• Build on the fly in response to HTTP requests for asset files
• Watch FS for any changes and rebuild everything
• Watch FS for any changes and only rebuild affected targets
this is... complicated
Slide 44
Slide 44 text
Daniel Espeset @danielespeset 44
source code built assets
Builda
Source file is changed
Slide 45
Slide 45 text
Daniel Espeset @danielespeset 45
source code built assets
Builda
Builda looks up dependencies
Slide 46
Slide 46 text
Daniel Espeset @danielespeset 46
source code built assets
Builda
Only rebuilds files that are now stale
Slide 47
Slide 47 text
Daniel Espeset @danielespeset
This solution gave us something valuable
47
A dependency graph
Daniel Espeset @danielespeset
Ranger gave us something valuable
59
The set of files that aren't used
Slide 60
Slide 60 text
60
Shrinkray
Slide 61
Slide 61 text
Daniel Espeset @danielespeset
• Pick a stylesheet loaded on the page
61
Shrinkray - clientside CSS analysis
Slide 62
Slide 62 text
Daniel Espeset @danielespeset
• Pick a stylesheet loaded on the page
• Randomly pick 50 selectors via CSSOM
62
Shrinkray - clientside CSS analysis
Slide 63
Slide 63 text
Daniel Espeset @danielespeset
• Pick a stylesheet loaded on the page
• Randomly pick 50 selectors via CSSOM
• Search for matches with document.querySelector
63
Shrinkray - clientside CSS analysis
Slide 64
Slide 64 text
Daniel Espeset @danielespeset
• Pick a stylesheet loaded on the page
• Randomly pick 50 selectors via CSSOM
• Search for matches with document.querySelector
• Send results to server
64
Shrinkray - clientside CSS analysis
Slide 65
Slide 65 text
Daniel Espeset @danielespeset
• Pick a stylesheet loaded on the page
• Randomly pick 50 selectors via CSSOM
• Search for matches with document.querySelector
• Send results to server
• Aggregate data with Map Reduce
65
Shrinkray - clientside CSS analysis
Slide 66
Slide 66 text
66
Slide 67
Slide 67 text
67
Moving to SCSS
Slide 68
Slide 68 text
Daniel Espeset @danielespeset 68
Existing preprocessor inlines
@import, versions images
Slide 69
Slide 69 text
Daniel Espeset @danielespeset 69
Linted for syntax (sorta)
Slide 70
Slide 70 text
70
Every color defined in our CSS
Slide 71
Slide 71 text
Daniel Espeset @danielespeset
• No @extends ever
• No @mixins (for now)
• Nesting level < 4
• Lints to enforce these and strict code-style adherence
71
Restricting SCSS functionality
Slide 72
Slide 72 text
Daniel Espeset @danielespeset
• @import statements needed changed
• Converter fixes 171,244 scss-lint errors
• Had to resolve hundreds of invalid CSS rules & selectors
72
Converter script
Slide 73
Slide 73 text
Daniel Espeset @danielespeset 73
Will fixing this break something?
color: rgb(25555, -10, 0);
Slide 74
Slide 74 text
Daniel Espeset @danielespeset 74
What about this one?
color: rgb(0, 0, 0, 0);