Talks
Building an Offline Experience with a Rails-powered PWA
Summarized using AI

Building an Offline Experience with a Rails-powered PWA

by Alicia Rojas

In the video titled "Building an offline experience with a Rails-powered PWA," Alicia Rojas, a software engineer at Telos Labs, discusses how to convert a traditional Rails application into a Progressive Web Application (PWA) that supports offline functionalities. The presentation begins with a thorough explanation of what a PWA is: a web application that adopts modern APIs to enhance user experience with features akin to native apps, such as offline support and native-like installation capabilities.

Key points covered in the talk include:
- Introduction to PWAs: Rojas emphasizes the advantages of PWAs, such as improved performance, offline capabilities, and better SEO, combining features from both web and native applications.
- Case Study: The need for a PWA arose from a request by the Chilean government for a tool aimed at farmers and agricultural technicians. The application’s design focused on usability in regions with unreliable internet access.
- PWA Setup: To transform a Rails application into a PWA, Rojas discusses the necessity of adding a service worker, which runs in the background to manage caching and offline access, and a manifest file that informs the browser about the app's presentation and behavior.
- CRUD Operations: The talk delves into how to implement create, read, update, and delete (CRUD) functionalities using Hotwire and IndexedDB, enabling the app to store data locally when offline and synchronize once internet access is restored.
- Challenges with IndexedDB: Rojas highlights the complexity of using IndexedDB due to its reliance on asynchronous JavaScript but explains how the decision to use it was made for its ability to handle larger data types in a user-friendly manner.
- User Interface Enhancements: Techniques for guiding user interactions with offline data and implementing functions like toggling online/offline preferences were discussed. The importance of validations and keeping both backend and frontend in sync was also emphasized.
- Compatibility Considerations: Rojas advises on testing features against various browsers to avoid compatibility issues, especially focusing on service workers and APIs across different platforms.

In conclusion, Rojas articulates the considerable benefits that PWAs can offer, such as accessibility and engagement with users in areas where internet connectivity is limited, providing a near-native experience without heavy reliance on JavaScript frameworks. Her documentation throughout the process aims to ensure that applications remain functional even when offline, enhancing the overall user experience. Rojas encourages audience members to reach out with any questions about PWAs, making herself available for further discussion.

