HSStudio Part 2/3: React for Speed on Mobile

In Part 2 of our three-part series about the custom surfboard configurator we made for Haydenshapes, I’m going to break down how we leveraged React.js for speed on mobile. If you haven’t read Part 1: Three.js for In-Browser 3D, feel free to loop back and start at the beginning.

React

We really love React.js because of its programming model and performant nature. We wanted to make HSStudio feel as app-like as possible, and React was a key component to achieving high frame rates. Although the interface appears straightforward, there is a lot happening under the hood.

For instance, when the user changes their board length, the app:

  1. Sets the activeLength in the state object
  2. Parses an array to find the available min/max width and thickness of the board (longer boards are made wider and thicker than shorter boards)
  3. Performs a volume lookup based on the current dimensions
  4. Draws a new texture with the dimensions in it
  5. Determines shouldComponentUpdate and redraws the relevant GUI elements

When the user changes a configuration option, such as selecting a new technology, we:

  1. Update the activeTechnologyUid in the state object
  2. Enable/disable any child options while ensuring any previously selected child options are re-selected
  3. Parse other configuration options and look for incompatibilities
  4. For instance, certain logos are not compatible with certain artworks, and certain artworks are not compatible with certain technologies. Changing a technology can affect the selected logo even though they’re not directly related to one another.
  5. Recalculate the price, which is the sum of the option prices, but prices change per user type and geography
  6. Update the url (note that the entire state object is represented in the url, so we can save state very effectively)

What we learned about React

  1. shouldComponentUpdate is performance’s best friend. This prevents any dom redraws by comparing data. We should only update the UI when its state data changes, like so:
shouldComponentUpdate: function(newProps, newState) {
  return (newProps.active !== this.props.active ||
    newProps.model !== this.props.model ||
    newProps.orderID !== this.props.orderID ||
    newProps.activeBitlyURL !== this.props.activeBitlyURL
  );
}

2. Selecting active elements is a breeze in our render function.

{this.props.logos.map(function(logo, key) {
var active = (activeLogoUid === logo.slug);
return <LogoListItem active={active} />
})}

3. Saving state drastically reduces testing time.

We serialize our state into a query string so when Grunt refreshes the page following a code change, we’re exactly where we were. No need to reproduce steps! We took advantage of React’s getInitialState to pull info from the query string and run the relevant methods.

Putting it all together

React was essential in building a performant webapp thanks to its strong functionality. To see it in action, head to HSStudio and build your perfect custom.

Next up

Part 3: Customizing Shopify

Thanks

This project would not have been successful without the hard work of many individuals. Our senior front-end engineer, Eric, did a great building the Bravenec© GUI, and Alex Roper nailed some iron-clad last-minute weekend coding. We’d like to thank our client, Hayden, for having the vision and trust while we sorted out how to accomplish his goals, as well as his team for building thousands of assets. It’s also important to recognize the efforts of the Three.js and Shopify communities. Without such excellent resources, we would have been adrift.

Credits

Technical Director: lucastswick
Creative Director: Chris Erickson
Designer: Willy Bravenec
Senior Front-End Engineer: Eric Van Holtz
Project Manager: Aaron Noah


Lucas is a Technical Director at Parliament where he helps brands like Haydenshapes do the impossible.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.