Slide 1

Slide 1 text

The Need For Speed Measuring Latency In Single-Page Applications Jordan Hawker RVA JavaScript November 2018

Slide 2

Slide 2 text

November 2018 Jordan Hawker 2 Performance: Why Do We Care? Poor performance impacts business metrics – Bounce Rates – Conversions – Feature Throughput – Revenue Impact – User Satisfaction

Slide 3

Slide 3 text

November 2018 Jordan Hawker 3 Instrumentation Before Optimization ● You don’t know what to optimize without data ● Backend Instrumentation – Mature instrumentation options – Detailed information about services – Doesn’t provide the full picture ● Can we track performance across the whole stack?

Slide 4

Slide 4 text

November 2018 Jordan Hawker 4 Web Application Performance ● Response Time ● Throughput ● Availability ● Responsiveness ● Rate of Requests ● Resource Consumption ● Efficiency ● Latency What does that even mean?

Slide 5

Slide 5 text

November 2018 Jordan Hawker 5 Interactivity User-Perceived Latency

Slide 6

Slide 6 text

November 2018 Jordan Hawker 6 Priority: User Experience ● Each metric has its own use, but... ● Real-world performance impact is paramount – Know what your users are seeing – Gather data on different devices and browsers – Understand variance across global regions ● Improvements across the stack will be reflected

Slide 7

Slide 7 text

November 2018 Jordan Hawker 7 Time To Interactivity The time it takes for the critical content of a page to load such that the user believes they can engage in their primary purpose visiting that page.

Slide 8

Slide 8 text

November 2018 Jordan Hawker 8 Third-Party Tools

Slide 9

Slide 9 text

November 2018 Jordan Hawker 9 PageSpeed Insights

Slide 10

Slide 10 text

November 2018 Jordan Hawker 10 WebPageTest

Slide 11

Slide 11 text

November 2018 Jordan Hawker 11 Lighthouse

Slide 12

Slide 12 text

November 2018 Jordan Hawker 12 Evaluating Third-Party Tools ● They give great overviews of app performance ● Detailed suggestions for optimization ● They don’t understand how SPAs render ● Data is a rough approximation at best ● How can we leverage framework internals?

Slide 13

Slide 13 text

November 2018 Jordan Hawker 13 Architecture

Slide 14

Slide 14 text

November 2018 Jordan Hawker 14 Critical Path ● Each page has primary activities ● Components related to that content are “critical” ● Secondary components – Also rendered on the page – Not tied to the primary activity – Don’t need to finish rendering

Slide 15

Slide 15 text

November 2018 Jordan Hawker 15 DOM Is A Tree ● ...and so are your apps! ● Pages are nested layers of components ● Each route or component has direct children ● Components with no children are “leafs” ● Each component waits on its children to render

Slide 16

Slide 16 text

November 2018 Jordan Hawker 16 Subscriber-Reporter Relationship ● Subscriber – Relies on child components (reporters) to render – Complex conditions for interactivity ● Reporter – Reports its own render times – Child of a subscriber – May also be a subscriber itself

Slide 17

Slide 17 text

November 2018 Jordan Hawker 17 Implementation

Slide 18

Slide 18 text

November 2018 Jordan Hawker 18 Approach ● Leverage hooks to approximate rendering ● Account for async behavior (e.g. requests, images) ● Capture per-component events & roll up to page ● Tie parents to their children to bubble data – Working up from the bottom of the tree is optimal – When child reports, check parent for interactivity ● Common method to check complex conditions

Slide 19

Slide 19 text

November 2018 Jordan Hawker 19 React ● componentDidMount – Invoked immediately after a component is mounted ● Create a higher-order component (HOC) – Provides components with this latency behavior ● Parent/Child relationship – this.props.children gives access to child components – Pass a parent reference down to children

Slide 20

Slide 20 text

November 2018 Jordan Hawker 20 Ember ● Routes: didTransition ● Components: didInsertElement ● Leverage Runloop – run.scheduleOnce('afterRender', this, this.reportInteractive) ● Parent/Child Relationship – this.parentView is a direct reference to the parent ● Ember-Interactivity: jhawk.co/interactivity-demo

Slide 21

Slide 21 text

November 2018 Jordan Hawker 21 Angular ● ngAfterContentInit – Called after Angular fully initializes all content of a directive ● Parent/Child Relationship – this.parentInjector.view.component

Slide 22

Slide 22 text

November 2018 Jordan Hawker 22 Vue ● mounted – Called after the instance has been mounted ● this.$nextTick – Called after all children have been rendered ● Parent/Child Relationship – this.$parent

Slide 23

Slide 23 text

November 2018 Jordan Hawker 23 Developer Tooling

Slide 24

Slide 24 text

November 2018 Jordan Hawker 24 Performance API ● Browser interface that provides performance info ● performance.mark – Creates a timestamp in the performance buffer ● performance.measure – Creates a measure between two timestamps ● Data can be inspected, tracked, and visualized

Slide 25

Slide 25 text

November 2018 Jordan Hawker 25 Performance Recording

Slide 26

Slide 26 text

November 2018 Jordan Hawker 26 User Timing

Slide 27

Slide 27 text

November 2018 Jordan Hawker 27 Timings in Third-Party Tools

Slide 28

Slide 28 text

November 2018 Jordan Hawker 28 Conclusions

Slide 29

Slide 29 text

November 2018 Jordan Hawker 29 What We Learned ● Define Critical Path ● Identify Bottleneck Components ● Defer Non-Critical Components ● Holistic user-centric metrics reflect improvements across the stack

Slide 30

Slide 30 text

November 2018 Jordan Hawker 30 The Path Forward ● Leverage multiple tools for instrumentation ● Measuring each layer of the stack is useful ● Capture real user metrics to understand impact ● Virtual machines are insufficient simulations ● Use framework-aware tools for granular data ● Be cognizant of the performance impact of leveraging framework internals

Slide 31

Slide 31 text

November 2018 Jordan Hawker 31 Thank You! JordanHawker elwayman02 www.JordanHawker.com Slides: jhawk.co/rva-18-latency