React Performance Fixes on Airbnb Listing Pages

There may be a lot of low-hanging fruit affecting performance in areas you might not track very closely在ut are still very important.

Airbnb has some incredible listings in Cuba地nd also a corner of the office inspired by Habana Vieja
airbnb.com listing detail page: https://www.airbnb.com/rooms/8357

Methodology

Initial render

webpack-internal:///36:36 Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) ut-placeholder-label screen-reader-only"
(server) ut-placeholder-label" data-reactid="628"
~/airbnb 胼胼 ag ut-placeholder-label
app/assets/javascripts/components/o2/PlaceholderLabel.jsx
85: 'input-placeholder-label': true,
app/assets/stylesheets/p1/search/_SearchForm.scss
77: .input-placeholder-label {
321:.input-placeholder-label,
spec/javascripts/components/o2/PlaceholderLabel_spec.jsx
25: const placeholderContainer = wrapper.find('.input-placeholder-label');
101.63 ms spent re-rendering Redux-connected SummaryContainer
export default class SummaryIconRow extends React.Component {
...
}
export default class SummaryIconRow extends React.PureComponent {
...
}
103.15 ms spent re-rendering BookIt
8.52 ms spent re-rendering BookIt

Scrolling around

Really bad scrolling performance on Airbnb listing pages before any fixes
Slightly improved scrolling performance of Airbnb listing pages after some fixes
58.80 ms spent re-rendering StickyNavigationController
const anchors = React.Children.map(children, (child, index) => {      
return React.cloneElement(child, {
selected: activeAnchorIndex === index,
onPress(event) { onAnchorPress(index, event); },
});
});
const anchors = React.Children.map(children, (child, index) => {      
return React.cloneElement(child, {
selected: activeAnchorIndex === index,
index,
onPress: this.handlePress,
});
});
class NavigationAnchor extends React.Component {
constructor(props) {
super(props);
this.handlePress = this.handlePress.bind(this);
}
handlePress(event) {
this.props.onPress(this.props.index, event);
}
render() {
...
}
}
32.85 ms spent re-rendering StickyNavigationController
18.45 ms spent in _handleScroll
this.state = { inViewport: false };
this.inViewport = false;
1.16ms spent in scroll event handler
32.24 ms spent in AboutThisListingContainer re-render
render() {
...
const finalExperiments = {
...experiments,
...this.state.experiments,
};
return (
<WrappedComponent
{...otherProps}
experiments={finalExperiments}
/>
);
}
const getExperiments = createSelector(
({ experimentsFromProps }) => experimentsFromProps,
({ experimentsFromState }) => experimentsFromState,
(experimentsFromProps, experimentsFromState) => ({
...experimentsFromProps,
...experimentsFromState,
}),
);
...render() {
...
const finalExperiments = getExperiments({
experimentsFromProps: experiments,
experimentsFromState: this.state.experiments,
});
return (
<WrappedComponent
{...otherProps}
experiments={finalExperiments}
/>
);
}
function getFilteredAmenities(amenities) {
return amenities.filter(shouldDisplayAmenity);
}
Improved scrolling performance on Airbnb listing pages after these fixes

Clicking on things

42.38 ms re-rendering ReviewsContent
12.38 ms re-rendering ReviewsContent

Typing stuff

61.32 ms re-rendering Redux-connected ReviewsContainer
3.18 ms re-rendering ReviewsHeader

What did we learn?

--

--

Creative engineers and data scientists building a world where you can belong anywhere. http://airbnb.io

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Joe Lencioni

Web infrastructure at @airbnb. Making web since the 90s. Co-created happo.io. he/him Minnesotan, liberal, dad. Follow @lencioni on Twitter.