 Yn ymwneud, eriwch. Hei, rydyn ni'n gweithio, ac rydyn ni'n gweithio i'r gwaith. Rydyn ni'n gwneud Eric. Rydyn ni'n gweithio i'r gweithio i Bryton. Rydyn ni'n gweithio i'r gweithio, ac yn ddweud i'r gwaith i'r gweithio i'r gweithio i'r mobile app. In both of these, I've been using Drupal to manage a lot of the content, and i spent some time over the last year researching ways that we can improve the responsiveness and the resilience of both websites and apps when we have poor network conditions. Felly, yn ystod yn gweithio ar 207, mae'n gweithio ar 2007. Yn y bwysig, gallw'n gweithio ar y cychydig, mae'n gwneud hynny'n hynny'n gweithio ar y chyfrin o'i ddweud a'r wneud yn y gwirionedd tyst i'r moddan o'r ysgol yw'r ysgol yn y bwrdd. Ond mae'r gwirionedd yna oedd y dyfodol o'r gweithio, a nad yw'n gwirionedd yw'n gwirionedd, ac mae'n gwirionedd, ac yn 2007, mae'n gwirionedd y pwysig, Y cyfle debyg o gyflawni allan i'w mwylawni'r iember, yn en avantielau a gynnig i'r mwylawni. Mae'n dweud sy'n gwelwch chi ato fel y pwysig gyda'r unrhyw ychydig y byd. Mae'r unrhyw i'r mwylawni o'r mwylawni, erbyn yn dweud y pwysig arall, ac rwy'n gwybod i'r unrhyw gan yn ei ddechrau. A'r rwy'n gynnig i'r mwylawni i'r byd, yn ymryd i ddweud o'r hollau sydd y gallwn y gallwn diolch. Ond, ydy'r pryd y byddwn i'n credu'r cymryd yn ymryd i'r cyfyrdd, ac y byddwn i'r cymryd yn ymryd i'r cymryd yn ymryd o'r cyfryd, a phobl yn ymryd i'r cyfryd i'r cyfryd i'r cyfryd i'r cyfryd i'r cyfrydd. A dwi'n deillwch ar gyfer y cyfle i'r gallu cyfnod oedd yn gallu gwneud ar gyfer y cyfle i'r cyfle i'r cyfle i'r cyfle i'r cyffredin. Mae'r cyffredin yn ymddangos ar gyfer y cyfle i'r cyffredin sy'n gwneud ar gyfer y cyffredin sydd yma, ac yn ddweud, mae'n ddweud i'r cyffredin yn ein gwneud. Mae'n rhaid i ni'n gwneud, mae eich gwneud yn ei wneud. Mae'n ddweud i ni'n gwneud. Ie, mae'n edrych yn siŵn i ddweud ar hynny, mae'n gweithio cymaint, a'r dynnu'n dweud ar hynny. Mae'n dweud hynny, mae'n ddweud ar hynny. Byddai'n ddweud ar hynny, mae'n ddweud ar hynny. Mae'r ddweud yn ddweud, a'r ddweud a'r ddweud. Yn ynddo i gyfnodd, rydyn ni'n rydyn ni'n golygu ar y dweud, But we've already been looking at the tweets. This is actually quite a good example. If this network connection has failed the website wouldn't have appeared at all. I'd have seen the tweets, I wouldn't necessarily have any more tweets but I could at least read something. There's a lot of apps there that have been built that's purely to show the same content that we have on a website. ..y'r rhai sgolwch yn ymgyrch yma. Mae'r Confrans wedi'u meddwl. Mae'r meddwl i'r meddwl. Ond mae'n mynd i gael o'r ffordd yma sy'n bwysig o'r ardeig. Ac mae'n ffordd i heal yma, mae'n ffordd i'r meddwl i'r ddweud. Mae'n meddwl i'r meddwl i'r meddwl i'r meddwl i'r meddwl... ..a phryd yn fydda'r wneud gweld, ychydig i'r ffordd i'r meddwl... ..y'r bod yn ein bod yn gondol o'r ffordd. Mae'n dwi'n cynnwys lle iawn, ar gyfer y maelio. Mae o'r cyhoedd â'r app o ran oedd gyrddion oherwydd. Mae'r ffordd mewn gwahanol yng Nghymru. Mae ffordd mewn gwahanol ar gyfer y maelio, rwy'n ei wneud oherwydd i chi wneud yma ar gyfer o bobl yn y ddechrau. Ac mae'n ddweud i fynd i rydyniaeth, mae'n meddwl yma yn fhorfyn hŷl i arweithio diwrnig. Mae'n meddwl ein wrthgrifnol o whattym. Ie, a we have seen the same information, the same stuff that we are looking at on the screen. So the only difference is in the software, on one we are using a native API and on the other we are using a browser. So I have put together a quick demo site which is very very simple. It is a kind of site that we might have for a conference. I've got a home page, a schedule page, and a few other static pages, but there's no login here, there's no forms, nothing. It's just the most basic kind of browser site, but it's a good example for doing some simple improvements. So what I wanted to ask myself is, can we take the site, and can we make it so that whenever somebody visits it, we can ensure that they can go back later, and even if they don't have a Wi-Fi or a mobile signal, still see it. Conference Wi-Fi can be a bit hit and miss, it's good here, but not everywhere. So can we provide something that a delegate could rely on, and how far are we off being able to do that? So some of this stuff is a bit new and a bit raw. The browser support is not complete, but it's good to have a look at and see where things are going. So the technology I want to talk about mostly is the thing called the service worker. It's a relatively new API that browsers have. You consider it like a client-side proxy, which is a programmable layer between the document and the network. Probably an easier way to think of it is by having a little mini web server running on your phone that can then talk to another server, so that if that network connection is broken, you can still interact with it. We can do a number of things. Most notably, it will handle the network requests that you make from your browser to a web server, and it will go through this worker. You can also programmatically access the browser's cache in a way that the normal browser cache is quite transparent. You don't really interact with it, but we'll see later that you can do it with this. A couple of other things that they can do, which I won't have time to talk about today, is that you can send push notifications from a server to your browser using this. There's also a background sync where if you are offline and you wanted to post a comment on a blog, then we can accept the comment and then post it when you're later online. We need to set one of these things up. It's quite straightforward. When we load a page, we want to register a service worker. I've put this code in, and I've put it inside this. We're just doing a test to see if the browser supports a service worker, then let's do this. If it's an older browser, nothing happens. We're not going to penalise anyone for using an older browser. We're not going to get the same experience they had before, but we want to do this as a progressive enhancement for browsers that can do it. I register this service worker, and I pass it in the name of a script. It's SWJS, which will tell the service worker what to do. We'll come to that in a minute. I want to look at this scope parameter quickly. That's interesting, because now once this worker is up and running, any pages that we load within that scope will use the service worker for all of their requests. That includes images, fonts, things from a CDN, any kind of Ajax requests that we post or get, analytics, that kind of thing. Everything will go through this worker. The script for setting up the worker, we'll put it in, but we'll just leave it empty for now. In the moment, just by doing that, we have a service worker. It doesn't do anything, but it is there. If we have a look at this demo site, this is in Chrome. This is a Chrome developer tools. We'll open up those tools, and we can see it running, and we can inspect it, as if in the same way that we inspected the browser window, we get a list of... I've got the console, and we can see the network requests that the worker makes. The service worker runs independently of the document window. It stays there, even if we close the window down. If we close the browser down, it will go to sleep. When we come back later on and open up the browser, the worker will wake up again and start running. The moment it's not really doing anything useful, we're going to add to it so that the requests that we make get written to the service worker. These things are primarily event-driven, and what we do is we write some JavaScript code to respond to certain events if we're interested in them. There's quite a few events, but the two most interesting ones are the install events. Whenever we first set up this worker, we can put some code in here that runs. The second one is a fetch event. That means wherever we ask the worker to go and get something, we put code in here. Typically, what we'll do is, in the first one, we'll download some things that we always want, so maybe a CSS, maybe some scripts and things. Typically, in the second one, we'll put something to behave in a certain way depending on the state of the network. If we look at the second event, we can pretty much put what we want in there and what we want to end up with is giving back something that is HTML. This is a really trivial example, but it shows that we get this event object which has a request within it. We can examine that and then we'll pass back a response. If we want to make that a little bit more useful, we need to look at a couple of other APIs and come back to that. The only thing I want to talk about is something called promises. We'll do a lot of asynchronous things. Going off to load something from the network is time-consuming. Promises are widely used in a functional programming world, but they can be a little tricky to get a head around. We need a way to get back something when asking a question that hasn't yet been answered. We have this promise and it will either resolve if it was successful or it will reject if it wasn't. We handle that by supplying two functions to say, do this if it resolves or do this if it rejects. The second thing to note is this fetch API. If you've used something like jQuery to do index requests, this is a look a bit familiar, but what we're saying is don't get a response from a URL and do something if it's successful or do something else if it's not. Again, that uses the promise. Finally, there's this cache API that I mentioned, which is a little bit different from the inbuilt browser cache because we can programmatically access it. We can choose what to put in there, what to get out. We can also get out things, even if they're stale, which is kind of where that comes in really handy for showing things that are offline. We have a bit more control over what gets stored in there and what doesn't. We can inspect the cache in the browser's dev tools. We'll see that demo that we visited earlier once around it with the service that I put these. CSS files and other resources in there. So quickly, a couple of other techniques for caching data. There isn't really a great one size fits all for us to say. This is how you make content work offline. Some things are fine. Some article or a blog post, it doesn't matter if we see something that's a bit old. Other things like sports results, you don't want to see something that's half an hour old if you're looking at the football scores. So that really needs to be current. So we need to bear this stuff in mind. So we'll start with the approach that is kind of standard to what we have now. So this idea of only going to the network. That's pretty easy. This is our affectionate service worker. All we do is respond with a promise that says fetch the same request. That's not going to do anything different than your browser is doing now. But it does go through the service worker. If we want to, now we're going to improve that by saying if you can't go to the network, let's go to the cache. So we'll start off in the fetch handle by calling this fetch and giving it the same request. What we want to do next is to say if that fails, fall back to the cache. So we'll put in this function on the network error and to say if it doesn't work, look in the cache to see if the response matching that request is in there. If it is, then send it back to the client. If it's not, then we'll just fail like we did before. We'll then add another function to say that if the request did work, and we did get a response back from the server, from the network, we'll put that, we'll put a copy of the response into the cache. So we can say, well, we've got this response, I need to save it for next time. And that makes a big improvement because now we can look at that site again and we'll load it up the first time. And then we'll go and put the device into flight mode. And now when it's done that, it's put a load of things into its cache and we're in flight mode but we can carry on using the site because what's happening here is that we're looking at that fetch event. We're just going to close the browser down and come back and you'll see that it's still there. So what happened there was we looked at the fetch event and we said we tried to the network first and that failed so we went to the cache and none of the wiser they get the page and they got the page straight away. But that's really only one case of offline. We've handled this flight mode but we haven't handled this scenario where anywhere it's very up and down it can kind of come and go. We haven't handled this scenario where we've got perhaps a very faint signal and we haven't handled this scenario where it may or may not work at all. We haven't handled to serve a failure as well so the S3 outage that happened a few days ago is also to make sure it's out of line. If the user has already got some pages in their cache then they're going to be less affected by it. So this kind of waiting that we saw earlier is a slow thing. It's kind of by design because when we view a web page in the browser the operating system has to talk to an HTTP and it has to send a request out via the computer's network connection. It sends out packets of data to a router. They go across the wire to other routers and that gets again picked up by a server and reassembled into HTTP into something that can build our response. Once it's done that, all that has to come. That data has to come all the way back and only when it comes back do we get to see the page so that can be quite time consuming. But also let's have a look at what happens when something goes wrong. So those packets are being sent out and we know that it's going somewhere but nothing's coming back. We're not here, we're not being told about failure. We're just not hearing anything at all. So the only thing that the browser can do in that scenario is wait. In fact the operating system waits and then after a while it will just give up. At that point we get the time up that we see. We have to do this because HTTP is a reliable protocol. We know this. It will either work or not or fail but we'll know it either way. But actually we've got this unreliable network underneath where anything can happen. So the only way that we can provide that certainty of reliability is by implementing a time up. So what we need to learn from that is that this offline state takes time to determine but perhaps more importantly than that that the user might decide you're offline before the computer does. So the operating system timeouts are quite generous but very often you'll just see a spin-out on the bar at the top and just give up. So can we do any better than that? This is really the concept of doing offline first is that we assume that the user is offline and we try and give them something straight away for GAMP and then we really want to treat the network as an enhancement. If we can get to a point where we somehow decouple the slow network interaction from the user pressing something or doing something then we'll get a really nice user experience because people aren't pressing or clicking a link and having to wait. This is what native apps do well. So I showed you the Twitter app earlier. I fire it up, I get that. Then after a few seconds I get the bubble that says New Tweets but I could start reading the tweets before then and if the network request had failed I probably want to see that new tweets. I might have got a message saying you're offline or something but it's a lot nicer than just seeing a blank screen. So to do that we need to learn some things in advance and I mentioned earlier that we had a handler to do installed so when the service worker is first run and we can use that we need to just... it's pretty simple what I did with that demo site is just to call fetch and get certain URLs all the pages that I always wanted to have offline and just put them in the cache and that means the first time I visited that website the resources were downloaded and they were put in the cache ready to go. We also need to change the fetch handler a little bit because before we added a fallback for when the network fails but what we have to do is wait for the network to fail and then execute the fallback. If we're going to do offline first we need to flip that on its head a bit. We need to go to the cache first and if we're looking in the cache then we'll try the network. If there's nothing in either of those then we can't do anything. But what I'll do is... this is the fetch thing. I'm going to look in the cache if it's in there I'll return the cache response if it's not there I'll fetch the network and then add it to the cache. But I'm going to do one more thing whenever I show the user a cache response I need to make sure that I keep my cache up-to-date because otherwise I've given it something from the cache and they've never ever gone and get the updated one. So we put in this second network request when I get something out of the cache. This is interesting because this is an asynchronous... it's an asynchronous call but we're not going to wait for it to come back. We're going to go back straight away and give the cache the page to the user. Another thing I wanted to do is I wanted to avoid showing somebody an old page even if I'm going to later update it. I don't really want the user to see something that could be hours old. So in our fetch handler we're actually going to get two responses. We're going to get either the cached one or we're going to get the cached ones and then we're also going to get another one from this second fetch that we do. What I wanted to do was to show I wanted to compare those two responses and see if anything's changed and if it has, I want to pop up a little thing on the screen or something so that some content has changed. I can do that in the service worker. I have access to my two responses. I can compare them over byte for byte or I can compare them with some kind of header. Then I can send this message to the browser window to say that a certain URL has been changed. In my document, in the script in the document I listen out for those messages and to say this data has changed and shown a message. We'll have a look at how that might work. I'm going to carry on browsing through the site and find a particular page. I know that this page will have changed. We're going to get the cached version. I know it's changed. Once my second fetch finished, I know that it's changed and I can pop up this little message to say reload it. That's just a link to the page. If somebody clicks on that link, we'll load the page again. It will come back through the cache and be updated. This whole process of checking will happen again. The second time, it probably won't have changed, so I'll never see that message. That's really nice because as a user, I got to see the page straight away and I still have the new one. If that page hadn't changed, I'd have just seen it straight away and I'd never know that it had been updated. I'd never know that I wasn't looking at some freshly fetched content. It's the right content for people to see, but I saw it really quickly. This is closer to the experience that people have with native apps where things are just loading in the background and separated out from the pressing of the link. I don't have this sense of pressing something and having to wait. There is a Drupal module called PWA. It's called Progressive Web App. Progressive Web App is a larger marketing term that is used by people using it to describe things like offline technology, also the push notifications, and also just making websites that are essentially installable. I can add something to this site called a manifest file. It's just a JSON file that explains a little bit about what my site does and gives it an icon and a color scheme and things like that. If I was to do that on Chrome here, I would get a pop-up that says, do I want to add this site as long as it's stored on my home screen? There it sits alongside all the other native Android apps. The Drupal module that I mentioned is a first attempt to try and make a Progressive Web App out of the Drupal site. It works by essentially aspiring the pages that get out for it and making a list of resources, style sheets and things, and then trying to build this service work script for us. It works quite nicely. It doesn't work every situation, but it's quite a nice first attempt. It's a long way off being a production ready, but if you are interested in how these things work, then you're worth doing that. I've also got some resources that are particularly useful. There's quite a few videos from Google.io on this topic that are quite good. Actually, the first link has a list of all the others, and I don't know if you don't get them all down. I've also written up most of the content of this talk into a blog post, and I'll tweet that link out. Just to summarise, I think that this is a very interesting topic going forward. I think there's a lot of apps that could be websites, and I think that there's a lot of small things that we can do to improve websites as well to maybe make it less necessary to put the right app alongside it. It's very easy to add this sort of stuff incrementally, so you can start by having a service worker to cache your style sheets and just make them load a bit faster, and then maybe you could cache the home page and have a custom offline page, and then you could take it one step further and say that I could maybe have an option to cache all pages in a particular category, things like that. But we can start to add little bits and pieces, and we can start to add it for browsers that support it at the moment, which is Chrome and Firefox and Opera. So thanks for listening. Is that actually an application that you download on the server? No, because it's not a module, right? Or is it...? No. The service worker is an API that is included with browsers. So Chrome, Firefox and Opera, they all have it. You write then some JavaScript code along with your website to say, start the service worker and do this with it. See, there's nothing that the user would have to do in advance of that. But you've now achieved to have the website offline after a certain point, that there would be situations you would see why not want? Yeah, there are going to be situations where it doesn't work. Probably the most obvious way is Safari, which doesn't support this. But I would sort of say that don't hesitate to use it, even though it's not supported in every browser, because there's no real harm done to anyone that doesn't have it. They have what they had before. There's also a scenario where you might run out of cache-based things. So I think it's probably important to see this as an improvement to a website rather than saying, you're now completely ready to replace a native app. How long does the service worker itself cache for? Suppose you want to push out a bit of the service worker. How long does that mean? Okay, each time you... every page you would say this page is a service worker. I think you can replace that script with a link tag in the header now. But then what will happen is the browser will make another request for the service worker and it will compare the two. If you've got a new script, it will download that one and it will kind of keep it in the background until you close all your tabs down on that site. Once it's done that, the new service worker will replace the other one and there is another event called Update where you can run things that are currently in caches or doing whatever you want in there. Was the service worker to be inside its own scope and able to say, no, you've gone with a new one? I choose to get myself from caches instead. I don't like a new one. I think it bypassed. I don't think you can use the service worker to serve up a new one. I think there are various things in there to sort of stop you shooting yourself in the foot. There's also a hard limit on the cash expiry time of the service worker script for like 24 hours. So after which it will always get a new one because otherwise you could potentially serve up a bug in the service worker and kind of get me there on the client's site forever. Yeah, sorry. How does it have to amount to the cash being formed? How would you handle some cash limitations or would it just kind of rejects a request that you'd be trying to put into it? Yes, it might fail when you're trying to put something in or it might just throw something else out. So you've kind of got to be prepared for something that might not be in the cash. I know I sort of said, yes, we've got all this programming access to it and we can kind of depend on it. But that's a pass. We can depend on it a bit more than we otherwise could. Yeah, it will probably be a promise we'll reject. I think there was, I heard some talk about a kind of a sort of two levels of storing one which was kind of where you could really put something on there that would be quite permanent and it would also only get permission from the browser but I don't know how, I don't know how far along that is. Is there a restriction on the resources that you can store on some new stuff filling up with videos? There is, but there is a limit but it's not well defined and it's very important to use it. And there's, like browsers use heuristics to say I'm going to get rid of this stuff out of the cash first and then that one. Both of nine is don't absolutely depend on it. Yeah, yeah, yeah. Yeah, sorry. So you say with the module you can create an application with a button like installs a website like a web app. To add it to the... To add it to the, to have that and to home screen what you need is a service worker and a manifest file. The manifest is just a text file which is Jason to say this is what my application is called and it has a few other things describing it. If you... Sorry. My question was what about the cash implementation and what you do is that? Is it still 24 hours? It's not so good. What gets added to the home screen is just a shortcut. The service worker will stay there permanently and it will kind of stay there in a sort of sleeping state. You might come back to it much, much later. When you come back to it, every time you come back to it your browser will check to see if there's an update. It's a bit like saying there's an updated version of this software. Do you want to install it? It will just do it. It will install it the next time around. How would it work in something more interactive? One of the right tools is probably the form right tool. The basic mechanism of when I send a form if I click the button to say submit it makes post requests to the server that request would be routed through the service worker. You could if you wanted to write some code in there that does something. It's quite hard to do that sort of thing offline because you've got this... You've got to use something like background sync to say I've now got this content I need to send it back to the server but I might be doing that much later and then it becomes really difficult to tell the user that you've sent it. It's quite a hard problem to solve. It can do in Facebook that sort of thing I think where you write a post if you're offline it just sits in a kind of outbox type thing. Does that do that? What is the bad kind of thing the way that it kind of ultimates the people many times? What it ultimates to be made to start making requests as soon as you hit the network because it's there since then that you could be online and you'd like to be making requests if it fails but then it tries to make another request when you're back online but you don't actually know what it's doing so you try not to be going over your things without knowing it. I also have a three life concern which is why Safari is actually... OK, so the first question is can the phone start making lots of requests without me knowing about it and start eating up your data? Yes, it can I think. I think that's probably something that will maybe get addressed in the future so there might be some opt-in but at the moment it is kind of a bit unknown but there's lots of ways in which browsers can do that anyway so they can start freeloading on the pages and start loading lots of resources in them but you could easily load a background video without realising it and also that's... Sorry? Right, yeah, maybe. Does it make the request as soon as you go online would you have to specifically programme it that way to... if you're offline and then you suddenly get single? Oh, right, OK. Then it makes the request when you first... No, if you're offline and you make a request in the example I had it will try and get it from the cache it will try and get it from the network but that one might fail and it would fail in that sense it's not going to wait and then it won't actually come back online it's just going to... that promise is going to reject it's going to fail that network request So... Yeah, background sync is a bit less... it's a bit less clear at the moment there aren't really that many good examples and just the other question about Safari is right and there's actually a good website which we won't get it up but it's service worker already and when you're presenting, put your laptop in and turn the Wi-Fi off so you can get it but yes, there is that effect this is quite a good resource for seeing kind of browser support or all the different components so yeah, it's not there for Safari it is in development for Edge actually that's quite a recent development but you can see that there's things like promises they are starting to work on I call the use cache right like the whole offline thing is there any issue or anything going on to create a new platform in the heart of the box that there are other things to do with the Wi-Fi? I'm not aware of any initiatives to get into Drupal Core at the moment I think it would be something that a concrete module would add on and that PWA module is one attempt to do it it's probably written but that demo, everything up until the first bit of the demo I did with that PWA module not the little box that popped up and said this is a change so I think just kind of if there was an initiative probably it would be the first thing to say are there any things about Drupal that would make it difficult to write so and I think those things would probably get addressed by a concrete module