By Lauren Bridge, Senior Software Developer, Zack Tanner, Senior Software Developer, and Matt Wong, Senior Software Development Lead
With the launch of our updated live guide on Hulu.com, tvOS, and Roku, we thought it’d be interesting to give a behind the scenes look at how we built the live guide experience and outline the technical challenges the team solved for, specifically when building for web.
Simplifying the Guide Layout
A significant challenge was rendering all the channels and a few hours of their programs into a grid. Our initial plan was to use CSS grid layouts to structure the layout.
Live TV feeds aren’t perfectly programmed every 15 or 30 minutes; instead, programs start at every minute of the day, with some only lasting a few minutes. In order to support this format, we realized we would need a column per minute to support the granularity of the TV programs. However, we wanted to show our viewers more than four to eight hours of content, which would result in hundreds of columns within the browser viewport and complicate the simple layout we had envisioned.
To resolve this challenge, we pivoted away from using CSS grid layouts and stacked the programs from left to right, where each program has a fixed-width — the remaining duration of the program multiplied by the fixed width of a 30-minute time block.
After sorting out our grid layout, we added pagination arrows and began fetching data so that users would be able to click forward to view future programming. After moving forward several hours, appending the additional programs to each row, and animating each row to the left, we began seeing performance issues.
We knew that expecting the browser to render hundreds of programs wouldn’t scale. We decided to leverage a common technique for saving CPU cycles that would be spent on rendering off-screen content: windowing.
We introduced windowing to the grid so we would only be rendering the visible programs and channels while deferring rendering of the rest until they entered the viewport. Using react-window, a slim react windowing library, we were able to set up and animate the scrolling capability of the channels and programs in the guide. The windowing of the channels (rows) we tied into the browser’s window scrolling, which allows the user to scroll up and down but still prevents the browser from rendering anything that is not visible. The windowing of the programs was tricky, since the programs are different widths in every column, so each channel’s programs are windowed individually. When users click the pagination button, we animate the scrolling of each row individually.
Left-aligning the first program
One of our final key challenges was to figure out a way to keep the text in the leftmost program in our grid visible. This was challenging, because as the user moves forward in time and the grid slides to the left, the programs that are going to be playing at the new first visible grid time need to re-align their content to be positioned at that time, instead of just at the beginning of the program. The inconsistency and variety of tv program start times and durations made it challenging to determine which program would be on at the new first visible time, let alone figure out how to left-align the content.
Our initial approach was to measure the distance required for each program’s text to slide and animate each program’s text individually the calculated amount, but we realized that this implementation would be complicated and performance-intensive
We instead chose to render the first program in each row twice — first in the grid to take up space and establish borders, and second floating above the grid. The floating program is absolutely positioned at the beginning of each row, so it is always left-aligned by default. We needed a bit of math to determine how wide that floating program should be so it doesn’t cover more than its’ shadow program underneath, but otherwise, this was an elegant and performant solution to a tricky problem.
Delivering the second version of the Live Guide was a fun and rewarding project for our team. We’ll continue to evolve the guide, integrate user feedback, and focus on more performance improvements.
If you’re interested in working on projects like these and powering play at Hulu, see our current job openings here.