Managing JavaScript Complexity

12,945 views

Published on

These are the slides for the talk "Managing and Visualizing JavaScript Complexity" given at QCon SF 2013 by Jarrod Overson

Published in: Technology

Managing JavaScript Complexity

  1. 1. Managing and Visualizing JavaScript Complexity Jarrod Overson Consultant @ Gossamer.io jarrodoverson.com
  2. 2. Yes, we’ll talk about “Code Complexity” and “Code Quality”
  3. 3. Check your bias at the door We’ll deal with it later
  4. 4. 1. Why is this important now 2. Static Analysis & Linting 3. Visualizing Complexity
  5. 5. The obvious…
  6. 6. JavaScript is Dynamic all the obvious pitfalls compounded by Immature tooling and IDEs Wildly variable module styles Best practices vary as language evolves Server & Client similar yet so different
  7. 7. The Talent Pool is ridic Web Platform Engineers jQuery experts Closures?
  8. 8. The less obvious…
  9. 9. Progress is staggering It’s hard to keep up The next tech might not be usable yet When it is, you want to actually be able to use it
  10. 10. Refactoring isn’t easy Callback hell is more than just deep nesting ! IDEs can’t help much, yet ! But flexibility is more important on the web than anywhere else
  11. 11. And the hard to admit…
  12. 12. The Web is hard Web Applications are not solved Even the giants pivot and backtrack So many solutions still don’t exist
  13. 13. So why are we here? Why bother?
  14. 14. JS coasted to the lead on neutral
  15. 15. And this isn’t even its final form
  16. 16. We can see where it’s headed and we’re betting on JS
  17. 17. 1. Why is this important now 2. Static Analysis & Linting 3. Visualizing Complexity
  18. 18. Respect your JavaScript and codify that respect.
  19. 19. All code should look the same. Style Naming Punctuation Indentation Comments Case
  20. 20. Get everyone together 1. Agree 2. Document 3. Enforce https://github.com/rwaldron/idiomatic.js/ https://github.com/Seravo/js-winning-style https://github.com/airbnb/javascript
  21. 21. Coding conventions based on Github analysis 1. >90% use last comma 2. >80% use space indents 3. >55% use single quotes http://sideeffect.kr/popularconvention/#javascript
  22. 22. Lax enforcement begets violations. Warnings need to fail builds. These is as important as failed tests.
  23. 23. Know your options JSLint Crockford-style linter, low configuration Closure Linter Google-style linter, low configuration JSHint ✔ Community driven JSLint fork, moderately configurable ESLint ✔ Pluggable styles, highly configurable
  24. 24. Know your options’ options { } "maxerr" "bitwise" "camelcase" "curly" "eqeqeq" "forin" "immed" "indent" "latedef" "newcap" "noarg" "noempty" "nonew" "plusplus" "quotmark" //... : : : : : : : : : : : : : : : 50, true, false, true, true, true, false, 4, false, false, true, true, false, false, false
  25. 25. Be aggressive. Default to overly strict.
  26. 26. Smart deviation is OK and expected. ! ! function fn(param) { /*jshint eqeqeq:false*/ ! if (param == 42) return; ! }
  27. 27. Set complexity limits "maxparams" "maxdepth" "maxstatements" "maxcomplexity" "maxlen" : : : : : 4, 4, 20, 7, 100
  28. 28. What is Cyclomatic Complexity a.k.a. Conditional Complexity ?
  29. 29. Cyclomatic Complexity is not magic nerd hokum something you should ignore
  30. 30. Cyclomatic Complexity is the number of paths through a block of code (technically)
  31. 31. Cyclomatic Complexity is how hard your code is to test. (practically)
  32. 32. Complexity : 1 ! function main(a) { ! }
  33. 33. Complexity : 2 function main(a) { if (a > 5) { } }
  34. 34. Complexity : ? still 2 function main(a) { if (a > 5) { ! } else { ! } }
  35. 35. Complexity : ? now 3 function main(a) { if (a > 10) { ! } else if(a > 5) { ! } }
  36. 36. Complexity : ? still 3 function main(a) { if (a > 10) { ! } else if(a > 5) { ! } else { ! } }
  37. 37. Complexity : ? also 3 function main(a) { if (a > 5) { if (a > 10) { ! } } }
  38. 38. Complexity : 7 function main(a) { if (a) { } else if (a) { } ! if (other) { } ! } for (var i = 0; i < a; i++) { if (i % 2) { } else if (i % 3) { } }
  39. 39. Don’t get hung up on numbers ! function main() { /*jshint maxcomplexity:12*/ ! } //... ! * note : jshint calculates complexity differently than complexity-report (plato, grunt-complexity)
  40. 40. Cyclomatic Complexity is an early warning but isn’t everything.
  41. 41. OMG! I’m going to make the best .jshintrc
  42. 42. It’s ok. Have an ideal set of options, and a current set that passes now. Visualize your goal.
  43. 43. 1. Why is this important now 2. Static Analysis & Linting 3. Visualizing Complexity
  44. 44. Plato. One cool guy. github.com/es-analysis/plato
  45. 45. Visualize your progress. Target hot spots and track progress. Promote files when ready. When a file clears, promote it to your ideal jshintrc.
  46. 46. Files passing “ideal” settings
  47. 47. Files to target next
  48. 48. Someday…
  49. 49. Challenge Accepted. You
  50. 50. But wait! There’s MORE!
  51. 51. Code is a liability. Your job is to provide value with as little code as possible.
  52. 52. How many lines of code does your main project have right now? If you don’t know, within 10%, then you’re ignoring it. Treat SLOC like credit card debt.
 Don’t add to it without knowing the balance.
  53. 53. Maintainability Index? Awesome, JavaScript is a real platform now! You’re drunk You’re both right.
  54. 54. Maintainability : 100 // empty file Well we can buy that.
  55. 55. Maintainability : 95 var foo = 42; Seems harsh, but ok.
  56. 56. Maintainability : 83 var foo = 42; ! var bar = Math.log(foo++); Holy crap, we’re dropping fast…
  57. 57. Maintainability : 92 var foo = 42; ! function calc(x) { return Math.log(x++); } ! var bar = calc(foo); Ok, that does seem better…
  58. 58. Toolable via grunt-complexity https://github.com/vigetlabs/grunt-complexity
  59. 59. What are we really working with here?
  60. 60. var vocabulary = unqOperators + unqOperands; var length = totOperators + totOperands; var difficulty = (unqOperators / 2) * (totOperands / unqOperands); var volume = length * Math.log2(vocabulary); var effort = difficulty * volume; ! But don’t look at var maintainabilityIndex = Math.max( 0, ( 171 + -3.42 * Math.log(aveEffort) + ! -0.23 * (aveComplexity) + -16.2 * Math.log(aveLOC) Smarter people are responsible ) * 100 / 171 ); me for questions
  61. 61. 1976 Thomas McCabe - Cyclomatic Complexity 1977 Maurice Halstead - Halstead Metrics 1991 Oman/Hagemeister - Maintainability Index Phil Booth JavaScript Implementation Ariya Hidayat Source Analysis (Esprima)
  62. 62. Oh, come on.
  63. 63. These numbers are for introspection and exploration These calculations have been praised and criticised, promoted and shot down. (and Halstead died before being able to defend them)
  64. 64. The point is
  65. 65. “ The unexamined code is not worth releasing ” - Socrates
  66. 66. Code is not just logic
  67. 67. Code is the api between imagination and reality
  68. 68. Inconsistent, complex Code is an inconsistent, complex API
  69. 69. Tool how you code
  70. 70. Hack how you code
  71. 71. Visualize how you code
  72. 72. Visualize Everything
  73. 73. Jarrod Overson @jsoverson jarrod@jsoverson.com jsoverson.com jsoverson.com/google+ jsoverson.com/linkedin jsoverson.com/github jsoverson.com/twitter

×