Treebo like to implement their skeleton screens using preview enhanced components (a little like skeleton screens for each component). The approach is basically to enhance any atomic component (Text, Image etc) to have a preview version, such that if the source data that is required for the component is not present, it shows the preview version of the component instead.

For example, if you look at the hotel name, city name, price etc in the list items above, they’re implemented using Typography components like <Text /> which take two extra props, preview and previewStyle which is used like so.

Basically, if the hotel.name does not exist then the component changes the background to a greyish color with the width and other styles set according to the previewStyle passed down (width defaults to 100% if no previewStyle is passed).

Treebo likes this approach because the logic to switch to the preview mode is independent of the data actually being shown which makes it flexible. If you look at the “Incl. of all taxes” part, it’s just static text, which could have been shown right at the start but that would’ve looked very confusing to the user since the prices are still loading during the api call.

So to get the static text “Incl. of all prices” into a preview mode alongside the rest of the ui they just use the price itself as the logic for the preview mode.

This way while the prices are loading you get a preview UI and once the api succeeds you get to see the data in all its glory.

Webpack-bundle-analyzer

At this point, Treebo wanted to perform some bundle analysis to look at what other low-hanging fruit they could optimize.

Note: If you’re using a library like React on mobile, it’s important to be diligent about the other vendor libraries you are pulling in. Not doing so can negatively impact performance. Consider better chunking your vendor libraries so that routes only load those that are needed

Treebo used webpack-bundle-analyzer to keep track of their bundle size changes and to monitor what modules are contained in each route chunk. They also use it to find areas where they can optimize to reduce bundle sizes such as stripping moment.js’ locales and reusing deep dependencies.

Optimizing moment.js with webpack

Treebo relies heavily on moment.js for their date manipulations. When you import moment.js and bundle it with Webpack, your bundle will include all of moment.js and it’s locales by default which is ~61.95kb gzipped. This seriously bloats your final vendor bundle size.