Carousel of rooms on the Wayfair home page
Rooms feed page
Clicking on a room opens a modal for you to see details
Room Planner is ready to take 2018 by storm. First impressions will be crucial for success, and we want to wow our customers with the best of what Room Planner is capable of. Traditional routes of marketing can bring eyeballs to our site, but we hypothesize that there are more barriers of entry into Room Planner once customers actually arrive at Wayfair. For many, the barrier is the complex nature of a tool that has infinite outcomes. This begs the question, how can we keep our customers from feeling overwhelmed?
Our solution to this problem is to create a feed of popular Room Planner rooms designed by the Wayfair community. The feed is populated with publicly-shared rooms made by Wayfair customers and designers. Once made public, rooms can be liked by others, leading to a natural ordering of popularity and (hopefully) quality. By using user-generated content to inspire, we are telling to our passively engaged customers "designing a room like this is possible", and to our actively engaged customers "this room you designed is awesome". All of this is done without manually curating rooms or spending extra marketing dollars!
The potential beneficiaries don't stop at the customers. This feed can give internal users incredibly important insight on how customers are actually using Room Planner. Until now, it was extremely difficult to view rooms made by our customers. You would have to log into a specific customer's account and go to the Room Planner tool. As you can imagine, it is a tedious task to collect visual data on multiple customers' rooms. Just loading the feed for the first time can reveal a lot about how customers are interacting with Room Planner.
Engineering - Overview
We decided to give this feed its own page, which you can reach at link. The feature was built using the typical Storefront tech stack, with a heavy emphasis on Redux and GraphQL. The challenge to this project was not so much dealing with new technology, but leveraging our existing tools to build a performant feed feature. In fact, every engineering decision made had performance in mind because how the feature scales is key to its success.
Engineering - Backend
The first challenge we faced was where and how we wanted to store the feed data. The strategy we took was to create a feed database table in SQL server and initially feed it the rooms with the largest number of items, as they are most likely to be visually complete. Although not yet implemented, our plan moving forward is to have a Jenkins job run every night that would calculate the most liked rooms to re-populate the table with a new set of data. We also discussed the idea of implementing Redis caching if we wanted more flexibility at the database level. We liked these two paths because we wanted to avoid having our customers run heavy queries every time they hit the page because it would incur huge stress on our servers and lead to a poor customer experience. We didn't believe the benefits of having real-time feed reordering would outweigh the costs.
Engineering - GraphQL
The next question we needed an answer to was how to bridge the data from the backend to the frontend, and GraphQL was our solution. To have performant pagination for our feed, we built a GraphQL schema using the Relay cursor connections spec for our feed items as well as the likes for each feed item. Although it is difficult to delve into the actual performance implications given our limited data and time, what I can vouch for is how quick and easy it was to implement cursor based pagination with Relay. It was first introduced to Wayfair by the Idea Boards team as a POC, and we found that this project served as another use case.
Engineering - Frontend
Once the GraphQL schema and queries were functional, the next step was to build Redux reducers with a heavy emphasis on data normalization. GraphQL enabled us to wisely query for data in pieces so we didn't have the user waiting for anything longer than necessary, but all of that data is eventually accumulated in the frontend.
Think about how much data our feed contains. From rooms, products, and prices, to likes and customers, that's a lot of data! The Redux architecture we designed was inspired by the byId/allIds standard taught in the Redux docs, and is something we would highly recommend to the rest of Wayfair. This practice helps to flatten your Redux schema and access data from your frontend "datastore" in constant time given an id. The combination of optimistic UI updates in Redux thunks, skeleton states, and normalized reducers has helped us to create an app with a snappy frontend experience.
What's next for MVP
To get this feature in front of customers, we need to:
- Run a Jenkins job to update the feed daily with the most popular rooms.
- Cater some initial data for our customers to see on the feed Day 1 since there won't be any "likes" yet.
- Give individual rooms its own URL so customers can view rooms from the feed on its own page.
- Add a way for users to view rooms they have liked. This could be on an Idea Board, or on its own page.
- Build security monitoring for potentially inappropriate room images. This is a similar challenge to dealing with photos uploaded for product reviews.
To get this feature in front of internal users, we need to:
- Build more ways to filter what rooms show up on the feed.
It is also important to properly stress test this. There is much room for additional performance improvements, especially in the backend. I'd like to do an analysis on the GraphQL resolvers we built to see where the major pain points are. Setting up Redis caching for our feed item and like models should be first priority.
This feature is set up to be flexible for future iterations. We can apply different strategies to how the feed is ordered. For example, customers might want to see rooms with purple sofas. Or maybe they want to see bedrooms designed at less than $2000. Or, to take it one step further, maybe they want to upload a photo of their room to find visually similar rooms. To build this would require writing new SQL queries or probably something more cutting edge like machine learning and visual search algorithms. If you've managed to read this far, you might even have ideas of your own! We'd love to hear.