Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Frontend Archaeology

Frontend Archaeology

Given at Codelicious on 7th July 2016

Avatar for Tom Ashworth

Tom Ashworth

July 07, 2016
Tweet

More Decks by Tom Ashworth

Other Decks in Programming

Transcript

  1. TweetDeck A few million users. Six billion API requests every

    day. Maybe eighty thousand lines of JavaScript. Six years of git log. @tgvashworth 5
  2. const Example = component(example, withExtras); function example() { this.after("initialize", function

    () { this.on("click", this.onClick); }); this.onClick = function (event) { this.trigger("exampleWasClicked", { some: "data" }); }; } @tgvashworth 10
  3. Using "advice": this.onClick = function () { ... }; this.before("onClick",

    this.doAThing); this.after("onClick", this.doSomethingElse); @tgvashworth 12
  4. Flight had some problems: » Couldn't nest components » No

    standard state management » Events for data flow @tgvashworth 13
  5. Frameworks we like: » React (user interface library) » Elm

    (language for functional & reactive UI) » Cycle (functional & reactive UI in JS) @tgvashworth 14
  6. Ideas we like: » Component nesting & composition » Easy,

    predictable state management » Normal functions for data manipulation @tgvashworth 15
  7. In Flight, nesting components was icky: » Tightly coupled »

    Not reusable » Hard to debug (because events) @tgvashworth 16
  8. We created a mixin called withState: this.mergeState({ active: true, tooltip:

    "Hello!" }); this.after("stateChanged", this.render); @tgvashworth 23
  9. this.on("usersResponse", (e, response) => { if (response.requestId === this.id) {

    response.users.map(user => { this.trigger("tweetsRequest", { requestId: this.id, userId: user.id }); }); } }); this.on("tweetsResponse", (e, response) => { /* ... */ }); this.trigger("usersRequest", { requestId: this.id }); @tgvashworth 24
  10. Observables with RxJS: » Observable: represents a collection of future

    values » Observer: a collection of callbacks » Operators: pure functions like map, filter, concat, flatMap... @tgvashworth 27
  11. Way back in 2015... » require.js & AMD modules »

    Monoglobal (TD) » Bower dependency management @tgvashworth 31
  12. We had... define(["lodash"], function (_) { // . . .

    }); and we had... define(function (require) { var _ = require("lodash"); // . . . }); @tgvashworth 32
  13. codemod noun A large-scale codebase refactor, often mechanical or repetitive.

    js-codeshift noun Toolkit for running automated codemods. @tgvashworth 34
  14. @@ -3,10 +3,9 @@ * * Manages & removing tweets

    from collections */ -define([ - 'flight/lib/component', - 'data/with_client' -], function (defineComponent, withClient) { +define(function (require) { + var defineComponent = require('flight').component; + var withClient = require('data/with_client'); return defineComponent(customTimelines, withClient); @tgvashworth 36
  15. commit 3f617af133cb251ca10a0fadf223a49e71be2440 Author: Tom Ashworth <[email protected]> Date: Mon Nov 16

    15:47:18 2015 +0000 . . . 70 files changed, 3508 insertions(+), 3617 deletions(-) @tgvashworth 37
  16. Three step refactor recipe: 1. Find all the patterns 2.

    Choose the two most similar 3. Unify with a codemod Repeat. @tgvashworth 38
  17. Over time we had acquired... » Lots of complexity »

    Dependency on people, not systems » Word-of-mouth sharing @tgvashworth 42
  18. Some factors in increasing entropy and incidental complexity: » Changing

    requirements (it did X, now it must do Y too) » Bugs (ugh, it broke, fix it quick) » Intrinsic complexity (complexity replicates) @tgvashworth 48
  19. How we've addressed it... » Portfolio approach » Feature and

    Platform balance » Advocate for the codebase @tgvashworth 50
  20. Avoid complexity & decay by sharing knowledge: » Pairing »

    Onboarding » Code review @tgvashworth 53
  21. A great onboarding has side-effects: » Documentation! » More outside

    contributions » Faster incident management @tgvashworth 55
  22. Code review is the single most effective practice you can

    introduce to improve your team's work. @tgvashworth 58
  23. Over time, we learned some things about code review: »

    Don't review for more than hourDunsmore 2000 » Keep reviews smaller than ~400 linesCohen 2006 » Code review your own code firstCohen 2006 Yes, this slide features science. Cohen 2006 Cohen, Jason. 2006. Best Kept Secrets of Peer Code Review. Proceedings of the 22nd ICSE 2000: 467-476. Dunsmore 2000 Dunsmore et al. 2000. Object-Oriented Inspection in the Face of Delocalisation. Beverly, MA: SmartBear Software. @tgvashworth 60
  24. Way-er back in 2014: » Scary deploys (a nervous day

    in person-hours) » Built from a laptop » Manual testing checklist » Big commits (hard to code review) @tgvashworth 64
  25. Scary deploys: » Manual » Infrequent » Lots of code

    » Slow feedback loop (what broke?) @tgvashworth 65
  26. Practical ways to optimise for confidence: » Work on master

    (branches mean big merges) » Use feature flags (no-sweat releases) » Deploy as often as you can » Use alerts to spot trouble @tgvashworth 68
  27. Feature flags? function enabled(id, flag, threshold) { return hash(id +

    flag) > threshold; } const showSuperCoolFeature = enabled(user.id, "super_cool_feature", 50); @tgvashworth 69
  28. In summary » As frontend technology matures, so must our

    practice. » Find and reapply good ideas. » Take an active stance against debt & decay. » Optimise for confidence by tightening feedback loops. @tgvashworth 72
  29. Thanks ❤ Tom Ashworth @tgvashworth [email protected] Special thanks to the

    team @TwitterUK, especially @passy, for feedback! @tgvashworth 73