 is using the term offline after having a talk about desktop Ember apps may be a little misleading. When I'm speaking of offline, I'm talking about lack of network connectivity. And we're going to talk about how we can take our Ember apps and work with them offline. And I'd like to start with telling you a story on how I got started building offline web apps. And it actually started with a medical condition. This medical condition is called hydrocephalus. And this is water on the brain. So basically, infants get this where the water builds and there's no way to relieve the pressure. It's deadly if it's not treated. But with treatment, you can live a normal life. The little boy here in green, he was treated and was a fine student living a normal life. So I was introduced to this because I worked for an organization called Cure International. And we're a nonprofit. We work in 30 countries. And we operate hospitals and programs in the developing world. And we treat conditions like hydrocephalus, clubfoot, cleft palate. And so back in 2012, I was presented with a unique problem. There was a researcher over at Harvard Medical who wanted to be able to do some research on these hydrocephalus cases, be able to do some quality assurance to see if the methodologies being used were really effective. And the problem was, we needed to collect this data in locations throughout Africa where internet connectivity was iffy at best and sometimes expensive. So we needed something that could work offline. And so I took the time to learn how to build an offline app. Now, this was back in 2013. And so application cache was just kind of coming into fruition. And offline storage was kind of a new thing. But we successfully deployed in 2013. And to me, it proved that offline web apps could work well in the developing world where internet connectivity isn't guaranteed. Now, this was a solution for a specialty program we had. But we actually have a network of hospitals. And it got me thinking, OK, so if we could do offline web apps for one program, why can't we do it for all our hospitals? So the current methodology of if you're going to a mobile clinic, you'd have to do something like we see in this picture here, where all the medical records get loaded into these bins, and then the bins get shipped off to a clinic in rural Uganda where patients can be seen. And as a developer, I look at that and think, why can't I just load that onto a laptop? Why can't I just build something that will take that along? So I thought that this is a solvable problem. And then I thought more, too, about the fact of, well, at a hospital, there's more than just medical records. Hospitals need to be able to take care of things like inventory. And maybe to help pay the bills, you might have private patients. So maybe you need to do something with billing. So at the beginning of 2015, I started to work on this project called Hospital Run. Hospital Run is a hospital information system for charitable hospitals in the developing world. And it's built on Ember. It's built for offline and online use. It's an open source project. And one of the things we really wanted to be cognizant of was usability. So I don't know if any of you have any experience in the medical field. But even if you talk to people working in US hospitals, a lot of people are frustrated with the software they have to work with. It's a pain in the butt. It doesn't always do what you want to. So we wanted to create something that was simple, but also was approachable. So that's kind of a little bit of the background of Hospital Run. I'll talk a little bit more about it as I go on. But I just kind of wanted to introduce some of the context of what got me building offline apps. So at this point, you may be thinking, OK, offline apps, Africa, bad network connectivity, that sounds great. That's a good, feel good story. But I'm a developer here in the States. My clients have great bandwidth. Why should I care about offline apps? Well, here's why. The internet is being attacked by sharks, guys. Did you know this? I don't want to be some fanatic offline, but the Google tells me this. So OK, so seriously, this actually is a real article. And I think it's more link-bait than anything else. But I think it brings up a point. We face internet outages sometimes daily. And we don't even think about it. Maybe you're in the subway. Maybe you're at a conference. And there's not Wi-Fi everywhere. Or maybe you're somewhere where the cell towers just aren't working. And the thing is, we tend to treat offline or think about it as just kind of something we deal with. Because it's usually temporary if we have to deal with it at all. And so we think, well, it's not that big of a problem. And maybe we think, too, it's too hard of a problem to solve. And I'm here to tell you it's an easy problem to solve. And we'll get into that in a minute. Another reason you might want to care about offline is that there are performance gains that can be had by offline apps. If your data is local versus on a server, access is a lot quicker. There's another reason. And that's with a properly crafted offline app, server downtime becomes completely irrelevant. I love this tweet here where this guy is thinking about me saying, well, I need to reboot my database server. What about my users? Well, because this app was built for offline, he doesn't have to care about that. He can reboot a server. There could be a denial of service attack on a server. He doesn't care. So that's something to keep in mind. Another reason, or another thing to think about is, does your app really need a back end? Could you run your app without a back end? Let's say you just had a simple to do app. Well, most of that data is local to that user. Sure, you might use online access for something like backup. But there's actually room for these apps that just live completely offline. So earlier Estelle showed us how we could build desktop apps. Some of the things I'm going to talk about today could be put into practice in a desktop app using the same approaches for an offline app. So hopefully by now you can kind of see why offline is important, or at least maybe why you should think about it. And as we think about offline app development, there's an approach that we really can take. And it's called offline first. And I was thinking about who really knows about offline first? And I thought about the first offline animals and its dinosaurs and womp, womp, womp. Yeah, I know, I know. But OK, here's the point. You want to treat offline as the baseline for your app. Think about that as like your minimal viable condition for running your app. If your app can live offline, it can live anywhere. So we kind of start as that as our baseline. And then we build up from there. We use internet connectivity, online connectivity as a luxury. We use it when we have it. So there's a site offlinefirst.org. And they've kind of really started this conversation about offline first apps. And they have this great quote, I think, where it's talking about not just having this desktop approach where we think, OK, we always have a connection. We always have that watered land connection. And I think there's one part of this quote that's really important. And it's this, stop treating offline as an error condition. And if there's anything you take away from this talk, I hope you at least consider this. Really, we don't have an excuse as developers to do so. So yeah, just stop. So how do we build for offline first? So I really think, and I don't know why, but this seems to resonate with me, is we need to develop a survivor mentality. So maybe you guys heard of this movie Unbroken where this guy, Louis Zamperini, in 1943, he was part of a crew of 11 men who crashed in the Pacific Ocean. Louis and one of his crewmates survived for 47 days at sea, living on captured rainwater and fish that they caught. And they survived because they collected what they needed when it was available. Same thing with offline. We need to use connectivity when we have it so that we can work offline. So let's take a look at how we can do that. So the first thing we need for an offline web app is a way to store our app offline. And the way we can do this, or one of the ways we can do this, is by using application cache. Now maybe you guys have heard of application cache. Maybe you've even heard bad things about application cache. But the funny thing is, for an Ember app, it actually works really well. So to use application cache, you create a manifest file. And it lists all your resources that you need for your app to work offline. So think of your JS, your CSS, any images, that kind of thing. And application cache, the resources you declare in there are always pulled out of the cache, whether you're online or offline. So you have to keep that in mind. And you have to keep track of a version number so that when your app updates, the cache is also updated. Now fortunately, in Ember, this is dead stupid simple. So if you're doing an Ember CLI app, all you need to do is install Broccoli Manifest. There is a small bit of boilerplate that has to go in your index HTML. But once we have that in place, the app just works offline. Now when I say it just works offline, that doesn't mean that there aren't things that you need to do, but our app structure. And so I'd like to show just a quick demo here of how that works. All right, so let's just say we have our app running here on localhost 4200. It's our fun to-do list. Nothing exciting, but it'll prove a point. OK, so if I come over here and I kill my server and then come back here, yeah, my app doesn't work. And this is just a plain vanilla Ember app. But if I come over here and run this is the same app. The only difference is Broccoli Manifest is installed. So let me give it a second here. Let's see, make sure our app is up. OK, app's up. We're going to kill our app here, and it works. So there's a very simple thing you can do. Now the caveat here is this app, none of the data is coming from a server. It's all local, so there wasn't any need to fetch that data. So which actually brings me back to my next point, which is, what do we do about storage? So let's say I have a to-do list. That data needs to come from somewhere. And in the browser today, we have basically three mechanisms for offline storage. There's local storage. It's also called web storage. And this is a key value pair, kind of like cookies. It's a synchronous API, so it's really meant for small amounts of data. I wouldn't use it for a large data set, but if you just need to store little bits. Then the next option is web SQL. Now web SQL is SQL in your database. This is actually a deprecated spec, but it's still available in most browsers except for Firefox and IE. And then the last option is index DB. This is, I guess, the most recent offline storage available. It's a no SQL database, so it's like this object store that uses key value pairs. So when we talk about offline data persistence in Ember, if you're using Ember data, there's a couple adapters that you can use. Local storage uses local storage. There's another one called local forage, which is a wrapper that Mozilla built that uses either index DB or web SQL. And then the last one I'm going to talk about is pouch DB. And it uses index DB or web SQL behind the scenes, but it's actually an implementation of couch DB, which is a no SQL database, stores everything in documents and uses keys to reference them. And for hospital run, this is what we chose to use for our project. And the reason we chose to use it is mainly because it synchronizes nicely with couch DB. So in the browser, we have pouch DB running. And then in the server, we have couch running. And so what we can do is we can synchronize between the two. And then everyone who's looking at the patient records, they get the most updated records because synchronization is happening. And we kind of get that for free with couch and pouch. Now, we've learned a couple of things in using pouch in our Ember app. Search can be tricky because you're dealing with a no SQL database. So you can't just do like select star from blah where x is like foo. But there's stuff you knew with like map reduce, as well as there's a couple of plugins that are useful. Another thing we realized is you need to think about how much data you're going to be storing on the client. Our initial implementation, we were just sinking down the whole database. And we realized, wait a minute, there's some users who really only need patient data. They don't care about the inventory system. So you need to think about how you can partition that data so that you only bring down what you need. And then also you need to consider infrastructure. We found that we had some people using older machines. And we were sinking too often for basically their browsers were getting hung up because we were sinking too often. So we had to adjust that. So speaking of synchronization, anytime you work with offline data, synchronization to online, it's actually a really hard problem. And I know because when I built the hydrocephalus system, I did it all by hand. And it's complicated. It's kind of like building Git from scratch. I mean, maybe not completely, but you get the concept. So when you think about synchronization, the first thing I would ask is, like, do you really need it? If your data is per user, maybe you can just get away with sinking just that user's data. And so you don't have two people changing the same data set. And actually, we found that Couch and Pouch do a great job of synchronizing, even if two parties change. But even with good synchronization, you still have to handle conflicts. And actually, Ember makes this really easy. So there's different strategies for handling conflicts when synchronizing data. But a pattern that works a lot of the time is to let the last change in win. So if user A changes the first name yesterday and I change the name today, I should win. Now, if we did that at a record level, we could end up overwriting non-conflicting changes. But in Ember data, we actually have access to this changed attributes on a record. So I can tell on each save what fields were changed. And then what we do is we just simply keep track. We have another field that keeps track of time stamps of what fields were changed when. So if we get two different records in, two different copies of the same record in, we can compare, OK, you changed it yesterday. I changed it today. I win. And we just do that on server side to resolve this conflicts. OK, so we've looked at how to store app structure offline using application cache. We've looked at how to store our data. Our data. Well, let me tell you about data. How to store our data with browser storage and hopefully giving you a little picture of what it means to deal with offline online sync. But there's something new that we can do online. And that's service workers. So service workers take what's automated by application cache and puts the controller back in your hands. So if you remember from what you've seen of application cache, it's very declarative. You say these resources are available offline. This stuff is only available via network. It's all very declarative, but you don't have much control over it. You can kind of think of service workers as giving you a proxy server in the browser. You have control over network requests. So you can say, OK, pull it from the cache or pull it from the network or come up with a custom response depending on whatever you decide. Today is Tuesday, so you get bad data. I don't know. So anyway, you can do more with service workers than you could do with application cache. So one example, with traditional application cache, you have to store your data offline if you want to have access to it. With service workers, you could actually cache your API calls so that if you're offline, you just respond back with the cache version of the API call. You don't have to change your code to say, oh, well, I'm offline, so go fetch it from the database as opposed to fetching it from some online resource. You're calling the same data point. Now, obviously, if you start writing stuff, then if you need to write stuff offline, then you need storage. But this is some of what service workers gives us. So how do they fit into Ember? Well, I thought it was funny. The other day, Tom Dale tweeted that he wants to make service worker something Ember apps largely get for free. And I'm like, all right, cool. That's awesome. If we can do that, that sounds really good. So I had a thought. So there's this thing called Broccoli Manifest. Maybe there's a broccoli service worker. But I ran into a problem. Broccoli and service and worker are really common terms. And I really wasn't looking how to make broccoli. So I dug a little deeper. There wasn't anything in NPM. So I decided to make it. So you can now do service workers in Ember. This is a very new thing. And right now, it pretty much works like the broccoli manifest does. But eventually, hopefully, we can do things like cache API calls and really take advantage of some of the things that service workers give us. So I can give a quick demo here, I think. So this is another app, same app, actually. But now we are running. Let's just refresh and make sure I got the right one. So now we're running with service worker. And we should be able to look at the source just to make sure. OK, so really, really big. So really, at the bottom, it's just really this piece here where we're pulling a service worker that's been generated. And so let's go kill our app again. And it's up. So service workers, you can use them today. One thing I forgot to mention, they are only in Chrome without any special things. You can use them in Firefox if you use the nightly build. I think Firefox is going to have it available by the fall. Oh, and Opera as well has it. So yeah, that's service workers. That's it. So thanks a lot. Questions for John? Questions about offline embers, service workers? So what is your opinion about service workers and ember as a first class citizen? And what type of, is that something that you think that your library can be incorporated, or is it something that have to be a completely separate effort? So that's a great question. Because one of the nice things about service workers is it gives the control back to developers for dealing with offline resources. So I think the question becomes, how much control do you want as a developer? And how much do you want to have auto-generated for you? There are a couple of patterns when you start talking about offline development where I think those things could be boilerplate. So I think whether it's a broccoli service worker or something built into the framework itself, I think those use cases could be kind of automatic. And then if you wanted to deep dive in, I think it could be done kind of on your own project. So it makes sense. Any more? Maybe it's a little loaded. But how do you deal with privacy of medical records? A general approach, because I know it's a big question. Yeah. So one of the benefits in dealing with the developing world is we don't have a lot of the legal ramifications. But at the same time, patient integrity or patient privacy is something that we do care about. I mean, the one simple thing is just running everything over SSL. And then beyond that, yeah, it's a thorny issue.