How Rocketium does in-browser editing of 10,000 images or videos

Aniketchanana
Rocketium
Published in
5 min readMay 9, 2021

Rocketium’s primary benefit for customers is creating images and videos at scale. Customers can do it with our web product or API. Our customers are marketing and design teams in high-growth companies. With their scale comes an ever-increasing number of campaigns, products, geographies, languages, experiments, and more. They can serve their needs with one-size-fits-all generic creatives or highly personalized banners and videos. Obviously, our customers choose the latter.

This means their scale went from making 1 creative at a time to thousands. Even when all of them look the same but have different content, it is a technical challenge to make it work on a browser on any computer. But now imagine if they want to make content or styling changes across the thousands of creative variants that they are making. Here are common examples of what our customers need to do:-

  • Add a new graphic element to all creative variants, say Christmas decorations for the upcoming holiday season.
  • Fix the line spacing because it did not look good.
  • Change the color combination to make it look more modern.
  • Change button text from SHOP NOW to BUY NOW.
  • Use an updated background shared by the brand team.

Without powerful bulk-editing capabilities, it would have been a nightmarish experience where they would have to spend hours making every change one by one.

Rocketium campaign
Old experience where you made each change one by one

Building bulk-editing capabilities

We conceptualized a bulk-editing experience that let users multi-select creative variants and edit their content or style. They could then review the changes across individual selections before applying those changes all at once.

Bulk-edit is about applying changes in one variant to all the other variants. Seen this way, it is a for loop with O(n) complexity. However, before running this simple-looking for loop, we had to make many changes to our Redux logic.

Approach 1: Service worker for data manipulation

Initially, we thought of putting our code to update data of multiple variants in a service worker file. There was a problem with this approach. For service works, we need to put our complete code of updating only a single variant in a service worker file.

Approach 2: Running the same code in the main thread (🙀)

The previous approach caused code duplication between service worker and the main application code. We did not want to do this and started thinking about how to update multiple variants with a loop running the same code which is used to update one single variant.

Problems faced with bulk operations in the main thread

1: Applying each Redux action dispatched from editing one variant to selected variants

To solve this problem, we first created a list of actions used to change our variant's data. After this, we created a Redux middleware that listens for all these actions and sends that action to a function that takes the data from the action and applies it to all the selected variants.

2: Refactoring logic used to update a single variant so it could be used to edit multiple variants

We extracted the logic used to update a single variant from the reducer function in a separate Javascript file. We created multiple small functions out of it to take variant data and return updated variant data. Now the same functions were ready to be used for updating multiple variants.

3: Crashes when editing 50+ creative variants

As we dug into this, we found that our Redux store was getting updated for all variants every time an editing action happens. For example, if we have 100 variants and do 10 editing actions, Redux is updated 10 times for those 100 variants.

We know Redux is efficient enough to handle multiple updates by making a shallow copy of the part that needed to be updated in the Redux store. However, our variant size was big enough that even if we create a shallow copy it was overloading memory.

Our solution was to reduce the number of store updates for the large state to reduce memory use. For this, we used a FIFO queue. Every time there is an update to the base variant, we store that action in a queue. For that action, we update only the currently active variant. When the user reviews another variant, we dequeue the action and apply all the actions on run-time to the variants. We cover the variants that were not visited when the user clicks on save by running a single for loop and updating our Redux state only once. This does not block the main Javascript thread.

4: Displaying a large number of variants in a list view

Rendering large lists in React can cause performance issues, especially when UI updates frequently. It can slow down the whole UI experience.

For this problem, we used react-window. This library makes it easy to create virtualized lists. It re-renders part of an extensive data set that is currently in the view to reduce the number of re-renders.

Finally, after solving all these problems our bulk-edit is ready to use.

Bulk-editing 1,648 creative variants like a boss 😎

I hope you understood the concept of how to do multiple state updates in the Redux state of large data set without compromising performance. See you soon and happy coding until then! ❤

--

--