00:00:15.160 Hey everyone, thank you for making it to this talk. I hope today you learn something interesting and that you leave here ready to create your first Progressive Web Application (PWA).
00:00:20.920 I'm Alicia Rojas, a software engineer at Telos Labs. I recently completed my second year there in August. Additionally, I am a music composer and a natural resources engineer. I am passionate about technology and sustainability, which is the focus of this application. I was born in Chile, but I'm currently based in Mexico City.
00:00:33.239 Telos Labs is a software consultancy founded in 2017 by Horacio Trino, a Mexican entrepreneur. Our mission is to tangibly enhance society through clarity of thought, creativity, and technology. We are committed to developing products that deliver a significant impact, and we aim to build purposeful products. In this talk, I will cover several topics: first, we will discuss what a PWA is and why you should convert your app into one. Then, I will introduce a case study that highlights the challenges that led to the creation of this Progressive Web Application. I will also explain how to set up the main components to create a PWA starting from a Rails application. Finally, we will dive into the more substantial part of the app which involves performing CRUD actions - create, read, update, and delete - using Hotwire and IndexedDB.
00:01:17.720 So, what is a PWA, and why should you consider turning your app into one? PWA stands for Progressive Web Application. In formal terms, these applications are web applications that are gradually enhanced with modern APIs to deliver improved capabilities. PWAs provide benefits such as better page performance, push notifications, offline support, and they are installable, allowing them to offer a native app-like experience without sacrificing the benefits of the web.
00:01:35.359 PWAs effectively combine the best features of both web and native applications. Web apps excel in reach since they are platform-independent and can be indexed by search engines, making them advantageous for SEO. They are also budget-friendly and accessible through any web browser without the need for installation. On the other hand, native apps take advantage of platform specificity to offer more complex functionalities. PWAs fall somewhere in between with a slightly lower capacity compared to native apps but retain all the positive aspects of web apps while being less costly to develop.
00:02:09.240 The impetus for this application stemmed from a request by the Chilean government, specifically an agency related to agriculture. They needed a tool for farmers and agricultural technicians to conduct on-field sustainability assessments on their farms. The challenge was to create an app that could perform these CRUD actions in regions where internet connectivity can be unreliable or entirely absent. The app needed to be user-friendly and easy to share since we were targeting users who may not be particularly tech-savvy, such as farmers in rural areas, and it should work on mobile devices.
00:02:43.200 Initially, we considered developing a native app, but given our limited time frame and budget, we decided to build a web application using our favorite framework, Rails. We gradually introduced PWA enhancements to provide offline support. The goal was to create an application in which farm technicians could complete a lengthy questionnaire, which includes various questions and map features, while working in areas where reliable internet access is not guaranteed.
00:03:05.440 To set up the main pieces for a Rails application to become a PWA, there are two critical components needed: the service worker and the manifest. The service worker is a small application that runs parallel to your Rails app and intercepts network requests, providing caching of assets and background synchronization capabilities, among other features. Service workers act as proxies between your web server and the browser, aiming to enhance reliability by offering offline access and other conveniences. It is important to ensure that the service worker is positioned at the root or global scope so it can effectively control all routes.
00:04:05.840 The second component, the manifest, specifies to the browser how the PWA should behave, including how it displays within the operating system of the user's device. It is crucial for ensuring that the application looks and feels like a native app. It defines elements such as the splash screen appearance and how the home screen icon should look. The manifest file is typically referenced as manifest.json. To incorporate these elements into your application, I explored various approaches, ultimately deciding on the MVC pattern, inspired by a blog post from Mike Rogers several years ago.
00:04:51.200 The initial step is to create a service worker controller where you will define the actions for the service worker and the manifest. Next, you need to add routes for both actions and treat these files as view templates within your application. You will then create a companion JavaScript file to connect these pieces. The service worker operates independently, while the JavaScript file serves as the bridge between your app and the service worker. By adding functions to your service worker, you can ensure they manage authentication problems when necessary.
00:05:28.680 Now let’s dive into performing CRUD operations using Hotwire and IndexedDB. The first step is creating records while offline and later synchronizing them once the connection is available. IndexedDB is a JavaScript API that provides a way to manage a database of JSON objects right in the browser. During the development process, I explored different storage mechanisms, such as session storage and cookies, but ultimately chose IndexedDB for its ability to persist data across sessions and tabs. It is capable of storing larger, more complex data types, like files and images, and it allows for searching and storing larger data amounts compared to the alternatives.
00:06:29.440 Using IndexedDB does come with its challenges—essentially relying heavily on promises—so it’s beneficial to have at least a basic understanding of asynchronous JavaScript. If you find it tricky, there are libraries available that provide a more developer-friendly API for working with IndexedDB. Now, let’s examine how this functions in practice. When a client attempts to create a record and they are offline, the request to the web server will fail. This is where IndexedDB comes into play, allowing you to store the record locally in the browser until a connection is restored. Once back online, you can synchronize this data with the server.
00:07:33.320 To implement this functionality, I utilized Stimulus to check the network status. In my experience, a reliable method was to fetch a small image, ensuring it was not cached by the service worker. The goal here is to verify that you have internet access and that you are not just connected to a network with no actual service. As you submit forms or create records, check the network status. If the connection is down, prevent the default behavior from initiating the AJAX request and store the record in IndexedDB instead.
00:08:05.040 I discovered that these actions are commonly used across different controllers, so I created a mixin to enable code reuse across my Stimulus controllers. This setup involves checking for network connectivity and ensuring that before the submission of any data, valid form information is available. If the conditions aren’t met, you will save the record in IndexedDB for later synchronization, similar to how records are handled in the local storage.
00:09:05.600 The syncing operation can be initiated with a button in the user interface. When clicked, the button calls a Stimulus controller which verifies network connectivity. Only when confirmed connected will it allow synchronization to take place. This process sorts through records stored within IndexedDB and creates requests to your server to upload each record. During this phase, you can also handle potential errors and mark records as synchronized based on the outcome of the request.
00:09:57.360 After posting records, it is important to remove them from IndexedDB if you choose to do so, although leaving them there is also an option. This decision depends largely on the requirements of your application. Consequently, your users will be interacting with data that might not have been immediately visible until the synchronization process occurs. The goal is to provide updates through user actions while keeping them informed about the status of their records and actions regarding offline functionality.
00:10:58.920 Next, to facilitate user interactions with offline data, I adopted a template approach which uses template tags to hold discrete pieces of content that can be revealed upon user actions or conditions within the application. This is particularly useful for guiding the application’s behavior when users are online. Leveraging service workers, you can cache the templates as well as accompanying JavaScript for rendering while ensuring new content is available when required. The Mustache.js library proxies this rendering process, which populates and updates the UI with the data fetched from IndexedDB dynamically.
00:12:44.960 Some additional features I found useful included an option for users to toggle their offline/online preferences, which provides control in situations where the user may have unreliable network connectivity or may prefer not to utilize mobile data. The interface can effectively indicate to users when they are online or offline. Implementing the synchronization button or integrating background sync via the service worker could also enhance the user experience. However, users should have some level of control over when these actions occur to prevent unwanted background processes.
00:13:51.680 For updates, you would follow a similar approach by creating a template version of the form within your views. This template could be dynamically loaded, enabling users to edit existing records within IndexedDB. The underlying logic ensures that if the record already exists, updates will reflect appropriately without creating duplicates. The mixin from earlier can be applied here to maintain accuracy and efficiency when submitting records and updating IndexedDB.
00:14:47.680 The power of Hotwire and Stimulus frameworks allows you to build an effective PWA without the need for excess JavaScript frameworks. This integration streamlines the process of enhancing backend applications with offline capabilities through existing features. Overall, incorporating features and leverage of these frameworks enables you to empower users more efficiently, maintain engagement, and implement the application’s functionality seamlessly.
00:15:25.600 The importance of validations cannot be overstated. Ensuring the integrity of each record submitted within IndexedDB must match the backend requirements. Mismatch can lead to unnecessary validation issues when syncing later. Consequently, stay mindful of maintaining consistency between frontend validations and backend mechanisms. You want to have a reliable experience without validation conflicts that could disrupt functionality.
00:16:13.680 Moreover, understanding your user base and their browsers is crucial when implementing features for your PWA. There are various resources available, such as caniuse.com, which detail the features supported by different browsers, particularly regarding service workers and background sync APIs. Certain features may not work as expected across all platforms, especially iOS versions of Safari, which may cause compatibility issues for users. By keeping these factors in mind, you can better strategize and implement the necessary features.
00:17:31.440 In conclusion, PWA features can significantly enhance the usability and accessibility of your application across varied audiences, including those in regions with unreliable internet connectivity. Feature-rich applications allow you to engage with users who may otherwise be overlooked due to their offline circumstances. Utilizing frameworks like Stimulus enables the creation of almost native-like experiences without overwhelming amounts of JavaScript.
00:18:21.280 I've documented much of this process within a series of blog posts. The discussion encompassed how to cache assets and provide proper offline fallbacks to improve the overall user experience. Ensuring users do not encounter obstacles—like being greeted by the dinosaur game while offline—is a priority, and transitions can help mitigate these occurrences.
00:19:03.200 If you have any questions or would like to discuss Progressive Web Apps further, please don’t hesitate to reach out to me on any of the platforms. Thank you for your attention. If there are any questions, I have time to answer them.
00:19:26.000 Thanks.
Explore all talks recorded at Rails World 2023
+20