Architecting PhoneGap Applications
Coenraets, Christophe
Tired of Hello World? In this session, we explore best practices to build real-world PhoneGap applications. We investigate the Single Page Architecture, HTML templates, effective Touch events, performance techniques, and more. This session is a must If you plan to build a PhoneGap application that has more than a couple of screens.
 Okay. Yes. Okay. I think it's working. Good afternoon, everybody. And thank you for coming so late. I know I'm the only person now between you and the party, so I'll try to keep you awake. My name is Christophe Conrad. I work with Adobe. I'm based in Boston. I work with the PhoneGap team, and what I'd like to do with you today is to kind of take you through my experiences working with developers like you who build PhoneGap applications. So a lot of I'm going to show you a number of examples. So that's why I put my GitHub repository there. Sorry about the last name. That's the difficult part of this session. But most of the examples that you will see today are on that GitHub repository. On my blog, too, I blog a lot about PhoneGap, so you can find a lot of interesting information there as well. So what I decided to do was to try to do a top ten to keep it kind of lively. You know, top ten architectural principles. Some of them will be geeky, but a lot of them, as you will see, will be common sense. But for some reason, when we move to a new platform, sometimes we tend to forget what we learned in the previous language. And I'll try to remind you that you can actually apply some of the same principles when you build an application with PhoneGap. But before I do that, I always like to come back home with a little souvenir of my audience. So I need to know a little bit more about you. But the first thing I will do is this. I'm going to take a picture of you if that's okay. Let's see. All right. Let's do it. All right. And let's bring it back there. I think that's fine. I'll use Photoshop to add a few more people, but I think that will be fine. Which brings up a good question. What am I using here to do this presentation? What technology, what, you know, presentation technology am I using to do this? Am I using PowerPoint? Am I using Keynote? I'm using PhoneGap. Yes. So what you see here is actually a PhoneGap application. And I thought it would be useful to build it that way because then I will be able to show you stuff inside a presentation without doing the usual back and forth between my device and then the computer. So let's see if this works. Okay. So let's get started. So native applications are cool. And at Adobe, for instance, we build a lot of native applications. Like, for instance, if you use Photoshop on your device, this is not an HTML application. It's a native application. It makes a lot of sense because what we're doing in Photoshop is manipulating a crazy amount of pixels and it's very, very heavy. And native applications make total sense for that. However, we have also a lot of applications built with HTML because it makes sense when it's not crazy intensive like Photoshop, it makes sense to use an abstraction layer. And you all know that there is an abstraction layer that exists out there and that's essentially the WebStack. So HTML, JavaScript and CSS. And when you build with that, you can actually target all these different platforms. Some of them you may not be aware of. I finally found a bad developer the other day in Montreal. I was told that most of them are in Korea because it's a Samsung thing. But there are new platforms coming too. Like, for instance, the Mozilla phones with Firefox OS, Tizen, and there are, seems like every day there will be a new platform. And the nice thing about the WebStack is that you can build and deliver to all these platforms through the browser. Now, I don't know if any of you has ever tried to take index.html and submit it to the Apple App Store. They are not going to take that. So your delivery mechanism is really the browser. And that was really the initial idea behind PhoneGap. We said, okay, we love that platform so much and we are so close to being able to build apps with it that we're going to try to fill that gap if you want and to enable the development of apps. So something that you can actually deliver through the different app stores and things like that. So basically what we did initially was create a very thin, a very lightweight shell, a native shell that's simply wrapping your web app. So if you look at this, this is essentially 99% HTML, JavaScript, and CSS and 1% native. And the good news is even that native piece, we give it to you, that's essentially what PhoneGap is. It's a wrapper. But if you do that, your application may still not be interesting. And to be honest with you, Apple may still reject it. There is an item in the licensing agreement that if all your application is, is essentially a web app that you wrap, please deploy it through the browser. We are not going to take these applications. So they really want you to use the features that are available on your device. And so that's really the second component of PhoneGap. PhoneGap is a bridge. It gives you a consistent JavaScript API to all the cool features that you have on your phone, the GPS, the accelerometer, the camera, the contacts, you name it. And it's always the same JavaScript API. In other words, when you develop that application, you don't have to, you know, if iOS, then this JavaScript API, else if Android, then this JavaScript API, no, it's always the same thing. And we do the bindings if you do behind the scenes. So that's the second piece of PhoneGap. And if you know that, you know everything about PhoneGap. PhoneGap is nothing else, and that is by design. It's just a wrapper and a bridge, a wrapper for your web app. So now let's get into the real topic of this talk. Because it's a web app, a lot of people say, okay, I know how to develop web apps. We've been developing web apps for 15 years. I know how to do it. And then they get in trouble. And really what I want to do with you is to try to make sure that you don't get in trouble. So this is how people have been building web apps in the past. That's the old school architecture if you want. And you may recognize that you may have some version of that inside your company. That's a sitemap, right? And that's kind of your web app or your website. And behind each of these boxes, there is a little piece of PHP, JSP, ASP, Ruby on Rails or whatever. At the server side, that's going to generate a piece of UI, a piece of HTML that you then send back to the client and the client will render that HTML. So in other words, if I was to build, if that gets confusing, if I was to build a mobile application with that architecture, it would look something like this. So this is an employee directory application. You see that I work for an interesting company here. If I click one of these guys, it would do something similar to that. It would say, oh, okay, I need to display the details of that specific employee, Dwight. So I'm going to go ask my PHP server or ASP or whatever to give me that page. Is that good? Do you think you want to do that? And I'm saying that because I know you guys are super smart, but some people actually start this way. And then they say, hey, I can't use phone gap, it's too slow. But what happens here has nothing to do with phone gap, obviously. What happens is that you ask the server to generate your UI. And obviously, there is the network latency. There is, you know, if you're in the subway, it's going to take three seconds. On the web in a browser, people are used to wait two seconds. On the mobile app, not at all. They will totally trash your application if they have to wait half a second. So that is simply not acceptable. Okay? And the second thing that's probably not acceptable is that if you rely on the server to generate the UI, what do you lose that's expected from a mobile app? Offline, right? If you rely on a server and the server is not there, your app doesn't work at all. So even though you can build a phone gap application this way, the old way of, you know, web architecture, it's really, really, really not recommended to build it that way. And so the new school is to use what we call a single-page application. And a single-page application is essentially this. You have one and only one HTML page in your entire application. And then you will use JavaScript to create, to generate the UI at the client side, entirely in JavaScript. And you will create views in JavaScript at the client side that you will inject in that DOM. And when you don't need that view, you remove it from the DOM and you inject the next view. Okay? So you create the UI entirely at the client side in JavaScript. I'll get used to it. Okay. So some of the key differences here, obviously, compared to, you know, multi-page, you have only one page. The UI generation tier is client-side. It happens in JavaScript. It fully supports offline. You are fully in charge of the page transitions. If you ask the browser to go get the next page, the browser will be responsible for displaying it. And how will the browser do that? Boom, by simply replacing the existing page, forget the nice transitions that people expect. The major problem is that it's going to be slow. And another reason for that is that if on each page you load libraries and CSS files and stuff like that, it will have to be reloaded every single time. Obviously, in the single-page approach, because there is only one page, it's only reloaded once. So the number one principle is that even though for traditional web apps that you run, you know, on a traditional computer, single-page applications may or may not be a good fit for mobile applications, especially phone-gap apps, so not something that you run inside the browser, they are a must. You really need, if you want performance, you really need to do it this way. Okay? So the number one principle is use a single-page application. Now, there are many benefits, and we talked about them on the previous slide. There are also some downsides, because if you think about it the old way was really simple. Your unit of work was a page. And what can go wrong in a page? Can you have, let's say, memory leaks in a page? You know, the lifecycle of a page, you know, you displayed, the user is going to click something, and the page goes away. So the likelihood that you will experience a memory leak in that very small unit of work, it's very unlikely. However, with a single-page application, you never leave that page. It's always the same DOM. So now you really need to be careful about what you do, because I may actually spend eight hours in the same DOM, and remember, I will inject views, remove views from the DOM, so we'll speak about that in this presentation. All right, so how do you do it? How do you build a UI in JavaScript? Well, you know, it's HTML, so you know how to generate HTML. So if I need to create a view to display the details of an employee, I may do something like that. I create a string where I concatenate, markup, and then the model, you know, some data, and then I will render that. I will inject that fragment into the DOM. How do you guys like that? Beautiful code, easy to write, easy to maintain. You don't even have to use an HTML editor anymore, because it's totally useless, because of course, you can't get code hinting and stuff like that if you ever wanted to do that. You can't delegate the views to a designer, which these days is part of the workflow, because your designer is never going to write that code, obviously. So that is something that you shouldn't do. Instead, a better approach is to use templates. Now, I don't know if some of you are as old as I am and remember 16, 17 years ago how it started at the server side, it started the exact same way. I wrote that code in C and C++, and it was called CGI programming, and that's how you kind of generated dynamic web pages initially. And then people said, oh, that's crazy. You know, it's just not flexible enough, and we have to recompile all the time. Let's create templating engines or servers, and that's how PHP, JSP, Sqlfusion, all these solutions to that problem came about. Well we are solving the exact same problem here at the client side now. There are a lot of templating engines. And so the number two principle, the second rule, if you want, is that you absolutely need to do it that way. Otherwise, if you build anything more than a trivial application, you know, it's going to be a big mess. And so what should you use? There are many, many options, just like at the server side. Handlebars, JS, Mustache, JS, DustJS, if you use Backblown, we'll speak about frameworks in a second. Underscore.js is a kind of a multi-purpose library, but it also has support for templates. All right, so let's move on to this, which is something that I often see when I have to debug an existing PhoneGap application. I, you know, I try to debug it on my computer. And what's wrong here, oftentimes when I ask what's wrong, people tell me you have IE on your iPad that doesn't look right. So it's just, you know, to kind of give you the idea. What's wrong if this code is not minified is that there is a problem and the problem is happening online 3,000 something. And unless, of course, this code has been concatenated and minified, that indicates that your code is a big mess, okay? And I see that a lot because people start with JavaScript and, you know, the new JavaScript from the old days where you just kept adding functions to main.js. And that's essentially what happens at that point. So the third principle is really to think about it in a different way and very much like you talked about your code in another language and really provide structure to that code. And use some kind of an MV something, you know, architecture. And I put a star there because some people are religiously attached to MVC or MVVM. They are all different flavors of the core principle is that you should really partition your code. And that may be by creating model classes. And this is just, this is not like the way of doing it. You know, this is using a constructor pattern. You may want to use a module pattern. I don't really care at this point. I care that you partition your code. And let me actually go into some examples. I told you so, you know, some of the applications that I'm going to show you. So on the iPad, we're going to build something like this even though this is more of a phone layout. So this is the application that we are working on. And I want to show you some of the pieces. So first of all, principle number two was that, you know, you should work with templates. And so these are some examples of templates. The nice thing about templates is that at the end of the day, they are HTML. So you are back to, you know, HTML and then a bunch of placeholders. So like for instance, and this is using underscore JS. So that's the syntax. The most common syntax is the double curly. But underscore uses kind of a JSP syntax. And that's basically a placeholder simply saying, okay, at some point, I will merge my model into this and you will, you know, do the right thing. Okay. So now, so that's all of the templates. Now, let me show you some examples of views because it's all about, as I said, organizing your code here. So this is an example of a view. This is using actually backbone, but it doesn't really matter. The important thing is that we have a view here, a view object that we can instantiate if you want. And the way we render the view, so, you know, views typically will have a lifecycle and one of the methods of the lifecycle is going to be to render the view. And the interesting thing here is that you don't see any concatenated HTML code. The other thing we do is to actually invoke the template function and pass the model into it so that the template engine can do the merging like we expected. So you see that essentially I'll have, you know, this kind of object for each view in my application. And then I will also have models and in backbone, I created different models here. Models would be classes or objects that are responsible for managing the data. They don't know anything about the view. So that's, you know, a first rule of partitioning. And so that's kind of the way you start structuring your application. And we'll come back to that code in just one second. So you have models, you have views. And again, this is just sample code depending on whether you're using a framework or not, you know, it will be different. And then you can come up with your own approach. This is a controller and we'll speak about that one in a second. It's kind of a data adapter. I will speak about that specifically later in this presentation. Okay. So provide structure, use an MVC type of architecture. Now, before you go do that and try to reinvent the wheel, the fact is there are many, many, many smart people who have been thinking about this for a number of years now and came up with some frameworks. So before you create your own frameworks, I don't think the world needs, you know, additional JavaScript frameworks at this point, even though they keep coming. Consider using a framework. But consume responsibly, as always, because frameworks can be really easy. You know, there was one way of doing it with PhoneGap. PhoneGap is completely agnostic. As long as you have a web app, we'll happily package it and bridge it. We didn't want to say, hey, we would rather, you know, that you use that framework. That's really not what we wanted. But we saw a lot of people getting trouble. And so now I'm going to be just slightly a little bit more, you know, specific about what I think is good and what I think is bad. So the way we look at frameworks, and I don't think it's very controversial, is that there are really two categories of frameworks. On the left, you see what we call full stack frameworks. These are frameworks that try to solve all the problems in a web application. Some DOM manipulation, so how you access the different DOM elements to architectural concerns, so really provide that MVC type of structure. And then on top of that, make your application look good. So these frameworks typically come with a bunch of UI components, styles, themes, and that kind of stuff. So they cover the whole stack. In that category, you have Sencha, jQuery mobile, for instance, and Dojo, and they may be additional ones. Now, this is great because it's a one-stop shopping type of approach. You don't have to kind of make sure that all the pieces work together because hopefully, you know, the creators of these frameworks do that for you. The DOM side is obviously that it can be very heavy, and that in order to use one piece, you may have to embrace a lot of other things that you don't necessarily like. And a good example of that, there are a lot of people who start with phone gap using jQuery mobile. And I asked them, well, why did you choose jQuery mobile? And they said, well, it came with all these default components and the transitions and all that. I really needed that. So that's why I embraced jQuery mobile. Now, the problem, so basically, that person and there are many, was telling me, you know, I really liked what they have here in the UI layer, and therefore, I embraced everything else. Now, the DOM stuff is not a real problem. It's obviously jQuery core. But the real problem is the architectural stuff, which in jQuery mobile, you know, is you may like it and then it's fine, you can embrace it. But a lot of people are fighting it. And the only reason they keep fighting is to keep these UI components. So the other approach, if you are fighting it, don't use it essentially, and then build your own stack. And I have to say that these days, this is a more popular approach. And basically, in that case, you say, hey, for DOM manipulation, I'm not even going to use jQuery. Maybe I'll use Zepto because it's a clone in terms of syntax, but it's lighter weight because it doesn't care about old browsers. And when you build a map for mobile, you really don't care about old browsers. Or some people say, you know, jQuery was really helpful three years ago, but now you can pretty much do everything it does in plain JavaScript. So let's do that. Whatever seems right for you, you kind of pick your answer. Now, the big discussion is happening there in the middle in these micro architectural frameworks. You know, some people love backbone, some people love Angular, some people love Ember. And that's fine. You choose what you like because these frameworks are lightweight. I think certainly backbone is kind of the leaner, least directive type of framework. But even Angular, Ember, and Knockout are still reasonably sized. And you use that. And then on top of that, you may say, hey, I need to make my application look good. So I'm going to use a UI toolkit. Now, what you typically see in that category are toolkits, UI toolkits. I don't even call them frameworks because they don't do anything in that architectural box. They are typically 95% CSS. And if they are more than that, if they try to do stuff in the architectural layer, you shouldn't use them. Right? So you should really find one that focuses exclusively in that layer and that doesn't bleed on the other layers because that would mean it's not very well partitioned. Now, Twitter Bootstrap and Zurb Foundation are nice. They were not really created for mobile apps initially, even though they are adding components. Two good examples of UI toolkits would be Ratchet CSS and a new one that we are actually working on at Adobe called TopCode. So I'm going to show you TopCode. So this is basically why did we do that? Because one of the complaints that people had about PhoneGap was that it was too hard to build applications that looked good. And let's face it, initially, the initial adopters of PhoneGap were people like you and me, developers. And we are extremely good at writing code, but our skills are not necessarily great at coming up with great design and using the right gradient and the right text shadow and that kind of stuff. So we created apps that worked, but that looked terrible to kind of simplify. So people asked us, please, please, please help us there and give us some options. So this is really, really early and it's developed completely in the open. It's a GitHub project, an open source project. And it's 99.9% CSS. In fact, at this point, it's really 100% CSS. So you can still use the framework that you like and build the application the way you like. And we give you the themes and the skinning and stuff like that. So all these things, and that was the advantage of doing my presentation, really in a PhoneGap application, I can show you these components. There is a lot more to it. And you can go to topcode.io, which is the website, or you can go straight to the GitHub repository, get the code, and even, ideally, contribute to the code. Now, let me show you another example. So this one is actually Ratched CSS. Really, really simple and cool. And I like it a lot when I have to prototype, especially an iOS-looking type of application. Really consider Ratched CSS because, again, it focuses exclusively on that layer. It's very lightweight, very simple to use, and gives you a great look and feel out of the box. It looks a lot better, actually, on the phone because it was really built for that. The idea of Ratched is really iOS-specific. Topcode tries to be kind of a neutral theme. And if you follow the announcements on Monday, iOS 7 and all that, you will see that everybody is kind of going to a very flat, you know, Windows Phone-like, and even end the new versions of Android. And now iOS is very flat, no gradient, no kind of big Chrome stuff. It's really, you know, the content being king. And that's really the idea behind Topcode. All right. There's a little delay here. Okay. All right. So let's keep going in terms of architecture. And now I'll need your help because it's getting late for me, too. And I'll show you some code and you'll have to tell me what's wrong. Anybody wants to play that game with me? So this is something that I see a lot when I look at existing phone gap applications, and in fact, it doesn't have to be phone gap. I see this type of calls throughout the code. And think about maybe even the code that you write, hopefully not too much, but I see that really across the entire code base. And what's wrong with that? What's that? A bit chatty? No error and handling. You guys are really going into the details. But at a higher level, what is this? Well, because you may need data from the server. Yeah. Yeah. And we'll speak about that. Ideally, you'd love to never have to go to the server because it's going to be a lot faster. But sometimes, obviously, you need data from the server. But the question is interesting, though. This is obviously an Ajax call. And now throughout my application, I'm marrying myself to Ajax, right? And I'm saying, OK, well, so my data access strategy is Ajax. And it's really hard coded everywhere across many different components. Now, what if one day I decide that I don't want to do Ajax anymore, but I decide to be a lot more aggressive in terms of caching and try to go get data from a local database on the device as much as I can? Or what if I say, hey, isn't unit testing a good idea? And how granular can a unit test be if I have a server dependency? Does that really make sense? So this is not really good to be so specific about your data access strategy. So principle number five is that you really shouldn't do that. And you should abstract your data access strategy. Now, this is one of the common sense stuff that I told you about at the beginning of my talk, of course. And you have been doing that in other languages forever. But for some reason, when people go to PhoneGap, they are, Ajax, let's do it. Let's go. And you see that code all over the places. So here is what the same code roughly, and we may add, you know, error handling and that kind of stuff. But the same code at a high level should look something like this. Because if you read this code, you clearly have no idea at the end of the day, you know, how the data will be retrieved and from where? Okay, this is very generic. You have a data adapter that's going to do the trick behind the scenes. And basically the way you do that is by implementing a common interface. And you have then these pluggable adapters that implement the exact same interface. They all implement the same interface. And typically, I start, I always start with an in-memory adapter. Because that lets me really iterate super fast. What you should never do is wait for the server-side developer to, you know, build your big stack of RESTful services because then you kind of tie yourself to these services. I like to be very creative initially and say, okay, you know, let me come up with fake data because then I can really build the application that I have in mind and then we'll solve that problem to get to the data. Now, I know that it's a little bit backwards compared to what we've been doing, you know, the last 15 years where we started at the server-side. But now, people understand the value of a good user interface or user experience. So I typically start with that. I have a WebSQL adapter because that's still what iOS supports more than index DB. I may have a local storage adapter. And of course, I may have an Ajax adapter. And the benefit of this, for instance, if I say, you know what, the data that I used to get through Ajax, now I really want to get them from my local database, I can just unplug one adapter, plug the other one, and I'm done. Okay? So let me show you a few examples of that. So I'm going to start with those ones here. Again, there are different ways to implement them. I'm going to start with a very simple one. Again, implement it as an object, as a constructor, essentially. But so that's to get, you know, data about an employee. And so I called it JSON adapter. And basically, it defines an API. There is an initialized method in case I need to. If it was a database, maybe I need to open the database or do something of that nature. But most importantly, the real API is defined by ID, defined by name, and you go on, find no, find by manager, et cetera, et cetera. Now, the implementation of that here, of that adapter, is to indeed make an Ajax call. Okay? So I don't make my code a lot more complicated. In fact, I think it's cleaner. But the benefit is that now, if these services are not ready, I can go to this guy. And start with that. So this is my memory adapter. And you see how simple that is. I create dummy data, in this case, in an array. And then I implement the exact same interface. Okay? And you can go on and on and on. So I have here a WebSQL adapter. And you recognize your old friend SQL there. But again, inside the exact same API. Okay? Find by ID, find by name. And in there, I do some SQL. Okay? And now I can really plug and play these different adapters. Now, let's go back to the memory adapter. So it seems simple enough. It's even simpler than in other languages because you don't have to formally define an interface and all that. But, well, actually, let's go back to the JSON. Obviously, the methods have to be to have the same name. But that's not enough because what is an Ajax call returning? Obviously, I'm using jQuery here to make my Ajax call. What does it return? What do I get back from an Ajax call? A promise. So essentially, an Ajax call is asynchronous. So to make the plug and play thing work, not only do your methods have to have the same name, but they have to be invoked the same way. Because if one, you know, define by ID in my Ajax adapter returns a promise, so is asynchronous, essentially. And my in-memory adapter is synchronous, then it's not going to be plug and play, right? Because I'm going to have to invoke the methods in different ways. Which is why you notice that when I look at my in-memory adapter, I create, this is the jQuery implementation of that, I create a deferred object that I resolve immediately, okay? But the call is still going to be asynchronous. And indeed, the method returns a promise, the promise of that deferred object. And now, even though this is clearly, this can clearly work synchronously because all the operations are synchronous, but I provide that object with an asynchronous interface so it matches, you know, my Ajax adapter, which obviously is going to be important. So that's the little trick. You need to make sure that, you know, not only they have the same name, but they work the same way, they are all asynchronous. Okay. This one is really interesting, too, and I see a lot of issues with that, too. So abstract device features, which also means keep your application browser-runnable. So what do I mean by that? Okay, let's take an example. So there is a button there that says show notifications. So let's press that button. Let's press that button. Okay. How do you like this? You like it? Because I'm nice. I agree to you. But what can you immediately say about this application? And I, it's not a big secret because I told you before, but what can you say about this application? It's HTML. You love the body of that message, but you don't really like the header because if you use a JavaScript alert, like many people do when they develop a phone-gap application, they will see index.html. And you just gave away the fact that your application is not native and that's confusing for users. You know, casual users, they'll say, what is that thing? I'm not in a browser. Okay. So you're going to say, okay, that's easy to solve because as I said, phone-gap gives you these bridging APIs. Okay. And one of the bridging APIs you can see there is basically a bridge to a native alert. Okay. So let's try that. Phew. Okay. It looks much better because now that looks, you know, you can put whatever you want in the title in the body and even on the button, I can now relax because it looks great. But if I use that now, the problem is that it doesn't run in the browser. And my rule was keep your application browser runnable. And the main reason for that is because you want to be able to debug it easily. Believe me, debugging on this, even though it's getting better, is not fun. Debugging on this using, you know, for instance, the Chrome developer tools, really good tools. So if I can keep debugging my application here, that will make me a lot happier. So don't just replace all your JavaScript alerts with that because that's one easy way to totally break your app inside the browser. So now you know the approach. We are going to do the exact same thing we did for data access. You're going to abstract it one way or another. You're going to have some kind of a notification interface. Okay. So kind of the exact same way if you want. And so this is not the only thing that you need to abstract. So we spoke about notification. We spoke about storage with the data adapters, the sensors. So sensors are everything essentially that you can do with that thing, like access the GPS, the accelerometer, the compass. So these are all sensors that are available here, but not necessarily here. It's coming, but right now a lot of them are still not available here. So just don't just assume that you can invoke these things because again you break the rule, keep your application browser runnable and debugging is not going to work anymore. Now the last one is so interesting that I'm going to spend one specific item on that. You need to abstract the user interactions with your application because obviously if I work on this, this is mostly going to be through touch. If I work on this, at least the machine that I have, it's mostly going to be through the mouse and the keyboard. So principle number seven is that you really, really need to handle touch. Just don't ignore it like I see so many people do. So let me show you one way people ignore touch and simply do mouse because guess what? For developers who are not interested in the finest experience, mouse events actually work as touch events. In other words, if you use a click event and then tap with your finger, it's going to work. Not well, but it's going to work. And I see probably in over 50% of applications that I look at, people don't bother. They use these mouse events. And so what happens, for instance, so here is an example of what happens. So I have a list of items that I can select. I can tap. So let's do that. I'm going to select one. See the problem? So let's do it again. Before the event even reaches the application, it takes over 300 milliseconds. That's 300 milliseconds that I have no control over. My application has no control over. This is the OS. And why? Because the OS is wondering if you're going to mean double click. So it says, if after 300 milliseconds you didn't tap a second time, I'm pretty sure it's a click unless you're really, really slow. So at that point, I'm going to send a click event to your application. Now you may say, come on, 300 milliseconds. Who cares? People care a lot. On mobile, if it's not immediate, people reject your app and will say, hey, this doesn't feel native. It doesn't have to be that way. A lot of people say, look, phone, it's slow. Look. It doesn't react. That's what people who don't like hybrid applications, they will enjoy doing that kind of stuff to prove you wrong. But it doesn't have to be that way. So let me show you the exact same list. And I'm going to do this. Now you see basically what's happening. I'm using touch start here, which is triggered right away, two, three, four, or five milliseconds. Whereas my click event is still struggling because it's waiting to be triggered by the operating system wondering if it's a double click or not. So you say, great. That seems pretty simple. I'm just going to do a global fine and replace of all my click events by touch start. Now what happens if you do that, you break my other rule, which is that nothing is going to work here now. And I wish it could be as simple as that, but it's not only about tap events. Sometimes it's not only about touch start. Sometimes you have composite events like, okay, I want to swipe. And so if you just use touch start throughout, you're going to be in trouble and you're going to break a bunch of stuff. So basically what you have to do is say, okay, well, you do feature detection. You say, well, if touch start is available, I'm going to use that. If not, I'm assuming that you use some machine like this. And I'm going to register a click event. So that's pretty messy code, right? To kind of have to do feature detection at that level. So before you write that code, again, there are libraries that will do that for you automatically. And a really good one is called Fast Click. And basically, Fast Click is a drop-in library. You basically just add the script tag and magically it's going to do exactly what I said. So you keep coding essentially your click events, but Fast Click is going to hijack your click event and see, okay, is touch available on this device? If yes, I'm going to replace your click event by a touch event. Okay? So it's not the only one, but again, that's actually a pretty good option. Yeah. Well, so Fast Click doesn't, you know, does the right thing. Swipe is still going to work. In fact, I'm using Fast Click in this application and you see that I can still swipe. So that's the beauty of it, because handling that code can be really complex. So before you venture into that, you know, problem, look at Fast Click. Another good one is called Hammer.js. Also handles all the touch events really nicely. So these are libraries that have been tested in the field and we know they work. Okay. So number eight, we're getting there. Another reason a phone gap application may not deliver the best performance is when you don't use hardware acceleration. Now, let me kind of a mental break here. Show you one example and this one I will show it to you back later. So this is a prototype of a game. Okay. So you don't see anything. Okay. Oh, yes. Okay. So there is a, you know, you don't have the best experience because I'm streaming my screen, but hopefully you can see that this guy is running pretty fast, but it's super smooth on my screen here. You can come and check at the end of the session. So you need to use hardware acceleration. The place you typically see it immediately is when people, you know, slide pages and it looks jerky. It doesn't look like the smooth native experience. You need to hardware accelerate these transitions. Don't use jQuery transitions to do this. Don't do these transitions in JavaScript. Essentially, don't do them on the CPU. You need to execute these transitions on the GPU. Okay. So here is a typical setup. Don't worry. The screens are not going to bleed out of your screen. This is just my way of trying to represent that. A typical setup is to basically, when you're going to slide a view from the right to the center, you position it immediately to the right of the viewport of your WebView. Okay. And there is a, you define a CSS class that typically I call right to say, okay, this one is to the right of the viewport. The other one has the class left which positions it to the left of the viewport. And essentially, if I want to move the blue one to the center, I will press that button here. And you see it was nicely animated. The only thing I did was to essentially change the class name to center. If I want to put it back, to put it back to the right, I do that. If I want to move that one. And you see, I hope we don't lose too much, I'm sorry, I hope we don't lose too much of responsiveness through the streaming. It's pretty snappy. Okay. So how does it work and how do you do it right? So typically, people will start this way. They will say, okay, I got it, you know, to the right, I'm going to position it. I'm going to put the position, the left style to 100%. 100% is essentially the width of the viewport. So if you put the left attribute 100%, it's going to put it right to the left of the viewport. Right is going to be, sorry, left is going to be minus 100%. And that's how you do it. The problem if you do it this way, it's going to work just fine. Okay. This is going to, when you change the class of a div, it's going to put it to the right position. And because you also add the transition class, that thing is going to be animated. So it's good because this is already CSS animation as opposed to JavaScript animation. That is a progress. But this is not hardware accelerated. It's going to work. And depending on your hardware, it may be pretty jerky. So here is the right way of doing it to get hardware acceleration. You need to use a transform. And so it's essentially very much the same thing. But instead of setting the left attribute, you transform the x coordinates. So the first parameter of translate 3D is actually the x coordinate. And then the second is y and the third is z. Okay. So when you do that, using translate 3D, automatically will execute that transition on the GPU. Okay. The previous one is still doing it on the CPU. So very small technique, but that is what's going to make it faster. That's going to work on the desktop as well. So this was so common of a problem that I decided to write a little library, a kind of a micro library that does just that. And so if you want to get it, it's on my GitHub repository. It's called page slider. And it's very, very tiny. But it does exactly what I just told you in an efficient hardware accelerated way. No, for that you would probably have to use a polyfill and do some feature detection. I'm, well, on Android, you don't really get hardware acceleration in the same way. So certainly on older version of Android, it's not going to be hardware accelerated. But you still have to optimize it where you can. And certainly on iOS, that's going to make a big difference. It will work. It will work on Android. It will just not accelerate it. It's still going to be on the CPU. All right. Now, we are getting into the subtle things, but still we need to be really perfectionists if you want. So hide HTML behaviors in your application. And we spoke about one which was the alert. So that's an HTML behavior. But there are more subtle ones. Like this one. Have you ever tapped or pressed a link for a long time? Let's try. Okay. And then you get that. That's the default iOS behavior when you long tap a link. Hey, you seem interested in that link. Would you like to copy it? You want to open it? No. No, no. For me, this is not a link. I happen to implement this as a link. But for me, this is a list item. In an app, that's a list item. So please don't do that. Okay. Because again, if someone sees that, first of all, that's super confusing. Because that's really not what I expected. But again, you gave away that your application was not native. So it doesn't have to be that way. A simple style that you define on the anchor element will get rid of that. So now I can do this as long as I want. And it never, that little pop-up is never going to show up. Now, you still see a little thing that doesn't look right. That highlight is there. It's not something that I wanted. It's by default. You see, when I tap, you get that highlight. And you don't want that. Maybe you want your own, but you don't want that one. So there is another style that you can apply. And by the way, I will make all these slides available because I see a lot of people taking pictures, which is great. But if you go to my blog, you'll be able to go to slash NDC.PDF. And I'll put all that in a PDF file for you. NDC.PDF, yeah. So now it's all gone. Okay. Now I can do what I really wanted to do, but I don't have these HTML behaviors. Great. Now, we have just a couple of minutes for the fun part of my presentation where I will really ask you. So we covered a number of performance techniques already, you know, hardware acceleration, the click, the 300 millisecond delay that you really want to avoid. But there are a couple of typical problems that we have seen in applications. And I'll let you guess what they are. So what's wrong with this code? So I need to display a list of states in the United States. Now, you may not be familiar with that, but states in the United States don't change every day. There are 50 of them. It has been like that for some time, I think. So what's wrong with it based on that helpful piece of information? It's static data. You should never make that call to the server. I mean, it's already bad, you know, but on a mobile device, that's criminal. Okay. You should never make that call to the server. Yet, I see tons of stuff like you have a full-blown SQL database available to you on this. Okay. Or maybe if it's not that bit, it can go in local storage or whatever you want. This is another problem that I see all the time. And if you add them up, that is what creates slow applications. What's wrong with this one? Exactly. So if you didn't know it, this is essentially a query that I'm executing on the DOM. And it looks like I'm trying to style and configure a bug button in my header. So I'm, you know, adding a click handler. I changed the color, changed the text decoration, and I set the href link. So I do four operations on that same button. But every single time I query the DOM, it's like if every single time, you know, you wanted to read a field of an employee, you would reexecute the same select statement. It's that bad. Okay. So obviously, the right answer is to do something like that. You execute the query only once. You put it in a variable. You can use the dollar sign as a convention to remind you that it was a query on the DOM. But then you use that cached variable to do your business on that, you know, on that button. This one is a little more subtle, but it's even worse. So this is a view, some kind of a view, that I will instantiate multiple times. So I will create multiple objects because it's an employee view. Every time I need to display an employee, I will display, I will instantiate that view. I see that all the time as well. This is really bad. It has a big impact on performance. What's wrong with this one? Exactly. I have that template there. It's a handlebars template. And it doesn't matter which technology you use, with templating technology. In the initialize of the employee view, so that's going to be executed every single time, I recompile the template. The process of compiling a template is typically to create a function that you can pass an argument to do the model merging. There is absolutely no reason for that. You should compile it once and not every single time you create an instance. So when people start using templates, I see that a lot and that's not good. So a solution to that is maybe to pass the, to inject if you want, that's a kind of dependency injection, to inject, I don't know how to say it, in another way, to inject the compile template into the view and you're all set. You don't recompile the template all the time. This one. So I have a screen there with a bunch of icons. And I displayed these different icons. You see these are different images. See that all the time too. Exactly. So this is what? Seven images. In other words, seven HTTP requests to actually load these images. That's also kind of criminal, right? It shouldn't be that way. So what's the solution to use a sprite, which essentially is one big image with all your icons in this case, right? And you use that image as the background. You create a little viewport, you know, maybe 18 by 18, which is the size of an icon. And then you offset the background to display the icon that you really want to display. Makes a big, big difference. In fact, that application that I was showing you before, and again, I hope that I get that guy to run fast for you, come on. Okay. That's not bad. This is using a CSS sprite. This game is built using DOM. It's not Canvas at all. It's entirely DOM. And so basically, that's an image. Now, try to do the same thing by swapping the image. That guy is going to, you know, take his time. The only way to make him run fast, and again, you need to see it on my iPad, is to use a CSS sprite and to offset the background. That's the only way you can get to that level of performance. We are almost done. That one, I also like a lot because this is something you don't really think about during development, but that can become a big problem in production. So I need to display an employee. So in this case, again, I have no choice. The data is on the server. So I need to go to the server, get the data. And then, of course, it's an asynchronous call. So when I get the product back, it's a product in this case, then I display the view. I display the product. So imagine I have a list of product. I click one, and then that code runs. It's very possible that for two or three seconds, nothing is going to happen. So I'm going to tap that thing and like, what's going on? I don't see anything. Why? Because I'm not changing the view. I'm not displaying the view until I get the data back. So the rule is don't wait for the data to display the view because if you wait for the data, you know, people can wait for data. If you display the right, you know, visual queue if you want, that's fine. But people don't wait for the UI. As soon as you tap, you should move to the product detail view, and then it's empty initially, and then you update the view. So you do something. It's here, but, okay, whoops. Okay, here we go. You display the view, you make the request, you update the view. And the very last one, and probably the most important one because that's one that people don't think about and has very dramatic impact on the performance. By the way, most of these techniques are not specific to phone gap applications. It's basically web performance techniques at this point. But this one is very, very, very important. What's wrong with that code? Yeah, so it looks like I need to display a list. How many times am I going to relay out that document just to display that list? I'm going to do 100 relay outs on that document, which is crazy because relay out is probably one of the slowest operations performed by a browser. And here, for absolutely no reason, I'm doing that 100 times because obviously the only thing the user is interested in is the final list, right? And that's still the only thing the user is actually going to see. Okay, so what's the solution to this? Yeah, exactly. And again, think about it. So this is one simple way of solving that problem. You build a string, and then at the end, one DOM operation, so one relay out versus a 100 relay out. You would be amazed if you go through your code at the difference that this is going to make to your application. And that's really what I wanted to tell you. So let's quickly summarize. Use single page applications, use templates, handle bar JS is a really good one if you don't know what to use. Use some kind of MVC architecture framework. I told you my personal preference for build your own stack as opposed to the full stack frameworks, even though they have a place to abstract data access, abstract device features, specifically touch events. Don't get that 300 milliseconds delay, please. I don't want to see those hardware accelerations, these subtle HTML behaviors, and then architect for performance. That's all the time we have. I'll be around if you have additional questions. Thank you very much.
 Okay. Yes. Okay. I think it's working. Good afternoon, everybody. And thank you for coming  so late. I know I'm the only person now between you and the party, so I'll try to keep you  awake. My name is Christophe Conrad. I work with Adobe. I'm based in Boston. I work with  the PhoneGap team, and what I'd like to do with you today is to kind of take you through  my experiences working with developers like you who build PhoneGap applications. So a lot  of I'm going to show you a number of examples. So that's why I put my GitHub repository there.  Sorry about the last name. That's the difficult part of this session. But most of the examples  that you will see today are on that GitHub repository. On my blog, too, I blog a lot about  PhoneGap, so you can find a lot of interesting information there as well. So what I decided  to do was to try to do a top ten to keep it kind of lively. You know, top ten architectural  principles. Some of them will be geeky, but a lot of them, as you will see, will be common  sense. But for some reason, when we move to a new platform, sometimes we tend to forget  what we learned in the previous language. And I'll try to remind you that you can actually  apply some of the same principles when you build an application with PhoneGap. But before  I do that, I always like to come back home with a little souvenir of my audience. So  I need to know a little bit more about you. But the first thing I will do is this. I'm  going to take a picture of you if that's okay. Let's see. All right. Let's do it. All right.  And let's bring it back there. I think that's fine. I'll use Photoshop to add a few more  people, but I think that will be fine. Which brings up a good question. What am I using  here to do this presentation? What technology, what, you know, presentation technology am  I using to do this? Am I using PowerPoint? Am I using Keynote? I'm using PhoneGap. Yes.  So what you see here is actually a PhoneGap application. And I thought it would be useful  to build it that way because then I will be able to show you stuff inside a presentation  without doing the usual back and forth between my device and then the computer. So let's  see if this works. Okay. So let's get started. So native applications are cool. And at Adobe,  for instance, we build a lot of native applications. Like, for instance, if you use Photoshop on  your device, this is not an HTML application. It's a native application. It makes a lot  of sense because what we're doing in Photoshop is manipulating a crazy amount of pixels and  it's very, very heavy. And native applications make total sense for that. However, we have  also a lot of applications built with HTML because it makes sense when it's not crazy  intensive like Photoshop, it makes sense to use an abstraction layer. And you all know  that there is an abstraction layer that exists out there and that's essentially the WebStack.  So HTML, JavaScript and CSS. And when you build with that, you can actually target all  these different platforms. Some of them you may not be aware of. I finally found a bad  developer the other day in Montreal. I was told that most of them are in Korea because  it's a Samsung thing. But there are new platforms coming too. Like, for instance, the Mozilla  phones with Firefox OS, Tizen, and there are, seems like every day there will be a new platform.  And the nice thing about the WebStack is that you can build and deliver to all these platforms  through the browser. Now, I don't know if any of you has ever tried to take index.html  and submit it to the Apple App Store. They are not going to take that. So your delivery  mechanism is really the browser. And that was really the initial idea behind PhoneGap.  We said, okay, we love that platform so much and we are so close to being able to build  apps with it that we're going to try to fill that gap if you want and to enable the development  of apps. So something that you can actually deliver through the different app stores and  things like that. So basically what we did initially was create a very thin, a very  lightweight shell, a native shell that's simply wrapping your web app. So if you look at this,  this is essentially 99% HTML, JavaScript, and CSS and 1% native. And the good news is  even that native piece, we give it to you, that's essentially what PhoneGap is. It's  a wrapper. But if you do that, your application may still not be interesting. And to be honest  with you, Apple may still reject it. There is an item in the licensing agreement that  if all your application is, is essentially a web app that you wrap, please deploy it  through the browser. We are not going to take these applications. So they really want you  to use the features that are available on your device. And so that's really the second  component of PhoneGap. PhoneGap is a bridge. It gives you a consistent JavaScript API to  all the cool features that you have on your phone, the GPS, the accelerometer, the camera,  the contacts, you name it. And it's always the same JavaScript API. In other words, when  you develop that application, you don't have to, you know, if iOS, then this JavaScript  API, else if Android, then this JavaScript API, no, it's always the same thing. And we  do the bindings if you do behind the scenes. So that's the second piece of PhoneGap. And  if you know that, you know everything about PhoneGap. PhoneGap is nothing else, and that  is by design. It's just a wrapper and a bridge, a wrapper for your web app. So now let's get  into the real topic of this talk. Because it's a web app, a lot of people say, okay,  I know how to develop web apps. We've been developing web apps for 15 years. I know how  to do it. And then they get in trouble. And really what I want to do with you is to try  to make sure that you don't get in trouble. So this is how people have been building web  apps in the past. That's the old school architecture if you want. And you may recognize that you  may have some version of that inside your company. That's a sitemap, right? And that's  kind of your web app or your website. And behind each of these boxes, there is a little  piece of PHP, JSP, ASP, Ruby on Rails or whatever. At the server side, that's going to generate  a piece of UI, a piece of HTML that you then send back to the client and the client will  render that HTML. So in other words, if I was to build, if that gets confusing, if I  was to build a mobile application with that architecture, it would look something like  this. So this is an employee directory application. You see that I work for an interesting company  here. If I click one of these guys, it would do something similar to that. It would say,  oh, okay, I need to display the details of that specific employee, Dwight. So I'm going  to go ask my PHP server or ASP or whatever to give me that page. Is that good? Do you  think you want to do that? And I'm saying that because I know you guys are super smart,  but some people actually start this way. And then they say, hey, I can't use phone  gap, it's too slow. But what happens here has nothing to do with phone gap, obviously.  What happens is that you ask the server to generate your UI. And obviously, there is  the network latency. There is, you know, if you're in the subway, it's going to take  three seconds. On the web in a browser, people are used to wait two seconds. On the mobile  app, not at all. They will totally trash your application if they have to wait half a second.  So that is simply not acceptable. Okay? And the second thing that's probably not acceptable  is that if you rely on the server to generate the UI, what do you lose that's expected from  a mobile app? Offline, right? If you rely on a server and the server is not there, your  app doesn't work at all. So even though you can build a phone gap application this way,  the old way of, you know, web architecture, it's really, really, really not recommended  to build it that way. And so the new school is to use what we call a single-page application.  And a single-page application is essentially this. You have one and only one HTML page  in your entire application. And then you will use JavaScript to create, to generate the  UI at the client side, entirely in JavaScript. And you will create views in JavaScript at  the client side that you will inject in that DOM. And when you don't need that view, you  remove it from the DOM and you inject the next view. Okay? So you create the UI entirely  at the client side in JavaScript. I'll get used to it. Okay. So some of the key differences  here, obviously, compared to, you know, multi-page, you have only one page. The UI generation  tier is client-side. It happens in JavaScript. It fully supports offline. You are fully in  charge of the page transitions. If you ask the browser to go get the next page, the browser  will be responsible for displaying it. And how will the browser do that? Boom, by simply  replacing the existing page, forget the nice transitions that people expect. The major problem  is that it's going to be slow. And another reason for that is that if on each page you  load libraries and CSS files and stuff like that, it will have to be reloaded every single  time. Obviously, in the single-page approach, because there is only one page, it's only  reloaded once. So the number one principle is that even though for traditional web apps  that you run, you know, on a traditional computer, single-page applications may or may not be  a good fit for mobile applications, especially phone-gap apps, so not something that you  run inside the browser, they are a must. You really need, if you want performance, you  really need to do it this way. Okay? So the number one principle is use a single-page  application. Now, there are many benefits, and we talked about them on the previous slide.  There are also some downsides, because if you think about it the old way was really simple.  Your unit of work was a page. And what can go wrong in a page? Can you have, let's say,  memory leaks in a page? You know, the lifecycle of a page, you know, you displayed, the user  is going to click something, and the page goes away. So the likelihood that you will  experience a memory leak in that very small unit of work, it's very unlikely. However,  with a single-page application, you never leave that page. It's always the same DOM.  So now you really need to be careful about what you do, because I may actually spend  eight hours in the same DOM, and remember, I will inject views, remove views from the  DOM, so we'll speak about that in this presentation.  All right, so how do you do it? How do you build a UI in JavaScript? Well, you know,  it's HTML, so you know how to generate HTML. So if I need to create a view to display the  details of an employee, I may do something like that. I create a string where I concatenate,  markup, and then the model, you know, some data, and then I will render that. I will  inject that fragment into the DOM. How do you guys like that? Beautiful code, easy to  write, easy to maintain. You don't even have to use an HTML editor anymore, because it's  totally useless, because of course, you can't get code hinting and stuff like that if you  ever wanted to do that. You can't delegate the views to a designer, which these days  is part of the workflow, because your designer is never going to write that code, obviously.  So that is something that you shouldn't do. Instead, a better approach is to use templates.  Now, I don't know if some of you are as old as I am and remember 16, 17 years ago how  it started at the server side, it started the exact same way. I wrote that code in C  and C++, and it was called CGI programming, and that's how you kind of generated dynamic  web pages initially. And then people said, oh, that's crazy. You know, it's just not  flexible enough, and we have to recompile all the time. Let's create templating engines  or servers, and that's how PHP, JSP, Sqlfusion, all these solutions to that problem came about.  Well we are solving the exact same problem here at the client side now. There are a lot  of templating engines. And so the number two principle, the second rule, if you want,  is that you absolutely need to do it that way. Otherwise, if you build anything more than  a trivial application, you know, it's going to be a big mess. And so what should you use?  There are many, many options, just like at the server side. Handlebars, JS, Mustache,  JS, DustJS, if you use Backblown, we'll speak about frameworks in a second. Underscore.js  is a kind of a multi-purpose library, but it also has support for templates. All right,  so let's move on to this, which is something that I often see when I have to debug an existing  PhoneGap application. I, you know, I try to debug it on my computer. And what's wrong  here, oftentimes when I ask what's wrong, people tell me you have IE on your iPad that  doesn't look right. So it's just, you know, to kind of give you the idea. What's wrong  if this code is not minified is that there is a problem and the problem is happening  online 3,000 something. And unless, of course, this code has been concatenated and minified,  that indicates that your code is a big mess, okay? And I see that a lot because people  start with JavaScript and, you know, the new JavaScript from the old days where you just  kept adding functions to main.js. And that's essentially what happens at that point. So  the third principle is really to think about it in a different way and very much like you  talked about your code in another language and really provide structure to that code.  And use some kind of an MV something, you know, architecture. And I put a star there  because some people are religiously attached to MVC or MVVM. They are all different flavors  of the core principle is that you should really partition your code. And that may be by creating  model classes. And this is just, this is not like the way of doing it. You know, this is  using a constructor pattern. You may want to use a module pattern. I don't really care  at this point. I care that you partition your code. And let me actually go into some examples.  I told you so, you know, some of the applications that I'm going to show you. So on the iPad,  we're going to build something like this even though this is more of a phone layout. So  this is the application that we are working on. And I want to show you some of the pieces.  So first of all, principle number two was that, you know, you should work with templates.  And so these are some examples of templates. The nice thing about templates is that at the  end of the day, they are HTML. So you are back to, you know, HTML and then a bunch of  placeholders. So like for instance, and this is using underscore JS. So that's the syntax.  The most common syntax is the double curly. But underscore uses kind of a JSP syntax.  And that's basically a placeholder simply saying, okay, at some point, I will merge  my model into this and you will, you know, do the right thing. Okay. So now, so that's  all of the templates. Now, let me show you some examples of views because it's all about,  as I said, organizing your code here. So this is an example of a view. This is using actually  backbone, but it doesn't really matter. The important thing is that we have a view here,  a view object that we can instantiate if you want. And the way we render the view, so,  you know, views typically will have a lifecycle and one of the methods of the lifecycle is  going to be to render the view. And the interesting thing here is that you don't see any concatenated  HTML code. The other thing we do is to actually invoke the template function and pass the model  into it so that the template engine can do the merging like we expected. So you see that  essentially I'll have, you know, this kind of object for each view in my application.  And then I will also have models and in backbone, I created different models here. Models would  be classes or objects that are responsible for managing the data. They don't know anything  about the view. So that's, you know, a first rule of partitioning. And so that's kind of  the way you start structuring your application. And we'll come back to that code in just one  second. So you have models, you have views. And again, this is just sample code depending  on whether you're using a framework or not, you know, it will be different. And then you  can come up with your own approach. This is a controller and we'll speak about that one  in a second. It's kind of a data adapter. I will speak about that specifically later  in this presentation. Okay. So provide structure, use an MVC type of architecture. Now, before  you go do that and try to reinvent the wheel, the fact is there are many, many, many smart  people who have been thinking about this for a number of years now and came up with some  frameworks. So before you create your own frameworks, I don't think the world needs,  you know, additional JavaScript frameworks at this point, even though they keep coming.  Consider using a framework. But consume responsibly, as always, because frameworks can be really  easy.  You know, there was one way of doing it with PhoneGap. PhoneGap is completely agnostic.  As long as you have a web app, we'll happily package it and bridge it. We didn't want to  say, hey, we would rather, you know, that you use that framework. That's really not what  we wanted. But we saw a lot of people getting trouble. And so now I'm going to be just slightly  a little bit more, you know, specific about what I think is good and what I think is bad.  So the way we look at frameworks, and I don't think it's very controversial, is that there  are really two categories of frameworks. On the left, you see what we call full stack  frameworks. These are frameworks that try to solve all the problems in a web application.  Some DOM manipulation, so how you access the different DOM elements to architectural concerns,  so really provide that MVC type of structure. And then on top of that, make your application  look good. So these frameworks typically come with a bunch of UI components, styles, themes,  and that kind of stuff. So they cover the whole stack. In that category, you have Sencha,  jQuery mobile, for instance, and Dojo, and they may be additional ones. Now, this is  great because it's a one-stop shopping type of approach. You don't have to kind of make  sure that all the pieces work together because hopefully, you know, the creators of these  frameworks do that for you. The DOM side is obviously that it can be very heavy, and that  in order to use one piece, you may have to embrace a lot of other things that you don't  necessarily like. And a good example of that, there are a lot of people who start with phone  gap using jQuery mobile. And I asked them, well, why did you choose jQuery mobile? And  they said, well, it came with all these default components and the transitions and all that.  I really needed that. So that's why I embraced jQuery mobile. Now, the problem, so basically,  that person and there are many, was telling me, you know, I really liked what they have  here in the UI layer, and therefore, I embraced everything else. Now, the DOM stuff is not  a real problem. It's obviously jQuery core. But the real problem is the architectural  stuff, which in jQuery mobile, you know, is you may like it and then it's fine, you can  embrace it. But a lot of people are fighting it. And the only reason they keep fighting  is to keep these UI components. So the other approach, if you are fighting it, don't use  it essentially, and then build your own stack. And I have to say that these days, this is  a more popular approach. And basically, in that case, you say, hey, for DOM manipulation,  I'm not even going to use jQuery. Maybe I'll use Zepto because it's a clone in terms of  syntax, but it's lighter weight because it doesn't care about old browsers. And when  you build a map for mobile, you really don't care about old browsers. Or some people say,  you know, jQuery was really helpful three years ago, but now you can pretty much do  everything it does in plain JavaScript. So let's do that. Whatever seems right for you,  you kind of pick your answer. Now, the big discussion is happening there in the middle  in these micro architectural frameworks. You know, some people love backbone, some people  love Angular, some people love Ember. And that's fine. You choose what you like because  these frameworks are lightweight. I think certainly backbone is kind of the leaner,  least directive type of framework. But even Angular, Ember, and Knockout are still reasonably  sized. And you use that. And then on top of that, you may say, hey, I need to make my  application look good. So I'm going to use a UI toolkit. Now, what you typically see  in that category are toolkits, UI toolkits. I don't even call them frameworks because  they don't do anything in that architectural box. They are typically 95% CSS. And if they  are more than that, if they try to do stuff in the architectural layer, you shouldn't  use them. Right? So you should really find one that focuses exclusively in that layer  and that doesn't bleed on the other layers because that would mean it's not very well  partitioned. Now, Twitter Bootstrap and Zurb Foundation are nice. They were not really  created for mobile apps initially, even though they are adding components. Two good examples  of UI toolkits would be Ratchet CSS and a new one that we are actually working on at  Adobe called TopCode. So I'm going to show you TopCode. So this is basically why did  we do that? Because one of the complaints that people had about PhoneGap was that it  was too hard to build applications that looked good. And let's face it, initially, the initial  adopters of PhoneGap were people like you and me, developers. And we are extremely good  at writing code, but our skills are not necessarily great at coming up with great design and using  the right gradient and the right text shadow and that kind of stuff. So we created apps  that worked, but that looked terrible to kind of simplify. So people asked us, please, please,  please help us there and give us some options. So this is really, really early and it's developed  completely in the open. It's a GitHub project, an open source project. And it's 99.9% CSS.  In fact, at this point, it's really 100% CSS. So you can still use the framework that you  like and build the application the way you like. And we give you the themes and the skinning  and stuff like that. So all these things, and that was the advantage of doing my presentation,  really in a PhoneGap application, I can show you these components. There is a lot more  to it. And you can go to topcode.io, which is the website, or you can go straight to  the GitHub repository, get the code, and even, ideally, contribute to the code. Now, let  me show you another example. So this one is actually Ratched CSS. Really, really simple  and cool. And I like it a lot when I have to prototype, especially an iOS-looking type  of application. Really consider Ratched CSS because, again, it focuses exclusively on that  layer. It's very lightweight, very simple to use, and gives you a great look and feel  out of the box. It looks a lot better, actually, on the phone because it was really built for  that. The idea of Ratched is really iOS-specific. Topcode tries to be kind of a neutral theme.  And if you follow the announcements on Monday, iOS 7 and all that, you will see that everybody  is kind of going to a very flat, you know, Windows Phone-like, and even end the new versions  of Android. And now iOS is very flat, no gradient, no kind of big Chrome stuff. It's really,  you know, the content being king. And that's really the idea behind Topcode. All right.  There's a little delay here. Okay. All right. So let's keep going in terms of architecture.  And now I'll need your help because it's getting late for me, too. And I'll show you some code  and you'll have to tell me what's wrong. Anybody wants to play that game with me? So this is  something that I see a lot when I look at existing phone gap applications, and in fact,  it doesn't have to be phone gap. I see this type of calls throughout the code. And think  about maybe even the code that you write, hopefully not too much, but I see that really  across the entire code base. And what's wrong with that? What's that? A bit chatty? No error  and handling. You guys are really going into the details. But at a higher level, what is  this? Well, because you may need data from the server. Yeah. Yeah. And we'll speak about  that. Ideally, you'd love to never have to go to the server because it's going to be  a lot faster. But sometimes, obviously, you need data from the server. But the question  is interesting, though. This is obviously an Ajax call. And now throughout my application,  I'm marrying myself to Ajax, right? And I'm saying, OK, well, so my data access strategy  is Ajax. And it's really hard coded everywhere across many different components. Now, what  if one day I decide that I don't want to do Ajax anymore, but I decide to be a lot more  aggressive in terms of caching and try to go get data from a local database on the device  as much as I can? Or what if I say, hey, isn't unit testing a good idea? And how granular  can a unit test be if I have a server dependency? Does that really make sense? So this is not  really good to be so specific about your data access strategy. So principle number five is  that you really shouldn't do that. And you should abstract your data access strategy.  Now, this is one of the common sense stuff that I told you about at the beginning of  my talk, of course. And you have been doing that in other languages forever. But for some  reason, when people go to PhoneGap, they are, Ajax, let's do it. Let's go. And you see that  code all over the places. So here is what the same code roughly, and we may add, you  know, error handling and that kind of stuff. But the same code at a high level should look  something like this. Because if you read this code, you clearly have no idea at the end  of the day, you know, how the data will be retrieved and from where? Okay, this is very  generic. You have a data adapter that's going to do the trick behind the scenes. And basically  the way you do that is by implementing a common interface. And you have then these pluggable  adapters that implement the exact same interface. They all implement the same interface. And  typically, I start, I always start with an in-memory adapter. Because that lets me really  iterate super fast. What you should never do is wait for the server-side developer to,  you know, build your big stack of RESTful services because then you kind of tie yourself  to these services. I like to be very creative initially and say, okay, you know, let me  come up with fake data because then I can really build the application that I have in  mind and then we'll solve that problem to get to the data. Now, I know that it's a little  bit backwards compared to what we've been doing, you know, the last 15 years where we  started at the server-side. But now, people understand the value of a good user interface  or user experience. So I typically start with that. I have a WebSQL adapter because that's  still what iOS supports more than index DB. I may have a local storage adapter. And of  course, I may have an Ajax adapter. And the benefit of this, for instance, if I say, you  know what, the data that I used to get through Ajax, now I really want to get them from my  local database, I can just unplug one adapter, plug the other one, and I'm done. Okay? So  let me show you a few examples of that. So I'm going to start with those ones here. Again,  there are different ways to implement them. I'm going to start with a very simple one.  Again, implement it as an object, as a constructor, essentially. But so that's to get, you know,  data about an employee. And so I called it JSON adapter. And basically, it defines an  API. There is an initialized method in case I need to. If it was a database, maybe I need  to open the database or do something of that nature. But most importantly, the real API  is defined by ID, defined by name, and you go on, find no, find by manager, et cetera,  et cetera. Now, the implementation of that here, of that adapter, is to indeed make an  Ajax call. Okay? So I don't make my code a lot more complicated. In fact, I think it's  cleaner. But the benefit is that now, if these services are not ready, I can go to this guy.  And start with that. So this is my memory adapter. And you see how simple that is. I  create dummy data, in this case, in an array. And then I implement the exact same interface.  Okay? And you can go on and on and on. So I have here a WebSQL adapter. And you recognize  your old friend SQL there. But again, inside the exact same API. Okay? Find by ID, find  by name. And in there, I do some SQL. Okay? And now I can really plug and play these different  adapters. Now, let's go back to the memory adapter. So it seems simple enough. It's even  simpler than in other languages because you don't have to formally define an interface  and all that. But, well, actually, let's go back to the JSON. Obviously, the methods  have to be to have the same name. But that's not enough because what is an Ajax call returning?  Obviously, I'm using jQuery here to make my Ajax call. What does it return? What do  I get back from an Ajax call? A promise. So essentially, an Ajax call is asynchronous.  So to make the plug and play thing work, not only do your methods have to have the same  name, but they have to be invoked the same way. Because if one, you know, define by ID  in my Ajax adapter returns a promise, so is asynchronous, essentially. And my in-memory  adapter is synchronous, then it's not going to be plug and play, right? Because I'm going  to have to invoke the methods in different ways. Which is why you notice that when I  look at my in-memory adapter, I create, this is the jQuery implementation of that, I create  a deferred object that I resolve immediately, okay? But the call is still going to be asynchronous.  And indeed, the method returns a promise, the promise of that deferred object. And now,  even though this is clearly, this can clearly work synchronously because all the operations  are synchronous, but I provide that object with an asynchronous interface so it matches,  you know, my Ajax adapter, which obviously is going to be important. So that's the little  trick. You need to make sure that, you know, not only they have the same name, but they  work the same way, they are all asynchronous. Okay. This one is really interesting, too,  and I see a lot of issues with that, too. So abstract device features, which also means  keep your application browser-runnable. So what do I mean by that? Okay, let's take  an example. So there is a button there that says show notifications. So let's press that  button. Let's press that button. Okay. How do you like this? You like it? Because I'm  nice. I agree to you. But what can you immediately say about this application? And I, it's not  a big secret because I told you before, but what can you say about this application? It's  HTML. You love the body of that message, but you don't really like the header because if  you use a JavaScript alert, like many people do when they develop a phone-gap application,  they will see index.html. And you just gave away the fact that your application is not  native and that's confusing for users. You know, casual users, they'll say, what is that  thing? I'm not in a browser. Okay. So you're going to say, okay, that's easy to solve because  as I said, phone-gap gives you these bridging APIs. Okay. And one of the bridging APIs you  can see there is basically a bridge to a native alert. Okay. So let's try that. Phew. Okay.  It looks much better because now that looks, you know, you can put whatever you want in  the title in the body and even on the button, I can now relax because it looks great. But  if I use that now, the problem is that it doesn't run in the browser. And my rule was  keep your application browser runnable. And the main reason for that is because you want  to be able to debug it easily. Believe me, debugging on this, even though it's getting  better, is not fun. Debugging on this using, you know, for instance, the Chrome developer  tools, really good tools. So if I can keep debugging my application here, that will make  me a lot happier. So don't just replace all your JavaScript alerts with that because that's  one easy way to totally break your app inside the browser. So now you know the approach.  We are going to do the exact same thing we did for data access. You're going to abstract  it one way or another. You're going to have some kind of a notification interface. Okay.  So kind of the exact same way if you want. And so this is not the only thing that you  need to abstract. So we spoke about notification. We spoke about storage with the data adapters,  the sensors. So sensors are everything essentially that you can do with that thing, like access  the GPS, the accelerometer, the compass. So these are all sensors that are available here,  but not necessarily here. It's coming, but right now a lot of them are still not available  here. So just don't just assume that you can invoke these things because again you break  the rule, keep your application browser runnable and debugging is not going to work anymore.  Now the last one is so interesting that I'm going to spend one specific item on that.  You need to abstract the user interactions with your application because obviously if  I work on this, this is mostly going to be through touch. If I work on this, at least  the machine that I have, it's mostly going to be through the mouse and the keyboard.  So principle number seven is that you really, really need to handle touch. Just don't ignore  it like I see so many people do. So let me show you one way people ignore touch and simply  do mouse because guess what? For developers who are not interested in the finest experience,  mouse events actually work as touch events. In other words, if you use a click event and  then tap with your finger, it's going to work. Not well, but it's going to work. And I see  probably in over 50% of applications that I look at, people don't bother. They use these  mouse events. And so what happens, for instance, so here is an example of what happens. So  I have a list of items that I can select. I can tap. So let's do that. I'm going to  select one. See the problem? So let's do it again. Before the event even reaches the  application, it takes over 300 milliseconds. That's 300 milliseconds that I have no control  over. My application has no control over. This is the OS. And why? Because the OS is  wondering if you're going to mean double click. So it says, if after 300 milliseconds you  didn't tap a second time, I'm pretty sure it's a click unless you're really, really  slow. So at that point, I'm going to send a click event to your application. Now you  may say, come on, 300 milliseconds. Who cares? People care a lot. On mobile, if it's not  immediate, people reject your app and will say, hey, this doesn't feel native. It doesn't  have to be that way. A lot of people say, look, phone, it's slow. Look. It doesn't react.  That's what people who don't like hybrid applications, they will enjoy doing that kind of stuff to  prove you wrong. But it doesn't have to be that way. So let me show you the exact same  list. And I'm going to do this. Now you see basically what's happening. I'm using touch  start here, which is triggered right away, two, three, four, or five milliseconds. Whereas  my click event is still struggling because it's waiting to be triggered by the operating  system wondering if it's a double click or not. So you say, great. That seems pretty  simple. I'm just going to do a global fine and replace of all my click events by touch  start. Now what happens if you do that, you break my other rule, which is that nothing  is going to work here now. And I wish it could be as simple as that, but it's not only about  tap events. Sometimes it's not only about touch start. Sometimes you have composite events  like, okay, I want to swipe. And so if you just use touch start throughout, you're going  to be in trouble and you're going to break a bunch of stuff. So basically what you have  to do is say, okay, well, you do feature detection. You say, well, if touch start is available,  I'm going to use that. If not, I'm assuming that you use some machine like this. And I'm  going to register a click event. So that's pretty messy code, right? To kind of have  to do feature detection at that level. So before you write that code, again, there are  libraries that will do that for you automatically. And a really good one is called Fast Click.  And basically, Fast Click is a drop-in library. You basically just add the script tag and  magically it's going to do exactly what I said. So you keep coding essentially your  click events, but Fast Click is going to hijack your click event and see, okay, is touch available  on this device? If yes, I'm going to replace your click event by a touch event. Okay? So  it's not the only one, but again, that's actually a pretty good option.  Yeah. Well, so Fast Click doesn't, you know, does the right thing. Swipe is still going  to work. In fact, I'm using Fast Click in this application and you see that I can still  swipe. So that's the beauty of it, because handling that code can be really complex.  So before you venture into that, you know, problem, look at Fast Click. Another good one  is called Hammer.js. Also handles all the touch events really nicely. So these are libraries  that have been tested in the field and we know they work. Okay. So number eight, we're  getting there. Another reason a phone gap application may not deliver the best performance  is when you don't use hardware acceleration. Now, let me kind of a mental break here. Show  you one example and this one I will show it to you back later. So this is a prototype  of a game. Okay. So you don't see anything. Okay. Oh, yes. Okay. So there is a, you know,  you don't have the best experience because I'm streaming my screen, but hopefully you  can see that this guy is running pretty fast, but it's super smooth on my screen here. You  can come and check at the end of the session. So you need to use hardware acceleration.  The place you typically see it immediately is when people, you know, slide pages and  it looks jerky. It doesn't look like the smooth native experience. You need to hardware accelerate  these transitions. Don't use jQuery transitions to do this. Don't do these transitions in  JavaScript. Essentially, don't do them on the CPU. You need to execute these transitions  on the GPU. Okay. So here is a typical setup. Don't worry. The screens are not going to  bleed out of your screen. This is just my way of trying to represent that. A typical  setup is to basically, when you're going to slide a view from the right to the center,  you position it immediately to the right of the viewport of your WebView. Okay. And there  is a, you define a CSS class that typically I call right to say, okay, this one is to  the right of the viewport. The other one has the class left which positions it to the left  of the viewport. And essentially, if I want to move the blue one to the center, I will  press that button here. And you see it was nicely animated. The only thing I did was  to essentially change the class name to center. If I want to put it back, to put it back to  the right, I do that. If I want to move that one. And you see, I hope we don't lose too  much, I'm sorry, I hope we don't lose too much of responsiveness through the streaming.  It's pretty snappy. Okay. So how does it work and how do you do it right? So typically,  people will start this way. They will say, okay, I got it, you know, to the right, I'm  going to position it. I'm going to put the position, the left style to 100%. 100% is  essentially the width of the viewport. So if you put the left attribute 100%, it's going  to put it right to the left of the viewport. Right is going to be, sorry, left is going  to be minus 100%. And that's how you do it. The problem if you do it this way, it's going  to work just fine. Okay. This is going to, when you change the class of a div, it's going  to put it to the right position. And because you also add the transition class, that thing  is going to be animated. So it's good because this is already CSS animation as opposed to  JavaScript animation. That is a progress. But this is not hardware accelerated. It's  going to work. And depending on your hardware, it may be pretty jerky. So here is the right  way of doing it to get hardware acceleration. You need to use a transform. And so it's essentially  very much the same thing. But instead of setting the left attribute, you transform the x coordinates.  So the first parameter of translate 3D is actually the x coordinate. And then the second  is y and the third is z. Okay. So when you do that, using translate 3D, automatically  will execute that transition on the GPU. Okay. The previous one is still doing it on the  CPU. So very small technique, but that is what's going to make it faster. That's going  to work on the desktop as well. So this was so common of a problem that I decided to write  a little library, a kind of a micro library that does just that. And so if you want to  get it, it's on my GitHub repository. It's called page slider. And it's very, very tiny.  But it does exactly what I just told you in an efficient hardware accelerated way. No,  for that you would probably have to use a polyfill and do some feature detection. I'm,  well, on Android, you don't really get hardware acceleration in the same way. So certainly  on older version of Android, it's not going to be hardware accelerated. But you still have  to optimize it where you can. And certainly on iOS, that's going to make a big difference.  It will work. It will work on Android. It will just not accelerate it. It's still going  to be on the CPU. All right. Now, we are getting into the subtle things, but still we need  to be really perfectionists if you want. So hide HTML behaviors in your application. And  we spoke about one which was the alert. So that's an HTML behavior. But there are more  subtle ones. Like this one. Have you ever tapped or pressed a link for a long time?  Let's try. Okay. And then you get that. That's the default iOS behavior when you long tap  a link. Hey, you seem interested in that link. Would you like to copy it? You want to open  it? No. No, no. For me, this is not a link. I happen to implement this as a link. But  for me, this is a list item. In an app, that's a list item. So please don't do that. Okay.  Because again, if someone sees that, first of all, that's super confusing. Because that's  really not what I expected. But again, you gave away that your application was not native.  So it doesn't have to be that way. A simple style that you define on the anchor element  will get rid of that. So now I can do this as long as I want. And it never, that little  pop-up is never going to show up. Now, you still see a little thing that doesn't look  right. That highlight is there. It's not something that I wanted. It's by default. You see, when  I tap, you get that highlight. And you don't want that. Maybe you want your own, but you  don't want that one. So there is another style that you can apply. And by the way, I will  make all these slides available because I see a lot of people taking pictures, which  is great. But if you go to my blog, you'll be able to go to slash NDC.PDF. And I'll put  all that in a PDF file for you. NDC.PDF, yeah. So now it's all gone. Okay. Now I can do what  I really wanted to do, but I don't have these HTML behaviors. Great. Now, we have just a  couple of minutes for the fun part of my presentation where I will really ask you. So we covered  a number of performance techniques already, you know, hardware acceleration, the click,  the 300 millisecond delay that you really want to avoid. But there are a couple of typical  problems that we have seen in applications. And I'll let you guess what they are. So what's  wrong with this code? So I need to display a list of states in the United States. Now,  you may not be familiar with that, but states in the United States don't change every day.  There are 50 of them. It has been like that for some time, I think. So what's wrong with  it based on that helpful piece of information? It's static data. You should never make that  call to the server. I mean, it's already bad, you know, but on a mobile device, that's criminal.  Okay. You should never make that call to the server. Yet, I see tons of stuff like you  have a full-blown SQL database available to you on this. Okay. Or maybe if it's not that  bit, it can go in local storage or whatever you want. This is another problem that I see  all the time. And if you add them up, that is what creates slow applications. What's  wrong with this one? Exactly. So if you didn't know it, this is essentially a query that  I'm executing on the DOM. And it looks like I'm trying to style and configure a bug button  in my header. So I'm, you know, adding a click handler. I changed the color, changed the text  decoration, and I set the href link. So I do four operations on that same button. But every  single time I query the DOM, it's like if every single time, you know, you wanted to  read a field of an employee, you would reexecute the same select statement. It's that bad.  Okay. So obviously, the right answer is to do something like that. You execute the query  only once. You put it in a variable. You can use the dollar sign as a convention to remind  you that it was a query on the DOM. But then you use that cached variable to do your business  on that, you know, on that button. This one is a little more subtle, but it's even worse.  So this is a view, some kind of a view, that I will instantiate multiple times. So I will  create multiple objects because it's an employee view. Every time I need to display an employee,  I will display, I will instantiate that view. I see that all the time as well. This is really  bad. It has a big impact on performance. What's wrong with this one? Exactly. I have that  template there. It's a handlebars template. And it doesn't matter which technology you  use, with templating technology. In the initialize of the employee view, so that's going to be  executed every single time, I recompile the template. The process of compiling a template  is typically to create a function that you can pass an argument to do the model merging.  There is absolutely no reason for that. You should compile it once and not every single  time you create an instance. So when people start using templates, I see that a lot and  that's not good. So a solution to that is maybe to pass the, to inject if you want, that's  a kind of dependency injection, to inject, I don't know how to say it, in another way,  to inject the compile template into the view and you're all set. You don't recompile the  template all the time. This one. So I have a screen there with a bunch of icons. And  I displayed these different icons. You see these are different images. See that all the  time too. Exactly. So this is what? Seven images. In other words, seven HTTP requests  to actually load these images. That's also kind of criminal, right? It shouldn't be that  way. So what's the solution to use a sprite, which essentially is one big image with all  your icons in this case, right? And you use that image as the background. You create a  little viewport, you know, maybe 18 by 18, which is the size of an icon. And then you  offset the background to display the icon that you really want to display. Makes a big,  big difference. In fact, that application that I was showing you before, and again,  I hope that I get that guy to run fast for you, come on. Okay. That's not bad. This  is using a CSS sprite. This game is built using DOM. It's not Canvas at all. It's entirely  DOM. And so basically, that's an image. Now, try to do the same thing by swapping the image.  That guy is going to, you know, take his time. The only way to make him run fast, and again,  you need to see it on my iPad, is to use a CSS sprite and to offset the background. That's  the only way you can get to that level of performance. We are almost done. That one,  I also like a lot because this is something you don't really think about during development,  but that can become a big problem in production. So I need to display an employee. So in this  case, again, I have no choice. The data is on the server. So I need to go to the server,  get the data. And then, of course, it's an asynchronous call. So when I get the product  back, it's a product in this case, then I display the view. I display the product. So imagine I  have a list of product. I click one, and then that code runs. It's very possible that for two or  three seconds, nothing is going to happen. So I'm going to tap that thing and like, what's going  on? I don't see anything. Why? Because I'm not changing the view. I'm not displaying the view  until I get the data back. So the rule is don't wait for the data to display the view because if  you wait for the data, you know, people can wait for data. If you display the right, you know,  visual queue if you want, that's fine. But people don't wait for the UI. As soon as you tap, you  should move to the product detail view, and then it's empty initially, and then you update the  view. So you do something. It's here, but, okay, whoops. Okay, here we go. You display the view,  you make the request, you update the view. And the very last one, and probably the most important  one because that's one that people don't think about and has very dramatic impact on the performance.  By the way, most of these techniques are not specific to phone gap applications. It's basically  web performance techniques at this point. But this one is very, very, very important. What's  wrong with that code? Yeah, so it looks like I need to display a list. How many times am I going  to relay out that document just to display that list? I'm going to do 100 relay outs on that document,  which is crazy because relay out is probably one of the slowest operations performed by a browser.  And here, for absolutely no reason, I'm doing that 100 times because obviously the only thing  the user is interested in is the final list, right? And that's still the only thing the user is  actually going to see. Okay, so what's the solution to this? Yeah, exactly. And again, think about it.  So this is one simple way of solving that problem. You build a string, and then at the end,  one DOM operation, so one relay out versus a 100 relay out. You would be amazed if you go through  your code at the difference that this is going to make to your application. And that's really what  I wanted to tell you. So let's quickly summarize. Use single page applications, use templates,  handle bar JS is a really good one if you don't know what to use. Use some kind of MVC architecture  framework. I told you my personal preference for build your own stack as opposed to the full  stack frameworks, even though they have a place to abstract data access, abstract device features,  specifically touch events. Don't get that 300 milliseconds delay, please. I don't want to see  those hardware accelerations, these subtle HTML behaviors, and then architect for performance.  That's all the time we have. I'll be around if you have additional questions. Thank you very much.
Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_0_1655.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_1656_2651.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_2652_2903.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_2904_2951.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_2952_2999.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_3000_3047.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_3048_3095.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_3096_4355.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_4356_8951.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_8952_10175.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_10176_11807.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_11808_14675.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_14676_23339.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_23340_24875.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_24876_26171.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_26172_26291.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_26292_26363.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_26364_26663.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_26664_26891.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_26892_26987.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_26988_27251.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_27252_27299.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_27300_28259.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_28260_28307.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_28308_28811.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_28812_28907.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_28908_28955.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_28956_29291.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_29292_29339.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_29340_29387.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_29388_29447.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_29448_29495.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_29496_29963.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_29964_31631.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_31632_32591.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_32592_40019.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_40020_40139.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_40140_41207.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_41208_42059.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_42060_42119.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_42120_42611.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_42612_44435.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_44436_49475.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_49476_51779.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_51780_52115.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_52116_53555.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_53556_54131.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_54132_54203.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_54204_54299.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_54300_54347.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_54348_54395.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_54396_57527.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_57528_61343.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_61344_61715.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_61716_71279.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71280_71327.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71328_71411.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71412_71459.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71460_71531.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71532_71579.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71580_71627.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71628_71675.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71676_71723.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71724_71771.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71772_71831.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71832_71879.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71880_71927.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71928_71975.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_71976_72059.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_72060_72119.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_72120_72191.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_72192_74687.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_74688_90575.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90576_90647.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90648_90695.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90696_90743.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90744_90791.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90792_90839.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90840_90887.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90888_90935.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90936_90983.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_90984_91523.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_91524_91571.png Christophe_Coenraets_-_Architecting_PhoneGap_Applications-68334906_91572_97580.png
Okay. Yes. Okay. I think it's working. Good afternoon, everybody. And thank you for coming so late. I know I'm the only person now between you and the party, so I'll try to keep you awake. My name is Christophe Conrad. I work with Adobe. I'm based in Boston. I work with the PhoneGap team, and what I'd like to do with you today is to kind of take you through my experiences working with developers like you who build PhoneGap applications. So a lot of I'm going to show you a number of examples. So that's why I put my GitHub repository there. Sorry about the last name. That's the difficult part of this session. But most of the examples that you will see today are on that GitHub repository. On my blog, too, I blog a lot about PhoneGap, so you can find a lot of interesting information there as well. So what I decided to do was to try to do a top ten to keep it kind of lively. You know, top ten architectural principles. Some of them will be geeky, but a lot of them, as you will see, will be common sense. But for some reason, when we move to a new platform, sometimes we tend to forget what we learned in the previous language. And I'll try to remind you that you can actually apply some of the same principles when you build an application with PhoneGap. But before I do that, I always like to come back home with a little souvenir of my audience. So I need to know a little bit more about you. But the first thing I will do is this. I'm going to take a picture of you if that's okay. Let's see. All right. Let's do it. All right. And let's bring it back there. I think that's fine. I'll use Photoshop to add a few more people, but I think that will be fine. Which brings up a good question. What am I using here to do this presentation? What technology, what, you know, presentation technology am I using to do this? Am I using PowerPoint? Am I using Keynote? I'm using PhoneGap. Yes. So what you see here is actually a PhoneGap application. And I thought it would be useful to build it that way because then I will be able to show you stuff inside a presentation without doing the usual back and forth between my device and then the computer. So let's see if this works. Okay. So let's get started. So native applications are cool. And at Adobe, for instance, we build a lot of native applications. Like, for instance, if you use Photoshop on your device, this is not an HTML application. It's a native application. It makes a lot of sense because what we're doing in Photoshop is manipulating a crazy amount of pixels and it's very, very heavy. And native applications make total sense for that. However, we have also a lot of applications built with HTML because it makes sense when it's not crazy intensive like Photoshop, it makes sense to use an abstraction layer. And you all know that there is an abstraction layer that exists out there and that's essentially the WebStack. So HTML, JavaScript and CSS. And when you build with that, you can actually target all these different platforms. Some of them you may not be aware of. I finally found a bad developer the other day in Montreal. I was told that most of them are in Korea because it's a Samsung thing. But there are new platforms coming too. Like, for instance, the Mozilla phones with Firefox OS, Tizen, and there are, seems like every day there will be a new platform. And the nice thing about the WebStack is that you can build and deliver to all these platforms through the browser. Now, I don't know if any of you has ever tried to take index.html and submit it to the Apple App Store. They are not going to take that. So your delivery mechanism is really the browser. And that was really the initial idea behind PhoneGap. We said, okay, we love that platform so much and we are so close to being able to build apps with it that we're going to try to fill that gap if you want and to enable the development of apps. So something that you can actually deliver through the different app stores and things like that. So basically what we did initially was create a very thin, a very lightweight shell, a native shell that's simply wrapping your web app. So if you look at this, this is essentially 99% HTML, JavaScript, and CSS and 1% native. And the good news is even that native piece, we give it to you, that's essentially what PhoneGap is. It's a wrapper. But if you do that, your application may still not be interesting. And to be honest with you, Apple may still reject it. There is an item in the licensing agreement that if all your application is, is essentially a web app that you wrap, please deploy it through the browser. We are not going to take these applications. So they really want you to use the features that are available on your device. And so that's really the second component of PhoneGap. PhoneGap is a bridge. It gives you a consistent JavaScript API to all the cool features that you have on your phone, the GPS, the accelerometer, the camera, the contacts, you name it. And it's always the same JavaScript API. In other words, when you develop that application, you don't have to, you know, if iOS, then this JavaScript API, else if Android, then this JavaScript API, no, it's always the same thing. And we do the bindings if you do behind the scenes. So that's the second piece of PhoneGap. And if you know that, you know everything about PhoneGap. PhoneGap is nothing else, and that is by design. It's just a wrapper and a bridge, a wrapper for your web app. So now let's get into the real topic of this talk. Because it's a web app, a lot of people say, okay, I know how to develop web apps. We've been developing web apps for 15 years. I know how to do it. And then they get in trouble. And really what I want to do with you is to try to make sure that you don't get in trouble. So this is how people have been building web apps in the past. That's the old school architecture if you want. And you may recognize that you may have some version of that inside your company. That's a sitemap, right? And that's kind of your web app or your website. And behind each of these boxes, there is a little piece of PHP, JSP, ASP, Ruby on Rails or whatever. At the server side, that's going to generate a piece of UI, a piece of HTML that you then send back to the client and the client will render that HTML. So in other words, if I was to build, if that gets confusing, if I was to build a mobile application with that architecture, it would look something like this. So this is an employee directory application. You see that I work for an interesting company here. If I click one of these guys, it would do something similar to that. It would say, oh, okay, I need to display the details of that specific employee, Dwight. So I'm going to go ask my PHP server or ASP or whatever to give me that page. Is that good? Do you think you want to do that? And I'm saying that because I know you guys are super smart, but some people actually start this way. And then they say, hey, I can't use phone gap, it's too slow. But what happens here has nothing to do with phone gap, obviously. What happens is that you ask the server to generate your UI. And obviously, there is the network latency. There is, you know, if you're in the subway, it's going to take three seconds. On the web in a browser, people are used to wait two seconds. On the mobile app, not at all. They will totally trash your application if they have to wait half a second. So that is simply not acceptable. Okay? And the second thing that's probably not acceptable is that if you rely on the server to generate the UI, what do you lose that's expected from a mobile app? Offline, right? If you rely on a server and the server is not there, your app doesn't work at all. So even though you can build a phone gap application this way, the old way of, you know, web architecture, it's really, really, really not recommended to build it that way. And so the new school is to use what we call a single-page application. And a single-page application is essentially this. You have one and only one HTML page in your entire application. And then you will use JavaScript to create, to generate the UI at the client side, entirely in JavaScript. And you will create views in JavaScript at the client side that you will inject in that DOM. And when you don't need that view, you remove it from the DOM and you inject the next view. Okay? So you create the UI entirely at the client side in JavaScript. I'll get used to it. Okay. So some of the key differences here, obviously, compared to, you know, multi-page, you have only one page. The UI generation tier is client-side. It happens in JavaScript. It fully supports offline. You are fully in charge of the page transitions. If you ask the browser to go get the next page, the browser will be responsible for displaying it. And how will the browser do that? Boom, by simply replacing the existing page, forget the nice transitions that people expect. The major problem is that it's going to be slow. And another reason for that is that if on each page you load libraries and CSS files and stuff like that, it will have to be reloaded every single time. Obviously, in the single-page approach, because there is only one page, it's only reloaded once. So the number one principle is that even though for traditional web apps that you run, you know, on a traditional computer, single-page applications may or may not be a good fit for mobile applications, especially phone-gap apps, so not something that you run inside the browser, they are a must. You really need, if you want performance, you really need to do it this way. Okay? So the number one principle is use a single-page application. Now, there are many benefits, and we talked about them on the previous slide. There are also some downsides, because if you think about it the old way was really simple. Your unit of work was a page. And what can go wrong in a page? Can you have, let's say, memory leaks in a page? You know, the lifecycle of a page, you know, you displayed, the user is going to click something, and the page goes away. So the likelihood that you will experience a memory leak in that very small unit of work, it's very unlikely. However, with a single-page application, you never leave that page. It's always the same DOM. So now you really need to be careful about what you do, because I may actually spend eight hours in the same DOM, and remember, I will inject views, remove views from the DOM, so we'll speak about that in this presentation. All right, so how do you do it? How do you build a UI in JavaScript? Well, you know, it's HTML, so you know how to generate HTML. So if I need to create a view to display the details of an employee, I may do something like that. I create a string where I concatenate, markup, and then the model, you know, some data, and then I will render that. I will inject that fragment into the DOM. How do you guys like that? Beautiful code, easy to write, easy to maintain. You don't even have to use an HTML editor anymore, because it's totally useless, because of course, you can't get code hinting and stuff like that if you ever wanted to do that. You can't delegate the views to a designer, which these days is part of the workflow, because your designer is never going to write that code, obviously. So that is something that you shouldn't do. Instead, a better approach is to use templates. Now, I don't know if some of you are as old as I am and remember 16, 17 years ago how it started at the server side, it started the exact same way. I wrote that code in C and C++, and it was called CGI programming, and that's how you kind of generated dynamic web pages initially. And then people said, oh, that's crazy. You know, it's just not flexible enough, and we have to recompile all the time. Let's create templating engines or servers, and that's how PHP, JSP, Sqlfusion, all these solutions to that problem came about. Well we are solving the exact same problem here at the client side now. There are a lot of templating engines. And so the number two principle, the second rule, if you want, is that you absolutely need to do it that way. Otherwise, if you build anything more than a trivial application, you know, it's going to be a big mess. And so what should you use? There are many, many options, just like at the server side. Handlebars, JS, Mustache, JS, DustJS, if you use Backblown, we'll speak about frameworks in a second. Underscore.js is a kind of a multi-purpose library, but it also has support for templates. All right, so let's move on to this, which is something that I often see when I have to debug an existing PhoneGap application. I, you know, I try to debug it on my computer. And what's wrong here, oftentimes when I ask what's wrong, people tell me you have IE on your iPad that doesn't look right. So it's just, you know, to kind of give you the idea. What's wrong if this code is not minified is that there is a problem and the problem is happening online 3,000 something. And unless, of course, this code has been concatenated and minified, that indicates that your code is a big mess, okay? And I see that a lot because people start with JavaScript and, you know, the new JavaScript from the old days where you just kept adding functions to main.js. And that's essentially what happens at that point. So the third principle is really to think about it in a different way and very much like you talked about your code in another language and really provide structure to that code. And use some kind of an MV something, you know, architecture. And I put a star there because some people are religiously attached to MVC or MVVM. They are all different flavors of the core principle is that you should really partition your code. And that may be by creating model classes. And this is just, this is not like the way of doing it. You know, this is using a constructor pattern. You may want to use a module pattern. I don't really care at this point. I care that you partition your code. And let me actually go into some examples. I told you so, you know, some of the applications that I'm going to show you. So on the iPad, we're going to build something like this even though this is more of a phone layout. So this is the application that we are working on. And I want to show you some of the pieces. So first of all, principle number two was that, you know, you should work with templates. And so these are some examples of templates. The nice thing about templates is that at the end of the day, they are HTML. So you are back to, you know, HTML and then a bunch of placeholders. So like for instance, and this is using underscore JS. So that's the syntax. The most common syntax is the double curly. But underscore uses kind of a JSP syntax. And that's basically a placeholder simply saying, okay, at some point, I will merge my model into this and you will, you know, do the right thing. Okay. So now, so that's all of the templates. Now, let me show you some examples of views because it's all about, as I said, organizing your code here. So this is an example of a view. This is using actually backbone, but it doesn't really matter. The important thing is that we have a view here, a view object that we can instantiate if you want. And the way we render the view, so, you know, views typically will have a lifecycle and one of the methods of the lifecycle is going to be to render the view. And the interesting thing here is that you don't see any concatenated HTML code. The other thing we do is to actually invoke the template function and pass the model into it so that the template engine can do the merging like we expected. So you see that essentially I'll have, you know, this kind of object for each view in my application. And then I will also have models and in backbone, I created different models here. Models would be classes or objects that are responsible for managing the data. They don't know anything about the view. So that's, you know, a first rule of partitioning. And so that's kind of the way you start structuring your application. And we'll come back to that code in just one second. So you have models, you have views. And again, this is just sample code depending on whether you're using a framework or not, you know, it will be different. And then you can come up with your own approach. This is a controller and we'll speak about that one in a second. It's kind of a data adapter. I will speak about that specifically later in this presentation. Okay. So provide structure, use an MVC type of architecture. Now, before you go do that and try to reinvent the wheel, the fact is there are many, many, many smart people who have been thinking about this for a number of years now and came up with some frameworks. So before you create your own frameworks, I don't think the world needs, you know, additional JavaScript frameworks at this point, even though they keep coming. Consider using a framework. But consume responsibly, as always, because frameworks can be really easy. You know, there was one way of doing it with PhoneGap. PhoneGap is completely agnostic. As long as you have a web app, we'll happily package it and bridge it. We didn't want to say, hey, we would rather, you know, that you use that framework. That's really not what we wanted. But we saw a lot of people getting trouble. And so now I'm going to be just slightly a little bit more, you know, specific about what I think is good and what I think is bad. So the way we look at frameworks, and I don't think it's very controversial, is that there are really two categories of frameworks. On the left, you see what we call full stack frameworks. These are frameworks that try to solve all the problems in a web application. Some DOM manipulation, so how you access the different DOM elements to architectural concerns, so really provide that MVC type of structure. And then on top of that, make your application look good. So these frameworks typically come with a bunch of UI components, styles, themes, and that kind of stuff. So they cover the whole stack. In that category, you have Sencha, jQuery mobile, for instance, and Dojo, and they may be additional ones. Now, this is great because it's a one-stop shopping type of approach. You don't have to kind of make sure that all the pieces work together because hopefully, you know, the creators of these frameworks do that for you. The DOM side is obviously that it can be very heavy, and that in order to use one piece, you may have to embrace a lot of other things that you don't necessarily like. And a good example of that, there are a lot of people who start with phone gap using jQuery mobile. And I asked them, well, why did you choose jQuery mobile? And they said, well, it came with all these default components and the transitions and all that. I really needed that. So that's why I embraced jQuery mobile. Now, the problem, so basically, that person and there are many, was telling me, you know, I really liked what they have here in the UI layer, and therefore, I embraced everything else. Now, the DOM stuff is not a real problem. It's obviously jQuery core. But the real problem is the architectural stuff, which in jQuery mobile, you know, is you may like it and then it's fine, you can embrace it. But a lot of people are fighting it. And the only reason they keep fighting is to keep these UI components. So the other approach, if you are fighting it, don't use it essentially, and then build your own stack. And I have to say that these days, this is a more popular approach. And basically, in that case, you say, hey, for DOM manipulation, I'm not even going to use jQuery. Maybe I'll use Zepto because it's a clone in terms of syntax, but it's lighter weight because it doesn't care about old browsers. And when you build a map for mobile, you really don't care about old browsers. Or some people say, you know, jQuery was really helpful three years ago, but now you can pretty much do everything it does in plain JavaScript. So let's do that. Whatever seems right for you, you kind of pick your answer. Now, the big discussion is happening there in the middle in these micro architectural frameworks. You know, some people love backbone, some people love Angular, some people love Ember. And that's fine. You choose what you like because these frameworks are lightweight. I think certainly backbone is kind of the leaner, least directive type of framework. But even Angular, Ember, and Knockout are still reasonably sized. And you use that. And then on top of that, you may say, hey, I need to make my application look good. So I'm going to use a UI toolkit. Now, what you typically see in that category are toolkits, UI toolkits. I don't even call them frameworks because they don't do anything in that architectural box. They are typically 95% CSS. And if they are more than that, if they try to do stuff in the architectural layer, you shouldn't use them. Right? So you should really find one that focuses exclusively in that layer and that doesn't bleed on the other layers because that would mean it's not very well partitioned. Now, Twitter Bootstrap and Zurb Foundation are nice. They were not really created for mobile apps initially, even though they are adding components. Two good examples of UI toolkits would be Ratchet CSS and a new one that we are actually working on at Adobe called TopCode. So I'm going to show you TopCode. So this is basically why did we do that? Because one of the complaints that people had about PhoneGap was that it was too hard to build applications that looked good. And let's face it, initially, the initial adopters of PhoneGap were people like you and me, developers. And we are extremely good at writing code, but our skills are not necessarily great at coming up with great design and using the right gradient and the right text shadow and that kind of stuff. So we created apps that worked, but that looked terrible to kind of simplify. So people asked us, please, please, please help us there and give us some options. So this is really, really early and it's developed completely in the open. It's a GitHub project, an open source project. And it's 99.9% CSS. In fact, at this point, it's really 100% CSS. So you can still use the framework that you like and build the application the way you like. And we give you the themes and the skinning and stuff like that. So all these things, and that was the advantage of doing my presentation, really in a PhoneGap application, I can show you these components. There is a lot more to it. And you can go to topcode.io, which is the website, or you can go straight to the GitHub repository, get the code, and even, ideally, contribute to the code. Now, let me show you another example. So this one is actually Ratched CSS. Really, really simple and cool. And I like it a lot when I have to prototype, especially an iOS-looking type of application. Really consider Ratched CSS because, again, it focuses exclusively on that layer. It's very lightweight, very simple to use, and gives you a great look and feel out of the box. It looks a lot better, actually, on the phone because it was really built for that. The idea of Ratched is really iOS-specific. Topcode tries to be kind of a neutral theme. And if you follow the announcements on Monday, iOS 7 and all that, you will see that everybody is kind of going to a very flat, you know, Windows Phone-like, and even end the new versions of Android. And now iOS is very flat, no gradient, no kind of big Chrome stuff. It's really, you know, the content being king. And that's really the idea behind Topcode. All right. There's a little delay here. Okay. All right. So let's keep going in terms of architecture. And now I'll need your help because it's getting late for me, too. And I'll show you some code and you'll have to tell me what's wrong. Anybody wants to play that game with me? So this is something that I see a lot when I look at existing phone gap applications, and in fact, it doesn't have to be phone gap. I see this type of calls throughout the code. And think about maybe even the code that you write, hopefully not too much, but I see that really across the entire code base. And what's wrong with that? What's that? A bit chatty? No error and handling. You guys are really going into the details. But at a higher level, what is this? Well, because you may need data from the server. Yeah. Yeah. And we'll speak about that. Ideally, you'd love to never have to go to the server because it's going to be a lot faster. But sometimes, obviously, you need data from the server. But the question is interesting, though. This is obviously an Ajax call. And now throughout my application, I'm marrying myself to Ajax, right? And I'm saying, OK, well, so my data access strategy is Ajax. And it's really hard coded everywhere across many different components. Now, what if one day I decide that I don't want to do Ajax anymore, but I decide to be a lot more aggressive in terms of caching and try to go get data from a local database on the device as much as I can? Or what if I say, hey, isn't unit testing a good idea? And how granular can a unit test be if I have a server dependency? Does that really make sense? So this is not really good to be so specific about your data access strategy. So principle number five is that you really shouldn't do that. And you should abstract your data access strategy. Now, this is one of the common sense stuff that I told you about at the beginning of my talk, of course. And you have been doing that in other languages forever. But for some reason, when people go to PhoneGap, they are, Ajax, let's do it. Let's go. And you see that code all over the places. So here is what the same code roughly, and we may add, you know, error handling and that kind of stuff. But the same code at a high level should look something like this. Because if you read this code, you clearly have no idea at the end of the day, you know, how the data will be retrieved and from where? Okay, this is very generic. You have a data adapter that's going to do the trick behind the scenes. And basically the way you do that is by implementing a common interface. And you have then these pluggable adapters that implement the exact same interface. They all implement the same interface. And typically, I start, I always start with an in-memory adapter. Because that lets me really iterate super fast. What you should never do is wait for the server-side developer to, you know, build your big stack of RESTful services because then you kind of tie yourself to these services. I like to be very creative initially and say, okay, you know, let me come up with fake data because then I can really build the application that I have in mind and then we'll solve that problem to get to the data. Now, I know that it's a little bit backwards compared to what we've been doing, you know, the last 15 years where we started at the server-side. But now, people understand the value of a good user interface or user experience. So I typically start with that. I have a WebSQL adapter because that's still what iOS supports more than index DB. I may have a local storage adapter. And of course, I may have an Ajax adapter. And the benefit of this, for instance, if I say, you know what, the data that I used to get through Ajax, now I really want to get them from my local database, I can just unplug one adapter, plug the other one, and I'm done. Okay? So let me show you a few examples of that. So I'm going to start with those ones here. Again, there are different ways to implement them. I'm going to start with a very simple one. Again, implement it as an object, as a constructor, essentially. But so that's to get, you know, data about an employee. And so I called it JSON adapter. And basically, it defines an API. There is an initialized method in case I need to. If it was a database, maybe I need to open the database or do something of that nature. But most importantly, the real API is defined by ID, defined by name, and you go on, find no, find by manager, et cetera, et cetera. Now, the implementation of that here, of that adapter, is to indeed make an Ajax call. Okay? So I don't make my code a lot more complicated. In fact, I think it's cleaner. But the benefit is that now, if these services are not ready, I can go to this guy. And start with that. So this is my memory adapter. And you see how simple that is. I create dummy data, in this case, in an array. And then I implement the exact same interface. Okay? And you can go on and on and on. So I have here a WebSQL adapter. And you recognize your old friend SQL there. But again, inside the exact same API. Okay? Find by ID, find by name. And in there, I do some SQL. Okay? And now I can really plug and play these different adapters. Now, let's go back to the memory adapter. So it seems simple enough. It's even simpler than in other languages because you don't have to formally define an interface and all that. But, well, actually, let's go back to the JSON. Obviously, the methods have to be to have the same name. But that's not enough because what is an Ajax call returning? Obviously, I'm using jQuery here to make my Ajax call. What does it return? What do I get back from an Ajax call? A promise. So essentially, an Ajax call is asynchronous. So to make the plug and play thing work, not only do your methods have to have the same name, but they have to be invoked the same way. Because if one, you know, define by ID in my Ajax adapter returns a promise, so is asynchronous, essentially. And my in-memory adapter is synchronous, then it's not going to be plug and play, right? Because I'm going to have to invoke the methods in different ways. Which is why you notice that when I look at my in-memory adapter, I create, this is the jQuery implementation of that, I create a deferred object that I resolve immediately, okay? But the call is still going to be asynchronous. And indeed, the method returns a promise, the promise of that deferred object. And now, even though this is clearly, this can clearly work synchronously because all the operations are synchronous, but I provide that object with an asynchronous interface so it matches, you know, my Ajax adapter, which obviously is going to be important. So that's the little trick. You need to make sure that, you know, not only they have the same name, but they work the same way, they are all asynchronous. Okay. This one is really interesting, too, and I see a lot of issues with that, too. So abstract device features, which also means keep your application browser-runnable. So what do I mean by that? Okay, let's take an example. So there is a button there that says show notifications. So let's press that button. Let's press that button. Okay. How do you like this? You like it? Because I'm nice. I agree to you. But what can you immediately say about this application? And I, it's not a big secret because I told you before, but what can you say about this application? It's HTML. You love the body of that message, but you don't really like the header because if you use a JavaScript alert, like many people do when they develop a phone-gap application, they will see index.html. And you just gave away the fact that your application is not native and that's confusing for users. You know, casual users, they'll say, what is that thing? I'm not in a browser. Okay. So you're going to say, okay, that's easy to solve because as I said, phone-gap gives you these bridging APIs. Okay. And one of the bridging APIs you can see there is basically a bridge to a native alert. Okay. So let's try that. Phew. Okay. It looks much better because now that looks, you know, you can put whatever you want in the title in the body and even on the button, I can now relax because it looks great. But if I use that now, the problem is that it doesn't run in the browser. And my rule was keep your application browser runnable. And the main reason for that is because you want to be able to debug it easily. Believe me, debugging on this, even though it's getting better, is not fun. Debugging on this using, you know, for instance, the Chrome developer tools, really good tools. So if I can keep debugging my application here, that will make me a lot happier. So don't just replace all your JavaScript alerts with that because that's one easy way to totally break your app inside the browser. So now you know the approach. We are going to do the exact same thing we did for data access. You're going to abstract it one way or another. You're going to have some kind of a notification interface. Okay. So kind of the exact same way if you want. And so this is not the only thing that you need to abstract. So we spoke about notification. We spoke about storage with the data adapters, the sensors. So sensors are everything essentially that you can do with that thing, like access the GPS, the accelerometer, the compass. So these are all sensors that are available here, but not necessarily here. It's coming, but right now a lot of them are still not available here. So just don't just assume that you can invoke these things because again you break the rule, keep your application browser runnable and debugging is not going to work anymore. Now the last one is so interesting that I'm going to spend one specific item on that. You need to abstract the user interactions with your application because obviously if I work on this, this is mostly going to be through touch. If I work on this, at least the machine that I have, it's mostly going to be through the mouse and the keyboard. So principle number seven is that you really, really need to handle touch. Just don't ignore it like I see so many people do. So let me show you one way people ignore touch and simply do mouse because guess what? For developers who are not interested in the finest experience, mouse events actually work as touch events. In other words, if you use a click event and then tap with your finger, it's going to work. Not well, but it's going to work. And I see probably in over 50% of applications that I look at, people don't bother. They use these mouse events. And so what happens, for instance, so here is an example of what happens. So I have a list of items that I can select. I can tap. So let's do that. I'm going to select one. See the problem? So let's do it again. Before the event even reaches the application, it takes over 300 milliseconds. That's 300 milliseconds that I have no control over. My application has no control over. This is the OS. And why? Because the OS is wondering if you're going to mean double click. So it says, if after 300 milliseconds you didn't tap a second time, I'm pretty sure it's a click unless you're really, really slow. So at that point, I'm going to send a click event to your application. Now you may say, come on, 300 milliseconds. Who cares? People care a lot. On mobile, if it's not immediate, people reject your app and will say, hey, this doesn't feel native. It doesn't have to be that way. A lot of people say, look, phone, it's slow. Look. It doesn't react. That's what people who don't like hybrid applications, they will enjoy doing that kind of stuff to prove you wrong. But it doesn't have to be that way. So let me show you the exact same list. And I'm going to do this. Now you see basically what's happening. I'm using touch start here, which is triggered right away, two, three, four, or five milliseconds. Whereas my click event is still struggling because it's waiting to be triggered by the operating system wondering if it's a double click or not. So you say, great. That seems pretty simple. I'm just going to do a global fine and replace of all my click events by touch start. Now what happens if you do that, you break my other rule, which is that nothing is going to work here now. And I wish it could be as simple as that, but it's not only about tap events. Sometimes it's not only about touch start. Sometimes you have composite events like, okay, I want to swipe. And so if you just use touch start throughout, you're going to be in trouble and you're going to break a bunch of stuff. So basically what you have to do is say, okay, well, you do feature detection. You say, well, if touch start is available, I'm going to use that. If not, I'm assuming that you use some machine like this. And I'm going to register a click event. So that's pretty messy code, right? To kind of have to do feature detection at that level. So before you write that code, again, there are libraries that will do that for you automatically. And a really good one is called Fast Click. And basically, Fast Click is a drop-in library. You basically just add the script tag and magically it's going to do exactly what I said. So you keep coding essentially your click events, but Fast Click is going to hijack your click event and see, okay, is touch available on this device? If yes, I'm going to replace your click event by a touch event. Okay? So it's not the only one, but again, that's actually a pretty good option. Yeah. Well, so Fast Click doesn't, you know, does the right thing. Swipe is still going to work. In fact, I'm using Fast Click in this application and you see that I can still swipe. So that's the beauty of it, because handling that code can be really complex. So before you venture into that, you know, problem, look at Fast Click. Another good one is called Hammer.js. Also handles all the touch events really nicely. So these are libraries that have been tested in the field and we know they work. Okay. So number eight, we're getting there. Another reason a phone gap application may not deliver the best performance is when you don't use hardware acceleration. Now, let me kind of a mental break here. Show you one example and this one I will show it to you back later. So this is a prototype of a game. Okay. So you don't see anything. Okay. Oh, yes. Okay. So there is a, you know, you don't have the best experience because I'm streaming my screen, but hopefully you can see that this guy is running pretty fast, but it's super smooth on my screen here. You can come and check at the end of the session. So you need to use hardware acceleration. The place you typically see it immediately is when people, you know, slide pages and it looks jerky. It doesn't look like the smooth native experience. You need to hardware accelerate these transitions. Don't use jQuery transitions to do this. Don't do these transitions in JavaScript. Essentially, don't do them on the CPU. You need to execute these transitions on the GPU. Okay. So here is a typical setup. Don't worry. The screens are not going to bleed out of your screen. This is just my way of trying to represent that. A typical setup is to basically, when you're going to slide a view from the right to the center, you position it immediately to the right of the viewport of your WebView. Okay. And there is a, you define a CSS class that typically I call right to say, okay, this one is to the right of the viewport. The other one has the class left which positions it to the left of the viewport. And essentially, if I want to move the blue one to the center, I will press that button here. And you see it was nicely animated. The only thing I did was to essentially change the class name to center. If I want to put it back, to put it back to the right, I do that. If I want to move that one. And you see, I hope we don't lose too much, I'm sorry, I hope we don't lose too much of responsiveness through the streaming. It's pretty snappy. Okay. So how does it work and how do you do it right? So typically, people will start this way. They will say, okay, I got it, you know, to the right, I'm going to position it. I'm going to put the position, the left style to 100%. 100% is essentially the width of the viewport. So if you put the left attribute 100%, it's going to put it right to the left of the viewport. Right is going to be, sorry, left is going to be minus 100%. And that's how you do it. The problem if you do it this way, it's going to work just fine. Okay. This is going to, when you change the class of a div, it's going to put it to the right position. And because you also add the transition class, that thing is going to be animated. So it's good because this is already CSS animation as opposed to JavaScript animation. That is a progress. But this is not hardware accelerated. It's going to work. And depending on your hardware, it may be pretty jerky. So here is the right way of doing it to get hardware acceleration. You need to use a transform. And so it's essentially very much the same thing. But instead of setting the left attribute, you transform the x coordinates. So the first parameter of translate 3D is actually the x coordinate. And then the second is y and the third is z. Okay. So when you do that, using translate 3D, automatically will execute that transition on the GPU. Okay. The previous one is still doing it on the CPU. So very small technique, but that is what's going to make it faster. That's going to work on the desktop as well. So this was so common of a problem that I decided to write a little library, a kind of a micro library that does just that. And so if you want to get it, it's on my GitHub repository. It's called page slider. And it's very, very tiny. But it does exactly what I just told you in an efficient hardware accelerated way. No, for that you would probably have to use a polyfill and do some feature detection. I'm, well, on Android, you don't really get hardware acceleration in the same way. So certainly on older version of Android, it's not going to be hardware accelerated. But you still have to optimize it where you can. And certainly on iOS, that's going to make a big difference. It will work. It will work on Android. It will just not accelerate it. It's still going to be on the CPU. All right. Now, we are getting into the subtle things, but still we need to be really perfectionists if you want. So hide HTML behaviors in your application. And we spoke about one which was the alert. So that's an HTML behavior. But there are more subtle ones. Like this one. Have you ever tapped or pressed a link for a long time? Let's try. Okay. And then you get that. That's the default iOS behavior when you long tap a link. Hey, you seem interested in that link. Would you like to copy it? You want to open it? No. No, no. For me, this is not a link. I happen to implement this as a link. But for me, this is a list item. In an app, that's a list item. So please don't do that. Okay. Because again, if someone sees that, first of all, that's super confusing. Because that's really not what I expected. But again, you gave away that your application was not native. So it doesn't have to be that way. A simple style that you define on the anchor element will get rid of that. So now I can do this as long as I want. And it never, that little pop-up is never going to show up. Now, you still see a little thing that doesn't look right. That highlight is there. It's not something that I wanted. It's by default. You see, when I tap, you get that highlight. And you don't want that. Maybe you want your own, but you don't want that one. So there is another style that you can apply. And by the way, I will make all these slides available because I see a lot of people taking pictures, which is great. But if you go to my blog, you'll be able to go to slash NDC.PDF. And I'll put all that in a PDF file for you. NDC.PDF, yeah. So now it's all gone. Okay. Now I can do what I really wanted to do, but I don't have these HTML behaviors. Great. Now, we have just a couple of minutes for the fun part of my presentation where I will really ask you. So we covered a number of performance techniques already, you know, hardware acceleration, the click, the 300 millisecond delay that you really want to avoid. But there are a couple of typical problems that we have seen in applications. And I'll let you guess what they are. So what's wrong with this code? So I need to display a list of states in the United States. Now, you may not be familiar with that, but states in the United States don't change every day. There are 50 of them. It has been like that for some time, I think. So what's wrong with it based on that helpful piece of information? It's static data. You should never make that call to the server. I mean, it's already bad, you know, but on a mobile device, that's criminal. Okay. You should never make that call to the server. Yet, I see tons of stuff like you have a full-blown SQL database available to you on this. Okay. Or maybe if it's not that bit, it can go in local storage or whatever you want. This is another problem that I see all the time. And if you add them up, that is what creates slow applications. What's wrong with this one? Exactly. So if you didn't know it, this is essentially a query that I'm executing on the DOM. And it looks like I'm trying to style and configure a bug button in my header. So I'm, you know, adding a click handler. I changed the color, changed the text decoration, and I set the href link. So I do four operations on that same button. But every single time I query the DOM, it's like if every single time, you know, you wanted to read a field of an employee, you would reexecute the same select statement. It's that bad. Okay. So obviously, the right answer is to do something like that. You execute the query only once. You put it in a variable. You can use the dollar sign as a convention to remind you that it was a query on the DOM. But then you use that cached variable to do your business on that, you know, on that button. This one is a little more subtle, but it's even worse. So this is a view, some kind of a view, that I will instantiate multiple times. So I will create multiple objects because it's an employee view. Every time I need to display an employee, I will display, I will instantiate that view. I see that all the time as well. This is really bad. It has a big impact on performance. What's wrong with this one? Exactly. I have that template there. It's a handlebars template. And it doesn't matter which technology you use, with templating technology. In the initialize of the employee view, so that's going to be executed every single time, I recompile the template. The process of compiling a template is typically to create a function that you can pass an argument to do the model merging. There is absolutely no reason for that. You should compile it once and not every single time you create an instance. So when people start using templates, I see that a lot and that's not good. So a solution to that is maybe to pass the, to inject if you want, that's a kind of dependency injection, to inject, I don't know how to say it, in another way, to inject the compile template into the view and you're all set. You don't recompile the template all the time. This one. So I have a screen there with a bunch of icons. And I displayed these different icons. You see these are different images. See that all the time too. Exactly. So this is what? Seven images. In other words, seven HTTP requests to actually load these images. That's also kind of criminal, right? It shouldn't be that way. So what's the solution to use a sprite, which essentially is one big image with all your icons in this case, right? And you use that image as the background. You create a little viewport, you know, maybe 18 by 18, which is the size of an icon. And then you offset the background to display the icon that you really want to display. Makes a big, big difference. In fact, that application that I was showing you before, and again, I hope that I get that guy to run fast for you, come on. Okay. That's not bad. This is using a CSS sprite. This game is built using DOM. It's not Canvas at all. It's entirely DOM. And so basically, that's an image. Now, try to do the same thing by swapping the image. That guy is going to, you know, take his time. The only way to make him run fast, and again, you need to see it on my iPad, is to use a CSS sprite and to offset the background. That's the only way you can get to that level of performance. We are almost done. That one, I also like a lot because this is something you don't really think about during development, but that can become a big problem in production. So I need to display an employee. So in this case, again, I have no choice. The data is on the server. So I need to go to the server, get the data. And then, of course, it's an asynchronous call. So when I get the product back, it's a product in this case, then I display the view. I display the product. So imagine I have a list of product. I click one, and then that code runs. It's very possible that for two or three seconds, nothing is going to happen. So I'm going to tap that thing and like, what's going on? I don't see anything. Why? Because I'm not changing the view. I'm not displaying the view until I get the data back. So the rule is don't wait for the data to display the view because if you wait for the data, you know, people can wait for data. If you display the right, you know, visual queue if you want, that's fine. But people don't wait for the UI. As soon as you tap, you should move to the product detail view, and then it's empty initially, and then you update the view. So you do something. It's here, but, okay, whoops. Okay, here we go. You display the view, you make the request, you update the view. And the very last one, and probably the most important one because that's one that people don't think about and has very dramatic impact on the performance. By the way, most of these techniques are not specific to phone gap applications. It's basically web performance techniques at this point. But this one is very, very, very important. What's wrong with that code? Yeah, so it looks like I need to display a list. How many times am I going to relay out that document just to display that list? I'm going to do 100 relay outs on that document, which is crazy because relay out is probably one of the slowest operations performed by a browser. And here, for absolutely no reason, I'm doing that 100 times because obviously the only thing the user is interested in is the final list, right? And that's still the only thing the user is actually going to see. Okay, so what's the solution to this? Yeah, exactly. And again, think about it. So this is one simple way of solving that problem. You build a string, and then at the end, one DOM operation, so one relay out versus a 100 relay out. You would be amazed if you go through your code at the difference that this is going to make to your application. And that's really what I wanted to tell you. So let's quickly summarize. Use single page applications, use templates, handle bar JS is a really good one if you don't know what to use. Use some kind of MVC architecture framework. I told you my personal preference for build your own stack as opposed to the full stack frameworks, even though they have a place to abstract data access, abstract device features, specifically touch events. Don't get that 300 milliseconds delay, please. I don't want to see those hardware accelerations, these subtle HTML behaviors, and then architect for performance. That's all the time we have. I'll be around if you have additional questions. Thank you very much.
That's the difficult part of this session. But you see here is actually a PhoneGap application. was to build a mobile application with that right? If you rely on a server and the server is way. Otherwise, if you build anything more than a just a couple of minutes for the fun part of my covered a number of performance techniques applications, use templates, handle bar JS is a