$30 off During Our Annual Pro Sale. View Details »

Frontend Infrastructure at Etsy

Frontend Infrastructure at Etsy

Delivered at Smashing Conf NYC, June 17th 2015

Daniel Espeset

June 17, 2015
Tweet

More Decks by Daniel Espeset

Other Decks in Programming

Transcript

  1. Daniel Espeset
    @danielespeset
    Smashing Conf NYC, June 2015
    at Etsy
    Frontend
    Infrastructure

    View Slide

  2. talks.desp.in/smashing
    Resources for this talk

    View Slide

  3. 3

    View Slide

  4. Daniel Espeset @danielespeset
    A front-end operations engineer is not a title you’ve
    likely come across, but hopefully one that you will
    [...] an expert at serving and hosting front-end
    resources. [finding] the best ways to piece together the
    parts of a Web application, and [being a pro] at
    versioning, caching and deployment.
    Alex Sexton @slexaxton
    "Front-End Ops", Smashing Magazine, July 2013


    4

    View Slide

  5. Daniel Espeset @danielespeset
    Frontend Infrastructure
    5
    Daniel Espeset
    Daniel Na Takashi Mizohata
    Etsy
    Seth Walker
    Sufian Rhazi Jonathan Lai

    View Slide

  6. Etsy Engineering

    View Slide

  7. Daniel Espeset @danielespeset
    Anybody can touch
    (mostly) anything
    7

    View Slide

  8. Daniel Espeset @danielespeset
    Blameless
    postmortems
    8

    View Slide

  9. Daniel Espeset @danielespeset
    Everyone deploys
    9

    View Slide

  10. Continuous
    Deployment

    View Slide

  11. Daniel Espeset @danielespeset
    Push Button
    Deploys
    11

    View Slide

  12. pages/search_results.php
    if (Feature::isEnabled('my_new_feature')) {
    // TODO build this part
    } else {
    // Existing code
    }
    20
    21
    22
    ..
    100
    12
    config/production.php
    // Owner: despeset, frontend infrastructure
    server_config['my_new_feature'] = (
    'enabled' => 0
    );
    890
    891
    892
    893
    Checking a flag
    Defining a flag

    View Slide

  13. 13
    desp
    .join
    pushbot has changed topic to: " seth dna* gio* | desp"
    pushbot
    desp jklein : You're up
    desp
    .in
    pushbot has changed topic to: "desp jklein"
    pushbot has changed topic to: "desp* jklein"
    jklein
    .in
    pushbot has changed topic to: "desp* jklein*"
    pushbot
    desp jklein : everyone is ready
    Coordinating Deploys

    View Slide

  14. 14

    View Slide

  15. 15

    View Slide

  16. 16

    View Slide

  17. 17

    View Slide

  18. 18

    View Slide

  19. 19
    25-50Pushes a day

    View Slide

  20. 20
    // Owner: despeset, frontend infrastructure
    server_config['my_new_feature'] = (
    'enabled' => 0,
    'group' => 9903
    );
    890
    891
    892
    893
    894
    config/production.php

    View Slide

  21. 21
    config/production.php
    // Owner: despeset, frontend infrastructure
    server_config['my_new_feature'] = (
    'enabled' => 0,
    'group' => 9903,
    'admin' => 'on'
    );
    890
    891
    892
    893
    894
    895

    View Slide

  22. 22
    // Owner: despeset, frontend infrastructure
    server_config['my_new_feature'] = (
    'enabled' => 50,
    'group' => 9903,
    'admin' => 'on'
    );
    890
    891
    892
    893
    894
    895
    config/production.php

    View Slide

  23. Continuous
    Experimentation

    View Slide

  24. Daniel Espeset @danielespeset
    idea
    code
    release
    idea
    code
    release?
    A/B test
    idea
    prototy
    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
    24

    View Slide

  25. Daniel Espeset @danielespeset
    • Engineers are trusted and given agency
    • The production codebase is constantly changing
    • That codebase is filled with feature flags
    In a nutshell
    25

    View Slide

  26. Daniel Espeset @danielespeset 26

    View Slide

  27. Daniel Espeset @danielespeset 27
    Sass conversion

    View Slide

  28. Daniel Espeset @danielespeset
    Our frontend is made up of
    >300
    different “pages”
    28

    View Slide

  29. Daniel Espeset @danielespeset
    At any given time we
    may be running dozens
    of tests per page
    29

    View Slide

  30. Daniel Espeset @danielespeset
    4,096
    212=
    30

    View Slide

  31. Daniel Espeset @danielespeset
    212 300
    x =1.2 M
    31

    View Slide

  32. Daniel Espeset @danielespeset
    Reasoning about our
    frontend can be hard
    32

    View Slide

  33. Daniel Espeset @danielespeset
    Deleting code is often
    scary
    33

    View Slide

  34. Daniel Espeset @danielespeset
    Verifying changes is
    difficult
    34

    View Slide

  35. Frontend Infrastructure

    View Slide

  36. Daniel Espeset @danielespeset 36
    Performance
    Allison McKnight Kristyn Reith
    Etsy
    Natalya Hoota
    Lara Hogan

    View Slide

  37. Daniel Espeset @danielespeset
    source code
    deploy
    build system
    37

    View Slide

  38. Daniel Espeset @danielespeset
    source code production build
    38
    deploy
    build system

    View Slide

  39. Daniel Espeset @danielespeset
    Frontend
    Infrastructure
    39

    View Slide

  40. Daniel Espeset @danielespeset 40
    ...the bridge between an application's
    intent and an application's reality.
    Alex Sexton (JavaScript Laureate of Texas)
    "Front-End Ops", Smashing Magazine, July 2013


    View Slide

  41. {% css files="base" %}{% /css %}
    Template Code

    Rendered HTML
    most recent last modified date
    of file and all dependencies.

    View Slide

  42. {% css files="base" %}{% /css %}
    Template Code

    Rendered HTML
    adds version number,
    always happens.

    View Slide

  43. {% css files="base" %}{% /css %}
    Template Code

    Rendered HTML
    if (rand() > 0.01) {
    log(template, asset);
    }

    View Slide

  44. Where are my things?
    (Ranger)

    View Slide

  45. Daniel Espeset @danielespeset
    + +
    JS graph Asset logs
    CSS graph
    Ranger combines 3 dependency
    graphs
    45

    View Slide

  46. 46

    View Slide

  47. 47

    View Slide

  48. 48

    View Slide

  49. 49

    View Slide

  50. 50

    View Slide

  51. 51

    View Slide

  52. 52

    View Slide

  53. 53

    View Slide

  54. Daniel Espeset @danielespeset
    Ranger gave us something valuable
    The set of files that aren't used
    54

    View Slide

  55. Profiling CSS
    (Shrinkray)

    View Slide

  56. Daniel Espeset @danielespeset 56
    • Pick a stylesheet loaded on the page
    Shrinkray - CSS analysis

    View Slide

  57. Daniel Espeset @danielespeset 57
    • Pick a stylesheet loaded on the page
    • Randomly pick 50 selectors via CSSOM
    Shrinkray - CSS analysis

    View Slide

  58. Daniel Espeset @danielespeset 58
    • Pick a stylesheet loaded on the page
    • Randomly pick 50 selectors via CSSOM
    • Search for matches with document.querySelector
    Shrinkray - CSS analysis

    View Slide

  59. Daniel Espeset @danielespeset 59
    • Pick a stylesheet loaded on the page
    • Randomly pick 50 selectors via CSSOM
    • Search for matches with document.querySelector
    • Send results to server
    Shrinkray - CSS analysis

    View Slide

  60. 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
    Shrinkray - CSS analysis
    60

    View Slide

  61. 61

    View Slide

  62. Daniel Espeset @danielespeset
    • Low confidence on long-tail pages
    • Doesn't capture CSS appearing by user action
    Why doesn't it work yet?
    62

    View Slide

  63. Daniel Espeset @danielespeset
    • Increase measurement volume if perf allows
    • Add time skew to measurements
    • Intelligently target selectors based on the data
    • Add a second pass using an more invasive but
    thorough technique
    Possible solutions
    63

    View Slide

  64. 64
    #container .button-cool ul {
    color: pink;
    float: left;
    }
    #container .button-cool ul:before {
    content: '';
    background-image: url('selector-used?id=1');
    }
    890
    891
    892
    893
    894
    895
    896
    899
    some_page.css
    CSS Background Beacon

    View Slide

  65. Moving to Sass

    View Slide

  66. Daniel Espeset @danielespeset
    Existing preprocessor
    inlines @import,
    versions images
    66

    View Slide

  67. Daniel Espeset @danielespeset
    Linted for syntax
    (sorta)
    67

    View Slide

  68. 68
    Every color defined in our CSS

    View Slide

  69. Daniel Espeset @danielespeset
    • @import statements needed changed
    • Converter fixes 171,244 Sass-lint errors
    • Had to resolve hundreds of invalid CSS rules &
    selectors
    Converter script
    69

    View Slide

  70. Daniel Espeset @danielespeset
    Will fixing this break something?
    color: rgb(25555, -10, 0);
    70

    View Slide

  71. Daniel Espeset @danielespeset
    What about this one?
    color: rgb(0, 0, 0, 0);
    71

    View Slide

  72. Daniel Espeset @danielespeset
    CSS Source
    Legacy CSS Build
    Legacy Build
    72

    View Slide

  73. Daniel Espeset @danielespeset
    CSS Source
    Legacy CSS Build
    Converter Sass Build
    New CSS Build
    73
    Legacy Build

    View Slide

  74. Daniel Espeset @danielespeset
    CSS Source
    Legacy CSS Build
    Converter Sass Build
    New CSS Build
    AST Differ
    Parse to
    AST
    Parse to
    AST
    74
    Legacy Build

    View Slide

  75. Daniel Espeset @danielespeset
    CSS Source
    Legacy CSS Build
    Converter Sass Build
    100%
    New CSS Build
    75
    Legacy Build

    View Slide

  76. Daniel Espeset @danielespeset
    CSS Source
    Legacy CSS Build
    Converter Sass Build
    100%
    Etsy
    New CSS Build
    76
    Legacy Build

    View Slide

  77. Daniel Espeset @danielespeset
    CSS Source
    Legacy CSS Build
    Converter Sass Build
    50%
    50%
    New CSS Build
    77
    Legacy Build

    View Slide

  78. Daniel Espeset @danielespeset
    CSS Source
    Legacy CSS Build
    New CSS Build
    Converter Sass Build 100%
    78
    Legacy Build

    View Slide

  79. Daniel Espeset @danielespeset
    Sass Source New CSS Build
    Sass Build 100%
    79

    View Slide

  80. Daniel Espeset @danielespeset
    • No @extends or functions, ever
    • @mixins only defined in one global file
    • Nesting level < 4
    • Variable definitions should in a dedicated file
    Restricting Sass
    80

    View Slide

  81. 81

    View Slide

  82. Daniel Espeset @danielespeset
    • Enforce globally unique variable names
    • Sass AST!
    More to do
    82

    View Slide

  83. What have we learned?

    View Slide

  84. Daniel Espeset @danielespeset
    Disposability > Modularity
    84

    View Slide

  85. Daniel Espeset @danielespeset
    The frontend is getting
    more complex
    everywhere.
    85

    View Slide

  86. Daniel Espeset @danielespeset
    We need new strategies to
    manage and understand it.
    86

    View Slide

  87. Daniel Espeset @danielespeset
    It helps to have a team
    dedicated to this work.
    (or even just a person)
    87

    View Slide

  88. Daniel Espeset @danielespeset
    The browser is part of your
    distributed system, not just
    a client you support.
    88

    View Slide

  89. codeascraft.com
    etsy.com/careers
    Thank you.
    talks.desp.in/smashing

    View Slide