1 of 40

Interactive frontend development

Urmas Talimaa

SaleMove Inc

2 of 40

Bug reports

Product manager received a complaint from a customer:

I tried to use feature X, but when I clicked on the button, nothing happens. I tried this several times, nothing happens at all. Also feature Y is not working at the same time. When I refresh then everything is back to normal.

3 of 40

Bug reports

Product manager approaches the developer responsible for the user interface and asks to investigate and fix the problem.

You, the developer, go digging into the user interface and backend logs. The logs are hard to parse (as is usual), no bugs can be identified from the logs.

Using feature X works both locally and in the production environment, bug is not reproducible.

4 of 40

Bug reports

A lot of time wasted trying to reproduce the issue, no idea what and how to fix.

Developers are unhappy

Product managers are unhappy

Customers are unhappy

5 of 40

6 of 40

Redux action history

  • Add a bug reporting button to your application
  • Customer arrives at erroneous application state and clicks button
  • Action history is submitted to your server
  • You load the history in your browser and time-travel through the usage

The order of user interface transitions that surfaced a bug can be easily viewed and understood.

The bug might be in the user interface, but might also be in the backend or anywhere in between instead.

7 of 40

Redux action history

Rebel against wasting time trying to debug issue backend bugs through the user interface.

Order serializable, human readable user interface history today!

8 of 40

Redux action history

Hard to catch race conditions are the bane of developers.

Isolate and identify them with standardized, complete logs of the user interface!

9 of 40

10 of 40

Where to display all the views?

On a single Page?

Image courtesy of Derick Bailey.

11 of 40

Multi-Page Single Page Application

  • We cannot pack all our functionality in a single always-visible page
  • We could render different views when the application is in different states
    • Create actions to navigate the app
    • Bind those actions to link clicks
    • Reduce the actions into navigation state
    • Show certain views based on the current navigation state

12 of 40

Another problem

What if I’m deep in a single page application and a friend wants to open the same page?

Disappointment when friend lands to the landing view.

13 of 40

These are solved problems

Traditional web pages have had this solved from the beginning:

The URL.

14 of 40

History API

  • https://developer.mozilla.org/en-US/docs/Web/API/History_API
  • The history API allows
    • Pushing new URL and title to the history - effectively navigating to a different URL
      • The back button navigates to the previous URL
    • Replacing the current URL and title in the history
      • The back button navigates to the previous URL from the previous URL
    • Going back n steps
    • Going forward n steps
  • We can listen for changes in the history using onpopstate

15 of 40

History API

  • This allows us to implement a single page application that
    • Has different pages for different UI screens
    • Uses links (and automatic navigation) to change the pages
    • Navigates to the URL of the appropriate UI screen when URL is entered in the browser or the URL changes
    • Allows copying and pasting links to other browsers/people

16 of 40

17 of 40

React Router

  • Every framework has its own routing mechanism that builds on top of the history API
  • https://reacttraining.com/react-router/

The React Router

  • Links routes (URLs) and components
  • Declarative routing
  • Variables in routes are passed to components as props
    • Component with route "/user/:userId" can use props.match.params.userId

18 of 40

19 of 40

Where’s the elephant in the room?

20 of 40

Where’s the elephant in the room?

  • We have added additional state to our application
  • That state is not captured in our single source of truth
  • We lose much that we have worked so hard to achieve when adding important application state that is not captured in Redux.

21 of 40

Where’s the elephant in the room?

  • Changes in history are not reflected in Redux state
  • Changes in Redux state (time travelling) are not reflected in history or routing
  • Auto-navigation means directly mutating history in action creators

22 of 40

Connected React Router

  • Luckily there’s a suitable adapter that synchronizes history with Redux state
  • https://github.com/supasate/connected-react-router
  • React router also provides its own binding, but it is in beta (for v4 React Router) and currently does not work correctly with regards to time travelling using Redux dev tools.

23 of 40

Connected React Router

  • React Router version 4 has improved upon the previous versions a lot
  • Previously the React-like syntax was basically just configuration
  • Now there are actual React components performing the routing, which is much easier to manage and extend

24 of 40

What not to do with URLs

  • Do not implement wizards with different routes
  • Each Route should make sense on it’s own without requiring a specific status of some process in state

25 of 40

What not to do with URLs

Example flow:

dispatch(proceedToStepFour());�dispatch(push('/stepFourInProcess'));

  • In what order should these actions be dispatched?
  • What component should be shown in between then?
    • Is there sufficient state to provide props for that component?
  • One interaction = one action
    • Automatic navigation violates this, but if the route that is navigated to makes sense in isolation, then it is just providing convenience without affecting maintainability.

26 of 40

27 of 40

Optimization

General information and tips from https://facebook.github.io/react/docs/optimizing-performance.html

While optimization of React applications is not required for small or medium sized applications, thinking about ways to optimize generally (for arbitrary components) is useful.

28 of 40

Optimization

  • How much of the comment app is re-rendered when changing location from one comment to another?
  • How much actually has to be re-rendered?
  • One of the simplest ways to optimize is to cut down on re-renderings
    • Even though the actual DOM isn’t changing the virtual DOM still needs to be created and diffed
  • First step is to identify what components are changing
    • This can be done using React Dev Tools (Trace React Updates)
  • console.count(label) can be used in chrome to count operations

29 of 40

Optimization

  • React shouldComponentUpdate(nextProps, nextState) callback can be implemented to keep previous rendering of a component
  • Problem solved?

30 of 40

31 of 40

Optimization

Hand-writing shouldComponentUpdate is error prone and hard to maintain.

There must be a better way!

We are using pure functions and functional programming, �good things are supposed to happen.

32 of 40

Optimization

  • Components created by react-redux connect already implement shouldComponentUpdate by checking shallow equality of parameters
  • Deep equality checks are not done to avoid introducing unexpected performance degradation.

33 of 40

Optimization

  • Selector functions are pure functions and create new objects from objects in state
  • A new object is not shallow-equal to any previous one
  • Selector functions considered harmful???

34 of 40

Optimization

35 of 40

Be careful

36 of 40

Simplest method cache

  • Has size 1
  • Invalidation is trivial
  • Used in reselect

37 of 40

38 of 40

Immutable JS

  • Immutable JS provides collections (Maps and Lists) and performant methods to create new collections.
  • Using Immutable JS can be faster than creating new JavaScript objects using the spread operator or Object.assigns every time.
  • However, using Immutable JS means that your whole codebase should use Immutable JS objects as they have a different interface from standard JavaScript objects
  • Trade-offs…
  • https://redux.js.org/recipes/using-immutable.js-with-redux

39 of 40

Homework

  • Only submit what is yours

40 of 40