字幕列表 影片播放 列印英文字幕 JavaScript: Off the Grid Sophia Shoemaker KATIE: Hello. Welcome back to the SitePen track. We have Sophia Shoemaker. And you don't want to live in San Francisco with her because her grandfather was born right before the 1906 earthquake and she was in the 1989 earthquake. So, earthquakes follow her family around. If you live in San Francisco, you might want to move. Or maybe get her to move. Anyways. I am super excited about Sophia's talk because she's going to be telling us a story about the real world where some of like the hot topics, progressive web apps, what everybody is talking about, where the rubber hits and the road and these really cool technologies that we geek out about can actually bring a positive impact to communities that we want to serve. So, I think this is gonna be a really meaningful and awesome talk and I hope you're excited for it. So, let's give it up for Sophia. [ Applause ] SOPHIA: Come on, computer. Okay. I think we're good. There we go. Okay. Okay. Hi, everybody. I'm Sophia Shoemaker. I work as a freelance developer of shoes. Just kidding. [ Laughter ] I'm actually a web developer, a freelance web developer. But I really did make she's shoes. They're little baby shoes that I made. One of the companies that I work for is called Fullstack.IO. We write tons of tech books. We have a book about Angular, a couple books about React. We have a Vue book. The latest book that we're hoping to publish in the next couple of months is called JavaScript Algorithms and Data Structures. If you would like a beta version of the book, you can come find me after my talk. Yeah. Okay. So, before I get started with like the technical side of my talk, I want to give a little bit of background. So, for various political, social and economic reasons, there are large numbers of orphanages in many regions of Africa. For example, in Uganda there were 2500 orphanages in 1992. In 2013, there's 50,000. So, governments have begun to crack down on these orphanages because in a lot of cases they're not actually helping these children. And in a lot of cases there's abuse happening so they shut down and suspended or banned international adoptions. And for the past couple of years I have been working on a project for a nonprofit organization called Kaeme. They are working with orphanages and the government in Ghana to get these children out of these orphanages and back with their families. In a lot of cases these children often have family members alive. Sometimes their parents are still alive. So, they try to get them back with people that can take care of them or get them adopted. And the application that I built allows them to collect data and generate reports based on the data. So, I actually inherited this project from a group of grad students at Santa Clara University. The first version of the application was built with PHP. Anybody do PHP out here? [ Applause ] Which is great. PHP is great. But it needed a little bit of reworking to get it in a better shape so I re architected it to use Laravel. The Laravel framework. Which was fine. It totally worked great. But the team as the team started to use it more and more, it was getting pretty frustrating for them because their Internet connection in Ghana is limited. So, every page load required a round trip to the server which when your Internet is slow is not a great experience. So, in addition to speeding up the application, Kaeme also wanted the ability to use the application offline so that when they went out to the orphanages where there was no Internet, they wanted to be able to enter the data into the application directly rather than filling out a paper form and taking the paper form back to the office where there was an Internet connection and there's the chance of data not getting transferred properly or missing data. So, in re architecting this a second time, I opted to leave the database structure alone because the database structure was fine. So, it's I used a MySQL database and left that alone and focused on the backend code and the frontend code. So, for the backend, I opted to use AWS Lambda. And I used Lambda for two reasons. One, I am not a DevOps expert. And Lambda makes it really, really easy to write server side code without having to maintain a server. And since I was the only person working on this application, not using my headspace to maintain a server was really valuable. And then the other reason was switching from an EC2 instance that was running PHP to AWS Lambda significantly reduced the costs on AWS. So, right now Kaeme is essentially paying for the database because Lambda is so cheap. And then finally, I used React for the frontend because I am a React fan girl. And I also needed a single page application. Like I mentioned earlier, making a round trip to the server every time a page needed to get loaded was getting frustrating. And so, making a single page application was a really great way to reduce the amount of data and pages that were getting loaded or the amount of times that I needed to make get stuff from the server. So, okay. So, what is a progressive web app? I'm sure a lot of you are familiar with this term. But I just to want run through a couple of like features of a progressive web app because this is relevant to what I built for Kaeme. And this isn't a comprehensive list of features. But these are the ones that are relevant to the application. So, obviously it's progressive. But what does that really mean? It means it works for every user, regardless of browser choice. Whether somebody's on a mobile phone that has a really slow connection or an awesome Macbook Pro. It works on all different types of devices. Oops. It's responsive. Which means it fits any form factor, desktop, mobile, tablet. It's connectivity independent. Which means it is enhanced with service workers which I'll get to in a minute to work offline around low quality networks. And then it's safe. It's HTTPS to ensure content is served securely. So, one of the things you can do to improve your web application is to use a tool called Lighthouse. It's from Google. And if you're not familiar with this tool, it allows you to do an audit on your web application to see where you can improve in performance, accessibility, progressive web apps, all those features that I just talked about. And it can give you some great insight into where you can improve your application. So, I tried to run Lighthouse on the PHP version of my application and the audit didn't even finish running. It stalled out. I don't know if my PHP application was just really unprogressive or I don't know what. Or maybe Lighthouse isn't meant to run on PHP apps. It just didn't work. I don't know if you can see, but the text says, as page load time increases from 1 second to 7 seconds, the probability of a mobile site visitor bouncing increases 113%. So, yeah. it just was not great. But, so, I ran it again on the new version and this is just a, you know, a screenshot of all the information you can get from Lighthouse. It's a pretty extensive report. It's a great way to just get a gut check of what how you can improve your application. Here's just another screenshot of performance. Just some various things that you can do to improve your application. And then here's another this section is specifically about progressive web app features that you can improve on. Okay. So, service workers. So, in order to make any application accessible offline, you have to make use of service workers. Service workers are JavaScript files that allow you to cache other resources such as other JavaScript files, CSS, images. Then they can then be available offline. Service workers only run over HTTPS and make use of promises. So, let's take a look at how service worker works. So, there are three stages in the life cycle of a service worker. The registration phase, the installation phase and the activation phase. To register, a service worker will need to add code like this. The honor block detects whether or not service workers are supported before trying to register it. Then the register function registers a service worker which is just a JavaScript file in our application. And then we have a then and a catch to handle what happens when the promise is either resolved or rejected. So, this is what our service worker file actually looked like. It handles the install event and caches the context. We add the install event and call the wait until method on the event. This holds the service worker in the installing phase until everything is ready is good to go. Inside the wait until sorry. Inside the wait until the cache is dot open method is called and that creates a new cache called v1 which will be v1 of the site's resources. And that can be any name that you want. It doesn't have to be v1. So, if your service worker has been previously installed and there's a new version of your worker available on refresh or page load. For example, you've updated your application. You have a new JavaScript file or new CSS or it's been edited. The new version is installed, but it's not activated. So, in this code you'll notice that it's the same install code that I showed you in the previous slide. We've renamed the cache and we have new assets to install. It's now called v2. So, the new version of your service worker is only activated when there are no other pages loaded that are still using the old service worker. And as soon as there's no more pages loaded, then the new service worker gets activated. So, if you're a React fan like me, create React app does this all for free so you don't have to write this stuff. So, when you create a new React application, there's an option to add service workers and cache assets offline. And this is an example of what your index.JS file looks like in React. So, if you switch the last line, service worker.unregister to service worker.register, that will allow you to make use of service workers. Another aspect of this project that was pretty critical, I don't know if this was obvious or not, but I needed to know when the user was online or offline. The navigator online property returns the status with true, meaning online, and false meaning offline. So, in the application I start nod notice a lot of code that looked like this. A bunch of if elses all over the place. And to make my code more maintainable, I created a function that took two callbacks as parameters. An online callback and an offline callback. So, using this function, I could customize what happens when a user is offline versus online. So, when the user is offline, how do we store data that's getting created and updated? There's a few options for storing data offline. But first I want to give a few guidelines on storing data offline. Number one, like, the limit of you have a limit of 50% of the total hard drive storage. Like, for example, if you have a 500 gigabyte hard drive, 250 gigabytes total allowed for the browser. And then there's a limit of 10 megabytes to 2 gigabytes per group. A group is an origin like Google.com. Okay. So, in researching the technologies I needed to use for this project, I found that there was a few different options out there for storing data offline. There are a lot out there. But these are the ones that I became familiar with. Familiar with for this project. One is PouchDB in connection with CouchDB. PouchDB is a library that syncs with CouchDB, a NoSQL database. It makes going offline. If you have a user that's editing data offline and a different use offline and there are merge conflicts, PouchDB allows you to gracefully handle those issues. So, the con in using this for my project was that I would have to migrate my MySQL database structure to a NoSQL format which is something I'm not familiar with. And I have been burned in the past biting off more than I can chew with refactors. I wanted to leave the database along so I opted not to use PouchDB with CouchDB. And on top of it, the application the data was really meant to be relational database. It didn't really fit the NoSQL format of things. Okay. So, another option is IndexedDB, a low level way to store significant amounts of data including files and blobs. And this is from the MDN docs. IndexedDB API is powerful but may seem too complicated for simple case. If you'd prefer a simple API, try indications such as that huge long list that make IndexedDB a little more programmer friendly. I read this and said, hm, I'm not going down the path. I'm the only developer on this project. This looks a little more complicated and I don't have seven, eight, nine, ten months to work on this. So, I opted not to. But I think if I went back and re architected the application I would go down this path of using the IndexedDB because it fit better with the data that I was saving offline. But ultimately I ended up using localStorage. So, localStorage is a property, and the stored data is saved across browser sessions. It's a key value store that has a set, get and remove item methods on it. So, only strings can be stored in localStorage. So, if you want to store anything other than a string, you have to turn your data into a string. One caveat is that while storage limits for localStorage are larger than using cookies, you can't store like gigabytes for the user unless the user allows for it for the domain. So, typically localStorage is limited to 5 10 megabytes. Here is an example of how I used localStorage in the Kaeme application. I was using JSON, user the JSON.stringify, and then I would pull them out of local storage and turn them back into JSON objects. So, in order to properly save a child's record online and offline, I used my online offline function I showed you a couple slides back and saved it via API to the database or updated the Q value in local storage. And then any time the child's record is saved offline, I set a flag in the local storage record indicating the record had an optimistic update. You can see right there. Okay. hopefully this demo goes okay. Let me go back. This is what the Kaeme application looks like. Let me get some test data here. You can seeing right here this first record here. Actually, let me go back a little bit. So, this black button right here allows me to download a particular record and save it offline. It might take a little bit of time. We'll see how long it takes. See if the Wi Fi works okay. Come on. Great. Okay. So, now it's gray, that means that the that record particular record is saved offline. Right now I'm online. so, if I go in and edit, I can just change hello, hello. And then I'll save it. And then if I go back up here. And if I go up here and then turn off Wi Fi. You can see now that the only records that are showing up are the ones that I've downloaded to my application. And so, then I'll go in here and edit this one again. Earth are not great. Okay. So, then if I go back. So, I have these two records here that are highlighted red which means that there's been data that's been saved offline. So, then if I go back online. Get connected again. And then we go back. If guy in here, it says this child has updates that were done offline. So, riff the option to upload the offline data. Or I can opt to not upload that data if I wanted to. So, yeah. Let me just go back to here. Okay. So, yeah. That's how it works. [ Applause ] Okay. So, in this process there were quite a few challenges and frustrations that came with this project. Dealing with offline applications is not an easy task. At one point the team in Ghana was having some issues with the application and I couldn't reproduce the issue on my end. It always works on your own computer, right? So, we had a Skype call with them and they were literally holding a laptop up with the, you know, the application running with the computer that was offline. Because you can't do a screen share with the computer that's offline. So, I had them opening like Chrome Dev tools and inspecting the elements and clicking inside, you know, trying to figure out what the problem was. So, like the time difference, the language barrier and the technical capabilities of the team made for some interesting challenges and required a lot of patience on both ends. And we're still working out some bugs. But in general it's a much better experience. So, this is the Kaeme team in Ghana. So, in thinking about how to build this application, I knew that I could impose a few constraints on how the offline interactions work. The Kaeme team in Ghana is very small. There's just four people working on it to gather information about the children. So, it was easier to manage how the users would be allowed to use the application. I knew that there would not be a risk of a user potentially editing a child's record online and then somebody else editing the record offline because they all work together. Obviously, if the team scaled up in any way, I would have to rethink my approach. And there would be different constraints. For example, as a number of users scaled up, maybe I would have a child worker assigned to a particular user to ensure that the data would not get overwritten or maybe I would consider using PouchDB with CouchDB so that I could handle the conflicts there. And then finally one last thing, I just wanted to share something that I have seen floating around the Internet in a few places. It's this Japanese concept of ikigai. If you happen to speak Japanese, you can come up to me later and correct my pronunciation. Everyone according to Japanese culture has one. And discovering it brings satisfaction and meaning to life. When you combine these four things, what you love doing, what the world needs, what you can get paid to do and what you are good at, you can find your sense of purpose, your Ikigai. For me, this project has been an Ikigai experience. I loved stretching my engineering skills and feeling like this project has provided more value to the world than some of the other projects that I worked on. So, I hope you can all kind oh. There's the Ikigai. It's in the center of the circle there. I hope you can use JavaScript in helpful and useful ways that go beyond the typical ways that we think of creating web applications. I hope you can all kind your Ikigai experience with JavaScript. And that's it. Thanks. [ Applause ] KATIE: Hello, wow. That was so good. How many of you feel like your current job is your Ikigai? Yeah. I can I can't see much. I don't know how many people actually raised their hands. I'm sorry. That didn't work as well as I'd hoped. Anyway. Oh, my goodness. It's gonna be a great day today, folks. I hope you're ready. So, coming up next here in the SitePen track we have Lara Schenck is going to talk about CSS algorithms which might seem like a contradiction in terms, but actually is not. So, we'll all meet up back here at 11:15. And I hope to see you then. Take care. [ Applause ]
A2 初級 JavaScript。離網 - Sophia Shoemaker - JSConf US 2019 (JavaScript: Off the Grid - Sophia Shoemaker - JSConf US 2019) 3 0 林宜悉 發佈於 2021 年 01 月 14 日 更多分享 分享 收藏 回報 影片單字