Part 1| Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7
In recent years, one of the most exciting emerging areas of web development has come in the form of offline-enabled and offline-first functionality. Thanks to frameworks like Yjs, an open-source framework for real-time collaboration, offline-first applications are now a reality. Leveraged in conjunction with Service Workers and IndexedDB, a browser-based database, Yjs enables the implementation of collaborative applications that double as offline-first tools. Applications that work offline are essential, particularly when collaboration is required in areas with low connectivity.
Recently, your correspondent (Preston So, Editor in Chief at Tag1 and author of Decoupled Drupal in Practice) sat down with Tag1 colleagues Kevin Jahns (creator of Yjs and Real-Time Collaboration Systems Lead at Tag1), Fabian Franz (Senior Technical Architect and Performance Lead at Tag1), and Michael Meyers (Managing Director at Tag1) for an episode of Tag1 Team Talks about the range of possibilities available to developers leveraging Yjs for offline-first applications. In this multi-part blog series, we inspect some of the most fascinating features in Yjs that enable robust offline-enabled collaboration. In this first installment, we motivate offline applications and discuss the meaning of the term offline-first.
As we progress through this blog series, we will examine more deeply many of the concepts involved in offline-first collaboration. In the second installment, we cover how Yjs supports offline editing use cases, followed by a discussion of how to support offline documents with y-indexeddb. The fourth part of this blog series dives into conflict resolution with IndexedDB and Yjs, while parts five and six cover y-webrtc and garbage collection. Parts six and seven end with the limitations of content revision histories and challenges for garbage collection, an important and complex discussion.
What is an offline application?
During our wide-ranging conversation, we first covered a fundamental question of offline collaboration: What exactly do we mean when we say that applications are offline? After all, ever since the very beginnings of the web, in one sense we have misused the web to create robust applications. We enjoy web applications because they are available to us on all devices and synchronize data with the cloud, offering an efficient and pleasant user experience. Nonetheless, a significant disadvantage of the web is that it is not available offline. Consider being on a plane or train with a slow connection. Accessing your favorite website or your favorite applications is nigh impossible.
Describing the offline application
The most important advantage of what we deem offline applications is the notion of being able to collaborate offline and synchronize later. Applications that function seamlessly offline make use of Service Workers, a technology that did not exist during the first stages of the evolution of the web. As applications get increasingly complicated, a means to interact with servers when connectivity is transient is essential. For instance, some blog websites fetch data in the background and store them locally so you can view said content without access to the internet.
Consider the case of Twitter, for instance. Twitter works largely seamlessly offline by fetching data in the background while a connection is absent. As Kevin states on our recent Tag1 Team Talks episode, you can tweet endlessly on your device even while offline, and those offline tweets are published and synced to the server as soon as you restore your internet connection. Kevin argues that this is the most important motivator for offline applications
Defining offline-enabled
Often, applications are competitively positioned as being offline-first. Offline applications inherently dot a spectrum from offline-enabled applications on the one end to offline-only applications on the other. Offline applications are solely a question of the degree to which they enable progressive enhancement in an offline environment. In the view of our panelists on our recent Tag1 Team Talks, we define offline-enabled as specifically referring to an application having portions that function offline.
For instance, many websites on the internet display a different website whenever the accessing user is offline, frequently displaying a message such as: “Sorry, we’re offline right now so we can’t provide our normal services at the moment. Please check back later.” This sort of “maintenance mode” (to borrow from Drupal parlance) offers limited functionality, whereas other applications sometimes handle the offline case more gracefully.
Consider the case of Twitter, for instance, When a user opens the Twitter website and loses connectivity moments later, when that user posts a tweet, they will still be able to publish their post successfully. This is because that offline tweet is stored in a local database that is persisted while an internet connection is unavailable and issues the update to a central server once connectivity is restored. Of course, admittedly, the full feature set of the Twitter application isn’t available offline with all the tweets that the user has ever posted, but this limited functionality offers at least the ability to view some tweets offline, which is a crucial feature that Twitter provides in its mobile application experience.
Defining offline-first
On the other hand, defining an offline-first application requires a higher threshold when it comes to expectations of the application in question. Here, we define an offline-first application as being one that works both offline and online seamlessly from end to end, throughout all functionality that the application normally provides in a connected environment.
Consider, for instance, the example of Google Docs’ native offline plugin. Google Chrome has a feature that allows users to employ Google Docs in an entirely offline fashion. This functionality synchronizes all changes made by the user to documents to the platform. Implementing this approach with a simple blog is straightforward, because blogs tend to be relatively basic websites with uncomplicated rendering processes. A background job, in the case of an offline blog, can check to see if a visitor has an internet connection and serve the most recent content. If the user is disconnected from the internet, it will save the content stored in the local database to your browser for your convenience.
Defining offline-only
During our Tag1 Team Talks episode, we also traveled to the other extreme of the spectrum to discuss offline-only applications. There are applications commonly available that only function offline, and these are often designed with the specific purpose of helping users refrain from distractions. Commonly called productivity applications, offline-only applications aid efficiency in tasks, but whether offline-only applications truly aid productivity is a debate for another time.
How to build offline web applications
In short, offline web applications are not only becoming commonplace; they are also increasingly mission-critical for a wide variety of enterprise organizations. But how exactly can developers build offline applications for the web? There are two technologies that we cover extensively in this blog series that serve precisely that purpose: Service Workers and IndexedDB.
IndexedDB is a technology that enables local databases in the browser. These local databases can be used to store any conceivable data, for instance—and of course very commonly—the content of a website. Meanwhile, Service Workers are compelling from the standpoint of offline applications because they sit in the background of your website while it is running and intercept all requests that are issued from the website. Web browsers will initiate a single process for each website and intercept all requests for each respective website.
With Service Workers running in the background, you can verify that internet access is present and retrieve the latest state of your website by fetching all of the dependencies and Cascading Style Sheets (CSS) files. Once the dependencies are available locally on the browser, you can store all of this information in the offline database powered by IndexedDB and then serve the website with all of this data, fully offline. Better still, the website will still function even without Service Workers. But if Service Workers are supported by the browser, they will intercept requests and serve you website content while offline.
If you configure Service Workers correctly, Kevin attests during our recent Tag1 Team Talks episode on offline applications, you can also enable your web application to perform much more efficiently. After all, instead of always relying on network requests, which are inherently difficult to depend on, you can always serve what is available in the IndexedDB database first and update that local database as needed. In fact, Kevin uses precisely this approach to power Yjs.dev, the website for the Yjs community, which is a cache-first site that always fetches the local state in the background. The website loads very quickly because it always serves content from the offline database first.
Conclusion
As you can see, one of the most important use cases for web applications comes, ironically, from the lack of access to the web itself. After all, offline web applications are of critical importance when it comes to supporting offline use cases for users who have intermittent or nonexistent connectivity. However, thanks to emerging web technologies like Yjs, an open-source real-time collaboration framework, and IndexedDB, a local database in browsers that enables synchronization and caching of offline content, any developer can architect an offline application with relative ease, especially with the added support that Service Workers provide.
In this blog post, we covered some of the motivations that drive developers toward implementing offline applications and some of the ways we define offline applications in general. We established, first and foremost, that there is a spectrum of offline applications depending on the requirements presented by the application in question. This encompasses everything from offline-enabled applications that only facilitate some functionality offline to offline-first applications that endeavor to offer all features offline. On the extreme end of the spectrum lie offline-only applications, which are often productivity aids and specifically only function offline. In the next installment in this blog series, we continue our discussion of how IndexedDB and Service Workers enable the implementation of robust offline applications.
Special thanks to Fabian Franz, Kevin Jahns, and Michael Meyers for their feedback during the writing process.
For more Yjs content, see Yjs - Add real-time collaboration to any application.
Part 1| Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7
Photo by Markus Winkler on Unsplash