What is Decoupling?
Decoupling has been gaining momentum in the past couple years. An increasing number of websites and applications combine their content management system’s backend and editorial capabilities with a separate framework that renders the front end.
The idea is to make data available in a different format (usually JSON) so the framework can parse it, and so the developer can take full control of the markup, UI, routing, etc. While it’s not ideal for certain types of sites (if you have a lot of pages for instance), it becomes very handy when dealing with single page applications or projects that require a lot of user interaction.
I recently attended Decoupled Dev Days in New York City. This two day event was a way to gather a small portion of the Drupal community (and others) for an in-depth look at the work many people are putting toward making Drupal an attractive backend for a decoupled app. Guest speakers were also main contributors for Angular.js and Ember.js, which was beneficial; the goal was not to make another Drupal centric conference, but rather to attract a broader audience within the tech community.
It was a great opportunity to see the community at work and to get insights about implementation, performance, tools, and more while working on a decoupled app myself.
Two sessions were presenting what we would call Drupal install profiles - basically starter kits for a Drupal 8 decoupled project. Contenta and Reservoir both aim to get your Drupal install ready for beheading. They are also both quite opinionated in what they keep and remove from a regular install. I’d recommend reading this comparison article to learn more. Let’s keep in mind that these projects are in constant development and the early writing about them may not reflect some of the latest development phases.
Now An Then
Our team started working on a decoupled project for NowAnThen.com a few months ago. This site, a product of Wonderful Machine, is aimed towards engaging photographers, genealogists (amateur and expert!), and educators in creating timelines of their own images or of photos uploaded throughout the site. Users add the photos to their personalized timelines to create another medium for visual storytelling. Some timelines have only a few photos while others (such as the Global Timeline found on the home page) will have a vast amount of images attached to it. No matter what, the images should be able to load smoothly onto the timeline in order to create a seamless history viewing experience.
When we first heard the pitch for this site, we were immediately intrigued and up for the challenge. The site is essentially based on a scrollable, searchable timeline of images with metadata (caption, linked author etc). We inherited a prototype that was buggy and not scalable. The client wanted a robust solution in order to handle high traffic and offer more features while keeping the performance optimal. A user’s focus should be on the images and content of the site, rather than the site’s shortcomings.
We chose to decouple our own install profile with React for this project. It made perfect sense to just use Drupal for some basic functionality (paging, login and account creation, and obviously all the good backend stuff). Keeping this functionality as simple as possible was essential for this project. We chose to do the routing with Drupal as it seemed to add a lot of extra work with React for no legitimate reason. We basically decoupled the main content region of our theme layer.
I had worked with Angular and Drupal in the past for a simple project (bearangular.zivtech.com) as a way to get some chops, and I found React’s learning curve to be easier. It’s quite subjective, but I felt the level of abstraction was higher with Angular, making my understanding of the Javascript’s “behind the scenes” much more difficult.
My co-worker had already set up the app and made the Drupal data available to React through a custom module that passed the data through the Drupal.settings API. I didn’t have much to do to get up to speed with some of the syntax and JSX custom elements - everything was pretty straight forward. I had to brush up my ES6 skills and after doing a lot of jQuery, I actually really enjoyed jumping back into vanilla JS.
We used webPack to compile the JS and went through the usual npm workflow. Module installations were super simple, which was a nice change from the Drupal module world. It was all fun and games until we had to optimize for performance. We were building something that had not been done before and it required some serious brain twisting.
The homepage is a timeline of all images on the site, and this is where things got interesting. We needed to imagine a scenario with, say, a timeline of one million images. As we are dealing with overflown content, it seemed clear we could only load what’s in the viewport, such as an infinite scroll. But it’s not that simple.
We wanted to provide a smooth experience while scrolling, so the regular infinite scroll was not exactly an ideal solution. Instead, we decided to work with subsets of 15 images loaded initially, loading the next subset at a half past scroll in any direction (and unmounting the subset on the further opposite). We also had to have the date scroller respond to the timeline both when dragging it, clicking anywhere on its axis, or on scrolling through the timeline.
In the end, the challenges in this project had less to do with React itself and more to do with problem solving and implementation. React’s abilities excelled for the purpose of this project. It provided a complex solution to be implemented simply within the existing build. We believe decoupling will become an essential part of our development process for projects that have similar needs to NowAnThen.