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

Standing on the Shoulders of Giants or How to Read the Internals of React.js

Standing on the Shoulders of Giants or How to Read the Internals of React.js

Standing on the Shoulders of Giants
or
How to Read the Internals of React.js:

A talk about how to read code and libraries

Üstün Özgür

May 27, 2015
Tweet

More Decks by Üstün Özgür

Other Decks in Programming

Transcript

  1. Standing on the Shoulders of Giants
    or
    How to Read the Internals of React.js
    Üstün Özgür
    @ustunozgur

    View Slide

  2. If I have seen further
    than others, it is by
    standing on the
    shoulders of giants.

    View Slide

  3. Libraries

    View Slide

  4. Library Users
    From https://flic.kr/p/e8XRdD

    View Slide

  5. user (noun) /ˈjuːzə/
    A person who uses or operates something
    A person who takes illegal drugs;
    an addict

    View Slide

  6. Library users in real life read
    Library users in compute write,
    but rarely read.

    View Slide

  7. A computer language is not
    just a way of getting a
    computer to perform
    operations but rather that it
    is a novel formal medium for
    expressing ideas about
    methodology.
    Thus, programs must be
    written for people to read,
    and only incidentally for
    machines to execute.

    View Slide

  8. We should read
    libraries

    View Slide

  9. Why not?

    View Slide

  10. The acts of the mind [...] are chiefly these
    three:
    1. Combining several simple ideas into one
    compound one, and thus all complex ideas are
    made.
    2. The second is bringing two ideas together
    [...] to take a view of them at once, without
    uniting them into one, by which it gets all its
    ideas of relations.
    3. The third is separating them from all other
    ideas that accompany them in their real
    existence:
    this is called abstraction, and thus all its general
    ideas are made.
    John Locke, An Essay
    Concerning Human
    Understanding (1690)

    View Slide

  11. Libraries are abstractions.
    Good libraries are good abstractions.

    View Slide

  12. You probably will not read the code:
    - If you encounter no problems using the library
    - If the documentation is clear and abundant
    - If library has no bugs
    Does this mean you
    do not need to read the code?

    View Slide

  13. Why?

    View Slide

  14. • Intellectual curiosity
    • Understanding how software we write really works
    • Understanding how large applications are written
    • Benefiting from the experience of other programmers
    • Learning the language better
    • Leaky Abstractions
    • Coding is mostly reading and maintenance
    • We already read our coworkers and previous self's
    codes all the time

    View Slide

  15. We need rigor and
    technique

    View Slide

  16. How to Read Libraries
    Code

    View Slide

  17. View Slide

  18. "Great Books". Licensed under CC BY-SA 2.0 via Wikimedia Commons - http://commons.wikimedia.org/wiki/File:Great_Books.jpg#/media/File:Great_Books.jpg

    View Slide

  19. "I. The first reading can be called structural or analytic.
    Here the reader proceeds from the whole to its parts.
    II. The second reading can be called interpretative or
    synthetic. Here the reader proceeds from the parts to the
    whole.
    III. The third reading can be called critical or evaluative.
    Here the reader judges the author, and decides whether he
    agrees or disagrees. "
    From How to Read a Book by Adler

    View Slide

  20. - the structure and purpose of the book
    - note any divisions in the book
    - what problems the author is trying to
    solve.
    Structural

    View Slide

  21. Interpretive
    • constructing the author's arguments
    • special phrases and terms
    • understanding deeply

    View Slide

  22. Critical Stage
    • critique the book
    • judge the book's merit and accuracy
    • agree or disagree with the arguments

    View Slide

  23. Reading Libraries

    View Slide

  24. • Code is not linear, where do we start?
    • There is no argument, it either works
    or not
    • There is no single author
    • Some parts are legacy or for
    backwards compatibility
    Differences from Reading a Book

    View Slide

  25. Structural Stage
    • Understand the main purpose of the library
    • Understand how the public API (interface) is used
    • Read through the usage docs

    View Slide

  26. Structural Stage
    • Understand the hierarchy and skeleton of files
    • Directory level
    • Dependency level
    • Try to understand the main purpose of the library and
    key points
    • Try to go through the build process and see how
    pieces fit

    View Slide

  27. Tools for This Stage
    • Documentation and experimentation
    • Look at the directory structure
    • Look at the dependencies
    • Find the super nodes: most depended files
    • Try to find largest and most complex files

    View Slide

  28. Example
    React library

    View Slide

  29. View Slide

  30. View Slide

  31. Number of Files
    0
    75
    150
    225
    300
    Number of Lines
    0
    7,500
    15,000
    22,500
    30,000
    Versions 0.3 to 0.13

    View Slide

  32. Main Goals
    • It is a view layer
    • Rerender the views all the time
    • Componentize the application
    • Explicit state changes and flow of props

    View Slide

  33. var  HelloWorld  =  React.createClass({  
       render:  function  ()  {  
           return  Hello  World;  
       }  
    })
    React.createElement("div",  null,  "Hello  World")
    JSX
    React.render(,  document.body)

    View Slide

  34. var Counter = React.createClass({
    getInitialState: function () {
    return {counter: 0};
    },
    increment: function () {
    var currentCount = this.state.counter;
    this.setState({counter: currentCount + 1});
    },
    render: function () {
    return
    You clicked {this.state.counter} times.
    Increment
    )})

    View Slide

  35. Virtual DOM

    View Slide

  36. Directory Structure &
    Finding the Starting Point
    and Super Nodes

    View Slide

  37. Finding Biggest Files Crudely
    all_files = "find . -type f -name '*.js' -exec ls -l {} \;"
    files = os.popen(all_files).read().strip()
    sizes = Counter()
    for row in files.split('\n'):
    row = row.strip()
    file = row.split(' ')[-1]
    size = int(row.split(' ')[7])
    sizes[file] = size
    pprint.pprint(sizes.most_common(100))

    View Slide

  38. browser/ui/ReactMount.js', 29383
    classic/class/ReactClass.js', 28048
    core/ReactCompositeComponent.js', 27862
    browser/ui/ReactDOMComponent.js', 16391
    browser/eventPlugins/BeforeInputEventPlugin.js', 15126
    classic/element/ReactElementValidator.js', 13748
    browser/eventPlugins/SimpleEventPlugin.js', 12328
    browser/ReactBrowserEventEmitter.js', 12271
    core/ReactMultiChild.js', 12011
    browser/eventPlugins/ChangeEventPlugin.js', 11475
    browser/eventPlugins/ResponderEventPlugin.js', 11108
    classic/types/ReactPropTypes.js', 10895
    core/ReactInstanceHandles.js', 10019
    browser/ui/dom/DOMProperty.js', 9600
    core/ReactUpdateQueue.js', 9421
    core/ReactUpdates.js', 8530
    browser/eventPlugins/AnalyticsEventPluginFactory.js', 8301

    View Slide

  39. Finding Most Depended Files Crudely
    all_files = "find . -type f -name '*.js'"
    require_count = "ag --ignore=__tests__ %s | grep require | wc -l"
    files = os.popen(all_files).read().strip()
    n_occurrences = Counter()
    for file in files.split('\n'):
    if file.split('/')[1] in ['vendor', 'stubs', 'test', 'utils']:
    continue
    n_occurrences[file] = int(os.popen(require_count % file.split('/')
    [-1].replace('.js', '')).read().strip())
    pprint.pprint(n_occurrences.most_common(100))

    View Slide

  40. classic/element/ReactElement.js', 33
    addons/update.js', 22
    browser/ReactDOM.js', 17
    modern/class/ReactComponent.js', 16
    event/EventConstants.js', 16
    browser/ui/dom/DOMProperty.js', 15
    core/ReactUpdates.js', 13
    classic/class/ReactClass.js', 12
    browser/ui/ReactMount.js', 11
    browser/ui/ReactBrowserComponentMixin.js', 9
    browser/syntheticEvents/SyntheticEvent.js', 9
    core/ReactCurrentOwner.js', 9
    event/EventPropagators.js', 8
    core/ReactInstanceMap.js', 8
    browser/ReactBrowserEventEmitter.js', 7
    addons/ReactFragment.js', 7
    core/ReactInstanceHandles.js', 7

    View Slide

  41. Demo: Overview of
    Directory Structure

    View Slide

  42. Level 2: Diving Down
    • Getting into source code
    • Static reading
    • Lots and lots of searching , grepping and ack'ing and even
    better ag'ing!
    • Which file uses which?
    • Which file is used by which?
    • Tooling support

    View Slide

  43. Static Reading

    View Slide

  44. Tooling
    Use all the tools, all
    the editors, IDEs!
    Hint: Emacs can do anything,
    even open Vim

    View Slide

  45. Level 2: Diving Down
    • Dynamic reading from the browser
    • Experimentation with variables in the browser
    • Running and reading the tests
    • Reading advanced documentation

    View Slide

  46. Important Files
    • React.js
    • ReactMount->render
    • ReactClass: calls ReactComponent
    • ReactMultiChild for rendering

    View Slide

  47. * - constructor: Initialization of state. The instance is now retained.
    * - componentWillMount
    * - render
    * - [children's constructors]
    * - [children's componentWillMount and render]
    * - [children's componentDidMount]
    * - componentDidMount
    *
    * Update Phases:
    * - componentWillReceiveProps (only called if parent updated)
    * - shouldComponentUpdate
    * - componentWillUpdate
    * - render
    * - [children's constructors or receive props phases]
    * - componentDidUpdate
    *
    * - componentWillUnmount

    View Slide

  48. Demo: Deep Dive

    View Slide

  49. Level 3: Critique
    • What feels right about React?
    • What feels wrong?
    • Are there any leaky abstractions?
    • What could have been done differently?

    View Slide

  50. • Some Critique From Community
    • Modularity?
    • Virtual-Dom and Mercury projects
    • https://github.com/Matt-Esch/virtual-dom

    View Slide

  51. View Slide

  52. View Slide

  53. • Some Critique From Community
    • Cycle.js: Honestly Reactive
    • Rx decouples data production from data
    consumption. Apps in Cycle have nothing comparable
    to imperative calls such as setState(), forceUpdate(),
    replaceProps(), handleClick()

    View Slide

  54. • Some Critique From ClojureScript Community
    • No setState
    • Easy shouldComponentUpdate
    • Just pass props from the top

    View Slide

  55. Thanks
    Ustun Ozgur
    @ustunozgur
    [email protected]

    View Slide