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

Frontend Archaeology

Frontend Archaeology

Given at Codelicious on 7th July 2016

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