Architecting large Single Page Applications with Knockout.js
Sanderson, Steve
These days it's easy to get started building a Single Page Application (SPA). Dozens of frameworks are clamouring to pitch their trivial "hello world" and "todo list" examples. But the moment you step outside the predefined path and begin actually crafting something for a real business, you face an explosion of choices. This talk is about experiences of building large SPAs and maintaining them over time. In part, I'll demonstrate pros and cons of various technology choices, such as TypeScript, Grunt, and AMD module optimisers. In part, I'll demonstrate some Knockout.js-specific techniques, such as the new and powerful "components" feature that improves maintenance, testability, and runtime performance. Throughout, I'll share lessons learned from building and maintaining the core of the Windows Azure management portal, an exceptionally large and high-profile SPA whose various parts are developed by many different teams within Microsoft. I hope these experiences will prove useful when you build your next rich JavaScript application.
 All right then. I think I'll just kick off now. Is that okay? Yeah, ready to start? All right then. So, hello and thank you. Let me start my timer. Thank you for coming to this session. It's really great to see you all. Obviously, it's kind of weird looking up like that at you all, but I will try and maintain good eye contact and be a good presenter in this talk. My name is Steve and I, what do I do? I work for Microsoft. I work on lots of different web stuff for them and I started off this knockout project a few years ago and so that's why this subject matters to me. I work on single page applications. I've got a special interest in knockout, so it matters to me and I think it probably matters to a lot of people actually, the whole single page applications thing because maybe four years ago when we started knockout, people were not really building such massive single page applications. Typically, people were using knockout to do just a little bit of interactivity on a bigger page and that was quite straightforward and knockout solved that problem really well, but things have moved on enormously in a few years since then and now people are building these huge applications that stay in the screen for hours potentially as the user is navigating down around loads of different things without doing any server side page navigation and that presents a load of new challenges and I don't think that we've necessarily provided all that much in the way of examples and docs and such that cover those kind of scenarios. So hopefully I'm going to redress that balance a little bit today. Now then, I should warn you before we get started that sometimes people have said that my presentation style is a little bit like this to the audience and to be honest that's probably fair. It might well feel a bit like this from time to time, but I would just say to you don't worry about it. It's okay because I'm going to talk about lots of different things in this talk and I'll be changing subject like every five to ten minutes. So even if you get a bit lost, it's okay. You can pick it up again as soon as we move on to the next thing. Alright, so don't worry, chill out. Now I'm going to start off with a few slides. I will be doing mostly coding this talk, but I want to also, I want to communicate mostly ideas, concepts, challenges, solutions rather than just going like here's some code, here's some more code, here's some more code. So there will be a little bit of slides to start off with and I hope you'll find this valuable. So I just want to introduce some of the pros and cons of this single page application thing. I'll probably be talking about more about the cons than the pros because I think that's where there's more interesting stuff, but we will start with a bit of positivity. So what's positive about writing single page applications? Well, you know, why are we willing to give up on our 15 years of experience of doing server side page rendering? You know, are we mad? Why are we doing this? Well, you know, there's a few really key benefits and the chief among them is probably that we can produce the best user experience that can be delivered through a web browser. So we can produce applications that are just as responsive and nice to use or even more so than native desktop and mobile applications. But we're not writing native code, we're still writing cross platform code. And these two things together are the absolutely killer features of single page applications and this is pretty much the solid reason why you would be wanting to do this. And everything else is just a small benefit. But I'll just round it off a little bit. A few more smaller benefits are that as a developer, you can really just focus on the one technology. You can just get really good at your HTML and your JavaScript and your CSS and you don't have to spend half of your time doing that and half of it working with some almost unrelated server technology. So that can be nice for you. It also means that as you go further with this, you build more and more of your application that's able to run on the client without having that many server dependencies. And so if you use some kind of client side data store as well, you can even make your application work offline to some extent or at least work very responsively even in the presence of an intermittent network connection. So that's nice. And if you go really far with this and what you end up delivering is basically just static HTML and JavaScript files that talk to back end servers, then you can even deliver that around the world just by throwing it onto any static file host CDN type thing and you will get blazingly fast global distribution for basically no money whatsoever. So that's quite nice as well. But really, the two key things are the user experience and the cross flat formness. Now, my experience in this, I've worked on quite a few different single page applications, but this is the one I'm working on at the moment. How many of you have seen this or used it? Okay, wow, that's good, like a half of you. Right, so this is the new Microsoft Azure Management Portal. And this is a very, very large single page application. And it's quite advanced in many ways. It's got quite an advanced user experience. The user navigates around through these different blades that open up and they can slide back to where they came from. And this is really giving desktop applications a run for their money. I think you wouldn't even expect to do something as good as this in a desktop app. And it's got many other advanced features as well. Obviously, it's pulling in data from many, many, probably hundreds of back end servers to provide all the information about what's going on in your cloud services. And the user can even do things like customize the UI. So for example, here, they're going to pin this file system storage graph onto the home screen there. And then they could go along and say, hmm, I also want to keep an eye on the number of HTTP requests. So I'll pin that to my start board as well. And then maybe they want to customize it a little bit more by resizing things and moving them around. Maybe they don't actually need that giant map that serves no purpose, but just looks pretty for demos. So they're going to make that get a lot smaller and move it away and so on. And as you can imagine, this is a big, big project. We've got dozens of teams in Microsoft contributing code into this thing. So it's kind of massive. And we needed an architecture that was really going to scale very well, both in terms of allowing lots of developers who don't really understand it to contribute good code to it, but also in terms of providing really great performance for the end user. So we're not shipping too much code, and we're being efficient about all aspects of the delivery there. So that's what I'm working on at the moment. And after my experience of working on that, would I say that it's easy to build a single page application? No. I would not say it is easy. I would say it can be very challenging compared with many other types of architectural patterns that you could try and follow. And I will be mainly focusing on the difficulties with it in this talk and ways that you can overcome one. So to summarize some of the challenges that I think that we've faced and that you will probably face if you build a large single page application, let's start with staffing. It doesn't seem like a very technical problem, but it's kind of the root of many other problems. If you are working so heavily with JavaScript, it's not enough to have just one developer who's great at JavaScript. You need your entire team to be great at it, and to all understand the libraries and technologies that you're using. And then what about architecture? With single page applications, there aren't any de facto standard architectures, which is an enormous challenge. You've got so many decisions that you have to make about what technologies you want to use and how to combine them. And no one's really giving you the answers there, or are they? We'll get to that. And then page weight. In our case, we've got many megabytes of code. And what are we going to do? Just ship all that in one big blob down to the browser? Are we going to load every single file independently? It's very difficult to figure out what the optimal strategy is there. And then maintenance. All software projects struggle with maintenance to some extent. But if you are relying primarily on JavaScript and CSS, well, those technologies are not really known for their easy maintainability. So although it can be done, it can be a challenge. So we'll look at ways to mitigate that. Library dependencies. Now, I've chosen this Tetris icon to represent library dependencies, because that really summarizes how I feel about it. Because on our project, barely a week goes by without someone saying, we now need this extra third party open source library. Oh, and we need this other one and this other one. And they've all got to fit together and work together nicely and not blow each other up in any way at all. So we've got to keep managing that all the time. Build and test time. Maybe you don't even think that's a big problem for a single page application, but it was for us. Until a few weeks ago, we had this three minute build cycle between every time you touched a file and you were able to see it running. And that was horrible, absolutely horrible. We have thankfully dealt with that now, but unless you're careful, you could end up in this situation as well. Performance and memory. If you were building a small single page application, maybe you don't care if it leaks a bit of memory. Maybe you don't even notice because the user will just leave and do something else in a minute anyway. But with a massive single page application, you cannot afford to be leaking memory over time. And that can be a real challenge. Okay, good. So those are some of the difficulties and we'll look at ways of mitigating many of them through this talk. And as you know from the talk title, I'm going to be talking quite a lot about knockout. Now I'm not saying knockout immediately solves all those problems, far from it. There's a lot more you need to think about, but knockout is the library that we use to build the Azure Management Portal. It's what runs all of the UI that you've seen there. So let's start by asking, why do you think we chose to use knockout on that project? And I know that some of you are thinking, oh, well, it's very obvious why you chose knockout, isn't it? Because you're enormously biased towards using knockout. So that's why you chose it. But no, that's not the reason, honestly. So when they chose to use it, I was not on the team. The causality is the other way around. I joined that team because they chose to use knockout to do some really interesting things. So why do they, independently of me, choose to use this library? Well, a number of reasons. Let's go through a few of them. One of them is very deliberately a library. It's not a framework. Like some of the other larger model view frameworks in JavaScript, it tries to just be a library. It's not trying to dictate your overall architecture. It's designed from the beginning to play well with lots of other different components, which is very useful if you're building a large application and you can't take too much of a big gamble on any one thing. Another thing, knockout system of observables gives us precise control over which parts of our data are observable and in what way. And that means that we can be very confident about scaling to work with enormous amounts of data. Because we know that when one thing changes, it only affects the immediate things that that changes. The system doesn't have to recompute 10,000 other unrelated computer properties just to see if they might have changed. Knockout knows what has changed because it knows the dependency graph. So that gives us the confidence to scale a lot more. Another thing, well, firstly this is meant to be a thumbs up icon. I know it looks more like a boxing glove, but that kind of fits the theme. Anyway, the point is here, knockout is not the best known of these kind of libraries. There are others, particularly things like Backbone and Angular that are better known. And so those would have scored more highly on this particular criteria. But knockout is well known enough that it's no problem for us to find developers who understand it and it's no problem to find third party resources and libraries to work with it. So it scores well enough on that point. Finally, on the good points, knockout has always prized backward compatibility, both with its own previous versions and with older IE versions. So even the very newest stuff, the new features that I'm going to show you today that deal with components and custom elements and stuff, it still supports IE 6, which is almost starting to seem ridiculous at this stage. But we just haven't had a reason to drop backward compatibility. So we're keeping it there for now at least. So yeah, fantastic compatibility. Now one of the things that knockout hasn't ever really attempted to do particularly much, and this is a point against it in many people's view, is it doesn't give you a ready made architecture. It leaves a lot of decisions up to you. But maybe something I'm going to show you today helps a little bit with that. So let me give you a demo of something new that's coming to knockout 3.2, which will be released fairly soon. Now I asked before this talk and most people said they'd use knockout. I think maybe even everybody. So I'm not going to give you an intro to knockout. This is like a hello world scenario that I'm going to convert into a component. So you probably all understand this immediately. I've got a view model with a name property, which is observable, and I'm binding this to my view. And then I've got a text box here whose value is that name property. And then I'm saying I want to output the uppercase version of that name into a strong element there. So it'll show up on the screen. Let's just run it. And it will do exactly what you expect. So when I enter a name into here, then the uppercase version shows up here and everything stays in sync. Straight forwards, you've all seen that kind of code before, nothing clever. Now how can I convert this into a reusable component? Well, let's use the new components API. So I'm going to say knockout.components.register. And then I'll give a name to my new component. And I can call it anything I want, but I'm going to call it name editor. And then I give a configuration for my new component. And a component consists of a template and a view model. And these can be loaded from many different places. This is all pluggable. You can get them from AMD or you can hard code them in or whatever you like. For this Hello World demo, I'm just going to hard code the template straight into my config here. So I'm going to say template is this string. And I'm just going to cut this out here and drop this in here. And similarly on this line, I'm just going to drop that in there. Now of course, normally you would really load from external files. I'll show you that in a minute. But this is helpful to get started. And then I'll define a view model. And I can define that in a few different ways. But the way I'm going to do it here is a constructor function. So here my constructor function is going to define a name property. And I'm going to give that the same thing that we had before. So here's my name property of my component view model. Okay, good. So now I don't actually need this old view model at all anymore. And I can get rid of it from here. And if I want to use my new custom components, I can do it just like this. Name, editor. Great. A custom element. Let's see how this works then, shall we? Come back to my browser and reload. And you'll see it's still working as it did before. And this is now a reusable component. So I can, if I want to, let's say, well, let's have three name editors. Why not? And then when I go back, I've now got three name editors, which are all independent. They've all got their own view models and so on. And it's going to efficiently load the view models and the templates, what's it called, in parallel as it needs to render that UI there. Okay. So that's all very good. And there's loads more that we can do with components as well. For example, we can pass parameters into them. We can get parameters back out of them. We can subclass them. We can load them on demand. We can preload them. You've got a lot of opportunity there to compose a large application out of this system. And you may notice that this somewhat resembles the forthcoming web components notion, where you define custom elements and give behaviors and such to them. And yes, that's of course exactly what it's inspired by. But rather than waiting another like five years or whatever until every browser that your customers use supports that, you can just use that now even right back to IE6 because of the backward compatibility that we prize so highly. So that's a sort of hello world of components. But in this talk, I don't want to stop at this hello world level. I want to give you an idea of an application architecture that's realistic and could actually scale up to build a very large project. And of course, testing a realistic large architecture involves making a lot of decisions. What libraries are you going to use? What kind of modular loader are you going to use? What kind of testing system are you going to use? And there are so many decisions there that you could spend weeks just thinking about and reading people's blog posts and changing your mind over and over. So would it be nice if you could just sort of scaffold up a nice happy starting point just to see how this works and you could even build on that realistically to make a very large application? So scaffolding systems. What scaffolding systems are there? Well, there are ones built into things like ASP.net and other server side frameworks. But besides that, you're probably aware by now that the front end world is kind of a thing in its own right. Front end developers, that is people who build applications that run in the browsers, well, we've got our own preferred technology stacks. We've got our own libraries. We've got our own conventions and culture, our own thought leaders. Front end development is a thing now. So if you're going to get good at front end development, you probably do yourself a favor of understanding these front end technologies. And so what I'm going to show you is how we can use a scaffolding system which is kind of a de facto standard in the front end world called Yeoman. And this allows us to scaffold our starting points and different application pieces for many different technologies. So there are scaffolders for pretty much all the frameworks you've heard of and of course knock out is one of the things that there are many different scaffolders available for. So let me give you a little demo of scaffolding something up that produces a realistic architecture for us with components. So I'm going to, we're going to need a little scenario for an application that we want to build and it doesn't really matter because this talk is about the architecture and not about the actual application itself. But just as a happy little gimmick, I decided, okay, let's make a website for like a cable TV company or something that wants to display an online TV guide and lets people navigate through channels and see what's on and that kind of thing just to set us a bit of a scene for us. Now we need a back end that's going to provide the raw underlying data for that and so I've already implemented that and as it happens I've did it with web API but the technology there doesn't matter at all. I could have done it with node or with basic or assembly or whatever like crazy thing that you want to do as long as it spits out JSON then our front end doesn't care and we're going to keep the front end totally separate from it. So I want to scaffold up a front end for this and at first I'm going to need to install the yeoman tool so I'm going to go NPM node package manager install globally yeoman. So like pretty much all of the other front end tools, yeoman is built on node.js and so we'll use the node package manager to install that and this is going to go off and install it for my user account and it says okay everything's looking good you've installed yeoman well done. Now yeoman doesn't come with any template or maybe it does I don't know but it doesn't come with all the templates that you want by default. So let's install the knockout template into it. So let's say NPM install globally the generator that's what yeoman calls them all called KO for knockout. So there are various different generators available for knockout and this one called generator KO that's the one that I've put together so I can vouch that at least it's sane some of the others are probably really good as well but I don't really know. Anyway we've got that now so we can use this generator. So let's go into the folder where we're going to spit out the code. So we'll go into the TV guide project here and I'm going to make a new directory called TV guide dot front end and I'll change into that directory and now I'm going to use yeoman. So I'm going to say yeoman I would like you to please scaffold up a knockout application yo-ko and that's going to go and do its thing now and firstly it starts with this slightly embarrassing looking ASCII art thing don't blame me for that that's just what yeoman does by default kind of that's how it rolls we can ignore that we just have to answer its questions what's the name of your new site okay how about TV guide that makes sense what language do you want to use ooh we could use typescript or JavaScript well I'll get on to typescript later let's just do some JavaScript for now do you want some automated tests with jasmine and karma yes please why not I'm not going to talk about tests immediately but I will get to them hopefully before the end of this talk so that is now going off and it's using Bower the JavaScript package manager to fetch all these libraries that we're going to use knockout jQuery jasmine require js and so on and it's also installing a test runner called karma that I'll show you in a little bit alright so that's now gone and done its thing and if I look in this folder now you'll see there's quite a lot of stuff there but it's a little bit difficult to understand it through the command line so let's look at it in visual studio now I'm going to do this slightly naff thing here of doing it as a website project so I'm going to import these files as a website project and that allows visual studio to just look at the files that are on disk and not have any actual you know CS project or anything like that now if you were going to do this for a longer period you probably would want to use a web application project which would work absolutely fine too you then just have to keep remember to add files as you go along or of course you can just not use a visual studio at all you can use sublime or anything else and then you don't have to think about that sort of stuff but of course this is going to get way better with the new esp net vnext tooling which is going to take away the need to think about things like project files but anyway for this demo it's very convenient for me to do it as a web application project in a real project I would either use web application or I would just use sublime anyway what have we got in here so we've got some node modules because the build and test system that I'll show you is like most front end tooling built on node so we've got various things in there to do with gulp and karma I'll show you that later we've also got a test folder you can guess what's in there we'll get to that and we've also got some other stuff to do with build and test that we'll think about later so now let's just look at this source folder what have we got in there well some stuff is kind of obvious we've got css and html you know what those do we've also got bower modules this is why bower has installed the javascript libraries that we're depending on knockout and require js and other stuff and then the real application code is in these two folders app and components now in app we've got things to do with the application startup so that's the routing configuration and where the module should be loaded from and so on and then we've also got components and let me actually run this before I show you the component source code so if I want to run this all I have to do is point any web server at all to this source folder because it's just static files I could use is or anything else I like engine x anything you want but for convenience I'm just going to use this node based HTTP server which is a command line tool and I'll tell it to serve up the contents of this source folder so that's running now and I can open that in my browser so let's go to localhost 8080 and you can see here is my starting point for my application and let's just check there's no errors there's no errors everything's good okay so we've got this simple bootstraps based UI here we've got the traditional home and about pages and as I navigate around it's doing this client side routing there I'll I think I'll call it routing since I'm British it's doing client side routing there and you can see that up in the URL and it's got no real functionality other than you can click this button and it's going to just change a message just to show you how it works so let's see a bit of code there the about page component is exceptionally simple it's nothing more than a single static HTML file and that just shows that a component doesn't have to have any more than just static HTML if that's all you want but of course most components will have a combination of a view and a view model so the home one for example has got this view here you can see it's got that message and it's got a button that you can click that does something and when we look at the code there you can see that what this is is a class that's got a message property and when you do something it changes the message so that's how that works and also it's been defined as an AMD module which allows it to be loaded on demand if that's what we want and we'll get to that in a minute okay so that's our starting point but let's add some functionality to this I want this to be a TV guide website so I want to fetch some data about what's on TV and display it in a nice sort of grid format so I'm going to do this by creating a new component and I'm going to call it a program grid and then the idea is I can reuse my program grid and give it different parameters anywhere I'd like in my application so I could create a component if I wanted by creating the files directly in Visual Studio but it's slightly more easy to scaffold it if I want so I'm going to go back into this folder and I'm going to ask Yeoman would you mind be so kind as to create me a new knockout component and we'll call it program grid so that is going to scaffold up the files needed program grid HTML and JavaScript and it's registered it in my application startup file so now if we come back to Visual Studio and we reload you'll see we've got our program grid down here and this is a nice new reusable component and let's see what's in there not very much currently it's just a sort of hello world thing where it displays a message and it passes that message from the view so here my constructor sets a message property with some observable object and that is what gets rendered in the view it's also got a dispose function on the prototype there which you can use for any cleanup if you want to but I don't need that in this example so let's get rid of that and we'll just keep it a bit simpler so if we want to use this program grid from somewhere else in our application it's very very easy indeed all we have to do is just use a program grid element now you don't have to use custom elements if you don't want to if you like you can use the knockout component binding and bind a component into a div or whatever else it is that you'd like but I quite like using this custom element so that's what I'm going to do and now I don't need the rest of this view so let's get rid of that and we'll just change the title to what's on TV okay so now let's go back to the browser and we'll reload and we should see that the title changes what's on TV and we can see the program grid has been injected and bound for us just like you would want it to be and the good thing here is that the home component doesn't need to know anything about the program grid component at all it's loosely coupled which allows your code your components to be quite easily reused in different places and it gives you lots of interesting opportunities when it comes to optimizing your build system as well as I'll talk about in a minute but we can still do things like pass parameters in and get data back out right then so let's put some real functionality into this program grid now I want to actually fetch some data from my back end and render it so this is I'm going to do it in a pretty straightforward way just because this doesn't need to be complex here's a very simple way of getting and rendering some data I am just going to define a channels array on my program grid here so this is an observable array because it can change over time maybe we would use web sockets to push new information in real time or something it doesn't matter but in any case I'm just making it observable so it can change and then I'm populating it in an incredibly straightforward way just do an Ajax request to the back end and stuff the result into the channels array and we're done let's render this in the view now shall we I'll go over to the view and I'll just delete the stuff that I had before I'm going to drop in some markup that I've already prepared so my pre-prepared markup here is going to use an html table and it's going to say in the body of that table iterate over each of the channels and for each of the channels let's create a table row and on each row we're going to have two columns the first column will display an image with the TV channels logo and then in the second column will iterate horizontally across all of the programs and for each program will display a div with the title start time and end time and so on so let's see if that works shall we I think it might not work to see but let's just see so let's hit reload and we'll see nothing seems to be happening and oh dear we've got a connection refused from the back end that's just because I haven't started my back end running just yet and I just realized that a minute ago so let me start my back end running now with a bit of control f5 magic there and so now I can reload and this time it successfully fetched some data from the back end there and we can just see all these different TV programs and stuff but the layout is absolutely horrific right now so let's use a little bit of CSS to end this up and this talk is not about CSS so of course you can use less or sass or whatever you like and you can plug that into your build system that I'll show you later but I'm not really interested in that so I'm just going to dump a bit of ready-made CSS into this file right now just so that we can move on to something more interesting so here's my ready-made CSS I'll come back and I'll hit reload and now you'll see it really does look like an actual grid of TV programs that you would expect to see from your cable TV company or whatever sorry that the title is a slightly distracting alright so that's good but currently I've not really shown you anything particularly clever like currently I'm not even passing any parameters into my grid what if I want to control which channels show up like maybe we want to show all channels or maybe we just want to show the channels that you'll subscribe to so let's have a go at passing some parameter into there I'll go back to where the grid actually gets used and I'm going to say I'll pass a parameter prams equals let's say only my channels true so now I'm passing that parameter in and if I come back and reload nothing changes at all because my component doesn't know anything about this particular parameter name so let's make it aware of that so I'll go into the view model for that and I'm going to define a new property on my view model here called Fint filter channels and what that's going to do is it's going to take the existing set of channels and it'll run an observable filter over that array so that'll keep updated as the underlying array changes and what it does is it works out whether or not we're currently being asked to run a filter and if we are then we'll only use the channel if we're subscribed to it and if we're not filtering then we'll just use all channels so now if I come back and reload then why didn't that do anything I think it's because I didn't really reload properly then nope not for that reason maybe I didn't type it correctly some some way only my channels true oh that's right because currently I'm still binding to the full set of channels I want to bind to just the filtered channels so now if I reload you'll see we just get the filtered channels there so that's how we can pass a parameter in and of course it doesn't have to be a hard coded value like I've shown you here it can be an observable property as well and that will automatically stay updated and now we've got this we can reuse our grid in various ways with different parameters so let's have all channels down here and we'll say only my channel is false and now when I reload we're going to have two grids now we'll just have my channels at the top and we'll have all channels below it so that makes it very nice and convenient to reuse okay now let's change our focus slightly let's think about performance for a little bit or at least performance in terms of how this stuff is delivered to the browser let's see how many HTTP requests we're currently using so if I go into the about tab here and I reload then I look at the let's look at the network tab if I zoom in a bit you'll see we're making 18 HTTP requests to run that page even though it's completely trivial what HTTP requests are we doing? Well we're loading bootstrap and require and jQuery and knockout and crossroads and bootstrap and then we're loading all of the components like we're loading the about page we're loading the navbar template we're loading the navbar view model everything is loading separately and this is in some ways good and in some ways bad now it's good in that in the files that we're seeing in the browser dev tools exactly corresponds to the files that we see on our IDE which is really convenient in development and another good thing is we've got incremental loading here so if I start on the home page and I reload and then I clear the list of requests as soon as I switch to the about screen you'll see it dynamically fetches the template there so we've got automatic dynamic loading of different views and view models as we go along because it's all built on required.js so that's in some ways good but it's also really bad because we're just doing loads of HTTP requests wouldn't it be nice if we could bundle them and minify them you're all familiar with bundling and minifying right so let's say that we do want to do some bundling and minifying how can we do that well this brings us on to the topic of JavaScript build systems and since this talk is not all about knockout I'm also just want to cover some general principles for writing efficient single page applications let's just think about build systems for a minute so you are all familiar with other build systems like MS build or enant or something I don't know what you use how many of you have used either grunt or gulp before okay reasonable number like 20% okay I'll go through this fairly quickly then because a lot of you know this so these are JavaScript build systems that are like most front end tools built on Node.js and the idea is that for example with grunt you run it from the command line and it's going to go through a series of tasks that you've configured maybe to do things like link your code to come to bundle it to minify it to output it to a certain location and you run all that from the command line and that's very convenient and it's all fully designed to work with front end technologies like things like cof script type script all that kind of stuff so that's good now let's just compare these two things a little bit grunt has been around for a little bit longer of the two and what it's like to work with grunt is like this the configuration system is fairly declarative so if you want to configure for example a concatenation step you would declare oh you're going to get all the files from this location you're going to output to them to this other location and you would use declarative config for all the different tasks that you want it to do and you would also get it to load the code that executes those tasks from npm that's the node package manager and then finally you would give names to your tasks for example you say that the default task involves running the three three different steps in sequence queue in it and then concat and then minify and this is quite nice actually I do like it I've used it for over one to two years now this is what we use to build knockout and it generally works pretty well but there's also this newer thing that's come along more recently called gulp and the argument with gulp is what about if we don't want to keep dropping all these temporary files in different locations and picking them up and generally having to figure out different declarative config syntaxes wouldn't it be nice if we could just stream our files through a configuration that we define in code and so what it's like to work with gulp is a little bit more like the following now I've I started using gulp maybe three or four months ago and I really like it actually this is generally what I'm considering as my default system for new projects now I do enjoy it but that's not to say that grunt isn't still good so what it's like to work with gulp is a bit like this you start by declaring some some imports that you need to execute the various tasks that you want and these will all come from npm like the code to minify stuff and so on and then you would also declare tasks that you give a name to so you might say that when I want to process my scripts which is just an arbitrary string I want you to grab all the files under a certain directory and then I want you to pipe them through js hint to check for any errors and then pipe the results from that through a minification process with no temporary files this is all in memory and running in parallel and then pipe that all through a concatenation step and pipe all that out back onto disk and similarly for css maybe you'll do a similar thing except that you pipe it through a less processor and then finally you give names to the the tasks that you're working with so maybe your default task involves running scripts and styles in parallel because it's all going in parallel through streams and maybe you also want it to watch all the files in a certain folder so that when you change something it's going to rerun certain tasks so that's what it's like to use gulp and I really like it so that is what this scaffolding system sets up for you by default let's have a go at using it shall we and before we start I want you to realize and or remember at least the situation that we're in right now so the situation right now is that when you reload this about page we've got 18 separate HTTP requests going on to fetch all the different parts of the application and that is a bit much to be completely honest also notice that in the application folder we've got a source folder here but we have not got a disk folder and disk is where we're going to put the build output so we'll see that appear in a second now we have already got this gulp file that was set up for us I'm not going to go through every line of it but just to give you a quick overview it's got various tasks things like processing JS, processing CSS, HTML, cleaning all the build output and then finally it declares that the default task if you run it with no arguments involves running these three other tasks simultaneously and then giving this message so I will show you a little bit more of that in a second but let's just run it first so I'm just going to run gulp on its own to run the default task and that's going to run these things that have been declared by the scaffolder so that's doing its thing now it takes a few seconds it's going to take like seven seconds and of that seven seconds more than six of them are just running ugly file.js so that's pretty much all the cost of doing that if you just temporarily comment that out it will all go really fast but I want to have that on for this talk so that's output everything to the disk folder so if I come back to VS now and I hit reload we'll see a disk folder has appeared and it hasn't got very much in it really it's got one CSS file one HTML file one JavaScript file and some web fonts we won't worry about those things so it's got the what on earth is that supposed to mean go away so it's got these three files that there's basically all that we need to run our application and if I want to run that now I'm going to stop my web server that is serving the source folder and I'm going to start the web server serving the disk folder instead so this is what you would actually publish to the public internet and people would load to their browsers and now if I come back to my browser and I hit reload then instead of doing 19 requests it's now done three requests one HTML file one CSS one JavaScript and everything has been nicely bundled up into there and I'll show you more about how that works in a second but we're not completely finished yet because it doesn't quite work if I switch on to the home screen we'll get an error what's this error then we're getting a 404 not found it's trying to dynamically load our program grid and it's not there because the program grid isn't there is a standalone file in the disk folder so why is this is this some kind of a bug like why didn't include the program grid in the build output it's not a book otherwise I wouldn't have shown you I would have pretended it wasn't there it's quite deliberate so the system of components is very deliberately all about being loosely coupled and it's so loosely coupled that the required JS optimizer that walks through the dependency graph to find out how all of your code depends on other code doesn't even know that you're using the component it's just too loosely coupled and also sometimes you're going to want to preload your components and other times you'll want to dynamically load them so you need to declare which components are going to be included in the preloaded bundle and that's what I didn't do just yet so let's do that I'll go to my gulp file and you'll see up here this is the required JS optimizer config the required JS optimizer is the thing that understands all the different AMD modules that I've got walks through them understand the dependencies and is able to output bundles and currently it's including in the default bundle everything that the app startup file needs so that's all the library code and the routing config and everything and then I also explicitly have to reference any components that I'm using that are not known to the startup file so you can see the navbar the home page and the about component because that's nothing more than an HTML file you have to use a slightly odd syntax to import it because it has to get converted to a JavaScript wrapper anyway I want to import I want to include the program grid component here so I'm going to reference that it's in a folder called program grid and the actual module name there is program grid so that's now included let's go back and I will rerun gulp there and then that will hopefully be included in the scripts.js bundle file when it's outputted so now that's done I'll come back and I'll reload and instead of getting an error this time I will get my actual application working exactly as it should so that's good or is it's good really let's just take a step back for a minute so what we've accomplished now is that we're now preloading absolutely everything in a small number of files and that's kind of cool because we're doing a small number of HTTP requests but it's also not cool in a certain way because we're preloading everything even the stuff that the user doesn't even see and this is a bit of a problem for us on the Azure management portal right now because as it stands we preload every single thing there is whether or not you are ever going to see it and that is too much stuff really so we are working on producing a system now where it preloads some things and dynamically loads other things and out of the stuff that's dynamically loaded you don't still want to get all the files individually you still want to declare bundles that represent the sort of units of navigation that a user will normally do so you preloaded the right stuff and the other stuff comes in appropriately sized bundles can we do that with this build system of course we can otherwise I wouldn't be talking about it so let's go and have a look so you can see that we've got this bundles config here now require.js only got bundles support proper bundles support in the last few months so I'm betting that most of you haven't really used this bundles feature just yet but it works really well so what I can declare is arbitrary names for other bundles that will be packaged and loaded as a unit so let's say that I don't want to load the about page up front I only want to load that on demand so I'm going to take it out of my list of preloaded things there now I'm going to create a new bundle and I can call this anything I want let's call it about stuff alright and I can put an array of all the AMD modules that should be included in that bundle and I'm just going to put this about page thing in there now it's just a simple html file but there's no reason it's limited to be that it could be any AMD module including one with dependencies that have other recursive dependencies and so on and the bundler will figure all that stuff out for us so now when I come back and I'll reload gulp again instead of producing just a single scripts.js file when it's finished has it finished yet not yet here it comes if I come back and I reload my mouse is not working seriously my mouse is not working what's going on that's strange okay I'll hit reload now instead of just having scripts.js we've also got about stuff.js so that's been outputted as well and if we go over to the browser and I come over and I'm on the home page and I hit reload it currently is loaded everything it needs but it hasn't loaded anything to do with the about page at all and if I go to the network tab and I clear what it's already got there and I switch to about you'll see it dynamically fetches about stuff.js because it knows that the files it needs are in that bundle and inside there you'll see there's just the stuff that we need to render the about page it's just trivial right now but it could be a lot more and the important thing to understand here is that this bundle config has no impact whatsoever on my application architecture in development I do not have to think about this at all I just work with all the files as they are on disk and then the choice of bundling strategy is something that you can think about when you're going to production and as a sort of matter of DevOps so your DevOps team or you if you do DevOps as well can think about different bundling strategies and try out them different strategies without affecting your application architecture in any way at all and that's a really powerful and useful feature of this system. Okay right so that's one aspect of an important feature when building a large single page application is thinking about how the content gets delivered to the browser. Another aspect that it would be rather remiss of me not to mention at all is testing. Now how many of you test your JavaScript code? Alright so that's a lot less of you than write JavaScript code and I can understand that that's something I can definitely relate to because if you're working on a relatively small project testing JavaScript is an enormous overhead and is it really giving you the value that you need on a small project arguably not I mean what's the worst that could happen anyway I mean does it even matter anyway on a large project you don't actually have a choice because you will fail if you don't have decent tests for your large single page application and there are lots of different ways that you can do it. There are so many different choices for example you can do traditional unit level testing on your classes with mox you can test at a component level if you want to maybe you're still using mox at that level or maybe you're letting them use real services or you can even test the entire application all at once with a browser automation tool like Selenium or something like that. Now I will not say to you that any one of these things is the right way or that you should do more of one than another or anything like that because honestly I think it depends on the type of application you're building and where the value of your application is where is the business logic does it only make sense at an end to end level does it make sense on an individual class level that's up to you to decide. The only strong opinion that I'm going to give to you is please be selective about what types of tests you write probably the only wrong strategy is to just go let's test all the things in always possible because that's going to cost you a lot if anybody says you should just write every possible test of everything then you should probably punch that person and well I mean I am not a lawyer but legally I think you would be okay doing that I mean I haven't consulted a lawyer it's just my guess because yeah exactly because it's such a dumb opinion it's not going to cost you heavily to do that be selective about what you write tests for and make it match the places where your application has value. Now I cannot tell you that there's only one right way of doing testing but I can show you some examples of testing technologies. So this scaffolding system that I used here that sets up some tests with Jasmine and Karma. Now the notion of best practices in front end world has a half life of about three months so by the time anyone watches the recording of this it might have changed but as of today Jasmine and Karma are very much considered to be best of breed testing technologies so that's what this is going to use. So let me show you a little bit of how this works right now. We've got this test folder and inside the test folder we've got Bower modules to do with testing like Jasmine and we've also got some stuff to do with running the tests and then we've also got a sample test for the homepage component. It's very trivial let me show you what it does right now. So what it does right now is it uses Required.js to pull in the object that it wants to actually test then for this example test it creates an instance of homepage view model and it checks that the initial message is some value then it changes the object and it checks that the message changes in some way. So this is obviously trivial and a good quality valuable test would be exercising some kind of business logic which this does not but this demonstrates the testing technology and that's as far as we're going to get in this talk. So let's have a go at running this test shall we. You can run it in various different ways but the first way I'll show you is running it in a browser so I'm just going to open the Synglex HTML page in a browser and when that pops up you'll see here's my test running through the Jasmine browser test runner. You won't always want to run your tests in a browser but it's really good to be able to do so because of course you've got your debugger built into the browser there and that is absolutely invaluable when understanding why your tests are not passing or even worse why they are passing when they shouldn't be. So you will use the debugger very slowly to solve that problem but you don't always want to be working in a browser it can be very convenient to run your tests from the command line and that is where Karma comes in. Many of you use Karma, smallish number we're talking 5 maybe 10% at the most there. Alright so not many people are using this yet but it's growing in popularity and with good reason because it's really good. It's a great tool if you are into your single page applications. It's a command line test runner and so the idea is you run it on the command line it opens up real browser instances like actual instances of Chrome or IE or something and then it pushes tests into them and uses web sockets to pull the results out of them so it can get the tests and the results very very fast and give you really great continuous feedback as you're coding and of course being command line driven is very easy to factor into any sort of build or CI process that you've got. Now if you want to run this you need to define a Karma configuration and that's what has been declared, that's what's been scaffolded out for us by this system. Now to be honest with you I'm slightly disappointed with this choice of file name here. If it's me I would have called it Karma Karma Karma Karma configuration which I think it would have been cooler but they apparently didn't think of that so it's rather boringly karma.conf and what that does is it tells Karma where to find everything that you're using and it's a little bit fiddly to set that up because to get Karma to work with Require.js, to work with Jasmine, to work with Knockout components, to work with everything else that you're using simultaneously it's pretty fiddly and it might take you a couple of hours to get that working or it did me at least but thankfully now I've done that that's all there in the scaffolder and you can just use it. So let's have a go at running Karma on the command line. So let's say Karma start and what that will do is it will fire up a browser instance and it's going to start pushing tests into that as much as it needs and if we look back at the command line here you'll see it's executed one of one tests and believe it or not it passed great. Okay so that's good but now I want to show you how it gives you feedback as you're working. So I'm going to move this down to the bottom of the screen here and make it just occupy this little bit of the bottom there and I'm also going to move my VS window a little bit so we can still see that. And now let's write some more tests shall we? And so let's start with it and then because I don't actually have any business logic in this application this is obviously very fake so I'm just going to do a silly arithmetic test but you will understand how you can apply this to exercise your real logic. So let's do it should do arithmetic. Bit cheaty but I know. So let's declare a function here that our test will run and as soon as I press the save button here I'm going to click now immediately it realized that that test is there and it's going to run it and now we've got two tests executed and they both passed. Well done Karma. Alright let's put an expectation in there. Expect 1 plus 1, 2 equal 3 because I'm a moron. So let's try running that now. I'll press save and then it fails would you believe it? Oh let's review arithmetic. We'll fix that and we save it and it's working. Now the cool thing about this is it's not just watching my test files it's also watching the files that are being tested. So if some developer comes along and looks at this home view model and says oh do something that's not a very descriptive name is it? Let's change that to something else. Let's change it to change the message there. I'm a good programmer I've made the code better. As soon as they press save they'll go no bad programmer don't change that because the view depends on it being called do something so it's great to have that feedback so they're going to go obviously controls add enough times to make it go back and save and then it's going to be passing again and we know that things are good. So I would totally recommend trying out the Karma test runner for you. You can make it so it only runs certain tests and not all of them which you may need to do if you've got a very large test suite and you can't run them all every time you save anything. So that's really good and that's of course all set up for you by this Yeoman package. Now last thing that we have got time to talk about TypeScript. I bet everybody in this room has seen TypeScript before. Is that right? Hands up if you've seen TypeScript. Yeah I bet you all have and I bet most of you have at least tried it out as well. So I'm not actually even going to demonstrate this to you because it would be boring. All I would do is I would run the same scaffolder as before and when it asks me I would say yeah I'd like to use TypeScript please and then all the code would come out in TypeScript and then it would all work exactly the same as before, even the tests except that you have to compile before you run anything obviously. But other than that it would all work the same as before. Now what I think is valuable for me to communicate over the next 10 minutes or something is not the basics of TypeScript but rather what I think the pros and cons of it are. So I've been using TypeScript to build this management portal on a very large project for about a year now and I've got some pretty strong opinions about what's good and bad about it and I'm going to give you my opinions and hopefully that will be useful when you're thinking about whether to use it in a project. And as you will find out these are not marketing opinions. I would not get this sanctioned by marketing but that's okay because I haven't checked it with them. All right so if you haven't seen TypeScript just to refresh your memory it looks like this. So TypeScript is compiled so it needs to know where your files are so you use reference statements like that. Also if you're using AMD modules you can do these special imports and that fetches an AMD module asynchronously into your code there. You can also declare things like modules which are equivalent to namespaces and classes and when this compiles to JavaScript what we'll have here is an object, oh sorry a function called myapp.data.transaction repository and it's a function because of course in JavaScript all functions can act as class constructors so that's what it compiles to. Then we can define things like private properties on there and give them types. We can also define a constructor and the contents of that is of course what's going to go into the body of this function that it gets compiled to. We can do more. We can define things like methods just like you do in C-sharp and the parameters and return type are typed there and TypeScript will of course enforce that type checking at compile time but the types don't exist at all at runtime it's purely an artifact of compilation. JavaScript does not know about your types so they just checked compilation time there and also we can do things like type inference so you see this URL variable there I haven't declared type for it but the TypeScript compiler knows because it goes oh that's clearly going to evaluate as a string here that's going to be a string and then it will do all the type checking with that as a string so that saves you a lot of typing. Then it's also got some nice syntactical improvements like you see we've got a lambda function here just like in C-sharp you've got lambdas with the equals bracket thing and not surprisingly that compiles to a JavaScript function that works as you like and that's nice and then the final cool thing that it does is that of course it's got so much type information going around that the tooling can give you good feedback as you're coding with things like IntelliSense so that refreshes your memory hopefully of what it's like to write some TypeScript code and that leaves me on to this question is it a good thing or is it not a good thing? Now if you had asked me that question six months ago I would have struggled to give you an honest answer without being at risk of being fired because I did not like it one little bit. Oh no it was not nice as far as I was concerned I was having a bad time with TypeScript because I was working on a massive project and every time I typed anything I would have to wait multiple seconds before my characters would appear in Visual Studio and then they would probably have red squigglies on them even if it was perfectly valid code and I would be like what are you doing and I have to close and reopen files and then I would eventually try and compile my file and then I would immediately open up the Windows Task Manager and I'd look at the memory usage of TypeScript compiler and it would be like 200 megs, 300 megs, 400 megs, 500 megs, 1 gigabyte, 2 gigabytes and my fan in my laptop would be screaming and my fingers would be melting onto the keyboard and I'd be like ah what's going on and eventually it would all finish with this. We're forcibly killing TypeScript compiler and in my team we got so used to running this command that at one point somebody was going to get t-shirts printed with this slogan on it and eventually someone told them that that was a bad idea so they didn't do it but you understand how we felt at that time. But thankfully since then the TypeScript team have released the version 0.9.7 of their tooling. In fact they've gone to 1.0 since then but 0.9.7 is where everything changed. You can still hear me right? It's sounding strange to me. Okay so in 0.97 everything became so much better. It didn't eat up gigabytes of RAM anymore, it wasn't crashing Visual Studio, the Intellisense actually worked reliably, it was a completely different business after 0.97 so that was an enormous relief to all of us. So generally speaking you can tell I'm more positive this now but I want to still give you the most honest view of I can of this. So I would say that if you're using TypeScript on a large project now sometimes it's bunnies and sunshine and other times it still feels a bit like it's raining blood onto you. So in the spirit of honesty here are the top five best things in my opinion about working with TypeScript and the top five worst things that you still deal with. So let's do the good ones first. The bottom of the list, number five best thing about working with TypeScript is that you can write a code in a C sharp kind of object or into a type away. And you probably like that, I mean most people who do it like it I do anyway so I'm generally positive about this kind of thing. Number four, typo is a very rarely a problem when you're using TypeScript because of course the compiler is going to catch them for you. Very unlikely that you're going to get a typo in production that brings your application down. I appreciate that. Number three, it does have a pretty good syntax, I really like it, it genuinely improves on native JavaScript. So the fact that we can do things like modules and lambdas, I really do appreciate that. So thank you TypeScript team, that's good. Number two, best thing about working with TypeScript, the really big guns now. This is what TypeScript is all about, the fact that you've got strong typing and generics. Now the generics in TypeScript is absolutely gorgeous, it works so well and I really, really appreciate it. So a few weeks ago I was working on some quite complex data structure code with lots of nested generics and it was so great to know that as I refactored it it was going to tell me where I'd forgotten to add an extra generic parameter and so on. So I really, really appreciate that. Number one, best thing of all working with TypeScript, you don't have to remember your own APIs anymore, you can just intelligently go through the entire coding experience and you just don't have to keep remembering stuff. And speaking to someone with limited mental capacity, I really appreciate the fact that I don't have to remember everything all the time. So that's great. Now there are some things that are still not all that lovely and on a bad day I can still feel a bit depressed about it. So number five, not so good thing, well you see I really like JavaScript, I really like how dynamic it is and I like to do some crazy dynamic stuff with all the sort of dynamic function invocation and looking at the arguments array and all that stuff and you can still do that with TypeScript but the only way you do it is by declaring your variables of Type any which just means don't type check this variable. And so it makes me a little sad that I can't somehow have both the dynamic and strongly type things together but I guess that's just a logical limitation, you can't really fix that. But anyway, number four, thirdparty.ts files. If you use any third party JavaScript library which obviously you do then TypeScript doesn't know about them. So how does it know what types are in those files? Well you need to give it these type definition files and it's quite easy to find type definition files for any third party library you can think of. Now the only problem with them in my experience is that every single one of them is wrong or is least incomplete or doesn't match the version of the JavaScript library that you're using. So you'll get very used to patching these.ts files to correct all the mistakes that the author of them made and we do that a lot. Okay, number three thing I don't like, very often I'm writing some code and I'm thinking I know this is going to work at runtime, I totally know what I'm doing and TypeScript is like I don't really know that there's a property with that name and then you're oh damn it I've got to go and declare these extra types and just give all these extra hints to TypeScript. But you know of course it's fundamentally a necessity. If you want the benefits of strong typing you've got to also pay the price of telling it what the types of things are. And I kind of would like to live in a world that's not even logically consistent where I don't have to do that. But unfortunately that's not possible so you just have to live with that. Okay, number two thing that I don't really like is the VS tooling, like I said it's got way better than it used to be. It used to be a nightmare, it's now actually quite decent most of the time. And probably if you're working on a moderate sized project you will think it's completely flawless and wonderful. But we're working on a massive project and we still get times when it's given us red squiggly zoning perfectly valid code or IntelliSense just won't show for no reason today. So I'm sure that they will fix whatever the remaining issues are. They will make it perfect, I'm confident but it's just not 100% of the way they are yet. Especially when you compare it to something like the C-Sharp tooling which is just perfect in every way. Now number one, worst thing of working with TypeScript that I don't like, the fact that you're compiling your code at all. I mean if you've spent enough years working with JavaScript and just you save file, reload, save file, reload, the fact that you're compiling stuff all the time and every process that you ever have to create has to involve compilation, it's just a bit annoying. But there are ways of mitigating it. So Visual Studio has got the ability to compile on save individual TypeScript files and you should definitely do that because that will make your life suddenly become good as opposed to really miserable if you were having to rebuild everything every time you touch any file like I did until three weeks ago. So you will make things better for yourself by doing that. So that's my honest opinion. Now if I was to summarize this, would I use TypeScript or not? I think that honestly yes, I would now use it. On a project that gets beyond a few person month's work of work, I think that the benefits outweigh the drawbacks. Honestly I do now. That's not to say that there aren't drawbacks. Clearly they are. I just personally think that the benefits now outweigh them but only on a fairly large project. Now hopefully you can factor that into your own decisions now. Okay, we're coming up to the end now. I've only got a few moments left. So let's just summarize what we've talked about in this talk. Some of it was about knockout, some of it was about general single page application stuff. We talked about difficulties, right? So with staffing, I would say you can mitigate that by using as much standard front end tooling as you can and align yourself with the rest of the front end worlds so that you can stay up to date with modern technologies and you can get people to understand what you're working on. Two, architectures. Do something modular. For example, the knockout component feature that's going to help you a lot. Come up with something like that, page weight. Make sure you've got some system for doing the right amount of incremental loading and the right amount of upfront loading. I showed you one way of doing it. You may find some other way but do something like that. Maintenance. There's lots of options there. You could use TypeScript. You should be doing some kind of testing. You might want to do some kind of linting. Just do some stuff. It's going to make your life easier. Library dependencies. Make sure you pull them in from a package manager like Bower and you're not just inventing your own system for organizing libraries and versions. It will be easy for you. Build and test. Use the features that are available. If you're doing TypeScript, do compile on save. If you're using Gulp, look into its ability to stream individual changes as you are working on your code. It's going to make your life better. Performance and memory. I didn't really talk about this but one thing I would recommend is don't do what a certain team that built a large management portal recently did which is wait until two weeks before you go to production before thinking about memory leaks and then spending two solid weeks day and night in the Chrome debugging tools tracking down memory leaks. Look at them early on. Consider it to be part of your QA process. Just do some basic stuff to look for it from the beginning. Your life will be better. So there we go. Hopefully that will help you in your process of building a large single page application and you never know. It might even be bunnies and sunshine for you. I hope it is. That's all we've got time for. We do not have time for questions. I'm going to be around. Send me tweets if you want to ask some questions or just tell me what you think about this stuff. Please remember to evaluate your session on the way out and have a really great rest of your day. Thank you very much.
 All right then. I think I'll just kick off now. Is that okay? Yeah, ready to start?  All right then. So, hello and thank you. Let me start my timer. Thank you for coming to  this session. It's really great to see you all. Obviously, it's kind of weird looking  up like that at you all, but I will try and maintain good eye contact and be a good presenter  in this talk. My name is Steve and I, what do I do? I work for Microsoft. I work on lots  of different web stuff for them and I started off this knockout project a few years ago  and so that's why this subject matters to me. I work on single page applications. I've  got a special interest in knockout, so it matters to me and I think it probably matters  to a lot of people actually, the whole single page applications thing because maybe four  years ago when we started knockout, people were not really building such massive single  page applications. Typically, people were using knockout to do just a little bit of interactivity  on a bigger page and that was quite straightforward and knockout solved that problem really well,  but things have moved on enormously in a few years since then and now people are building  these huge applications that stay in the screen for hours potentially as the user is navigating  down around loads of different things without doing any server side page navigation and  that presents a load of new challenges and I don't think that we've necessarily provided  all that much in the way of examples and docs and such that cover those kind of scenarios.  So hopefully I'm going to redress that balance a little bit today. Now then, I should warn  you before we get started that sometimes people have said that my presentation style is a  little bit like this to the audience and to be honest that's probably fair. It might well  feel a bit like this from time to time, but I would just say to you don't worry about  it. It's okay because I'm going to talk about lots of different things in this talk and  I'll be changing subject like every five to ten minutes. So even if you get a bit lost,  it's okay. You can pick it up again as soon as we move on to the next thing. Alright,  so don't worry, chill out. Now I'm going to start off with a few slides. I will be doing  mostly coding this talk, but I want to also, I want to communicate mostly ideas, concepts,  challenges, solutions rather than just going like here's some code, here's some more code,  here's some more code. So there will be a little bit of slides to start off with and  I hope you'll find this valuable. So I just want to introduce some of the pros and cons  of this single page application thing. I'll probably be talking about more about the cons  than the pros because I think that's where there's more interesting stuff, but we will  start with a bit of positivity. So what's positive about writing single page applications?  Well, you know, why are we willing to give up on our 15 years of experience of doing  server side page rendering? You know, are we mad? Why are we doing this? Well, you know,  there's a few really key benefits and the chief among them is probably that we can produce  the best user experience that can be delivered through a web browser. So we can produce applications  that are just as responsive and nice to use or even more so than native desktop and mobile  applications. But we're not writing native code, we're still writing cross platform  code. And these two things together are the absolutely killer features of single page  applications and this is pretty much the solid reason why you would be wanting to do this.  And everything else is just a small benefit. But I'll just round it off a little bit. A  few more smaller benefits are that as a developer, you can really just focus on the one technology.  You can just get really good at your HTML and your JavaScript and your CSS and you don't  have to spend half of your time doing that and half of it working with some almost unrelated  server technology. So that can be nice for you. It also means that as you go further  with this, you build more and more of your application that's able to run on the client  without having that many server dependencies. And so if you use some kind of client side  data store as well, you can even make your application work offline to some extent or  at least work very responsively even in the presence of an intermittent network connection.  So that's nice. And if you go really far with this and what you end up delivering is basically  just static HTML and JavaScript files that talk to back end servers, then you can even  deliver that around the world just by throwing it onto any static file host CDN type thing  and you will get blazingly fast global distribution for basically no money whatsoever. So that's  quite nice as well. But really, the two key things are the user experience and the cross  flat formness. Now, my experience in this, I've worked on quite a few different single  page applications, but this is the one I'm working on at the moment. How many of you  have seen this or used it? Okay, wow, that's good, like a half of you. Right, so this is  the new Microsoft Azure Management Portal. And this is a very, very large single page  application. And it's quite advanced in many ways. It's got quite an advanced user experience.  The user navigates around through these different blades that open up and they can slide back  to where they came from. And this is really giving desktop applications a run for their  money. I think you wouldn't even expect to do something as good as this in a desktop  app. And it's got many other advanced features as well. Obviously, it's pulling in data from  many, many, probably hundreds of back end servers to provide all the information about  what's going on in your cloud services. And the user can even do things like customize  the UI. So for example, here, they're going to pin this file system storage graph onto  the home screen there. And then they could go along and say, hmm, I also want to keep  an eye on the number of HTTP requests. So I'll pin that to my start board as well. And  then maybe they want to customize it a little bit more by resizing things and moving them  around. Maybe they don't actually need that giant map that serves no purpose, but just  looks pretty for demos. So they're going to make that get a lot smaller and move it away  and so on. And as you can imagine, this is a big, big project. We've got dozens of teams  in Microsoft contributing code into this thing. So it's kind of massive. And we needed an  architecture that was really going to scale very well, both in terms of allowing lots  of developers who don't really understand it to contribute good code to it, but also  in terms of providing really great performance for the end user. So we're not shipping too  much code, and we're being efficient about all aspects of the delivery there. So that's  what I'm working on at the moment. And after my experience of working on that, would I  say that it's easy to build a single page application? No. I would not say it is easy.  I would say it can be very challenging compared with many other types of architectural patterns  that you could try and follow. And I will be mainly focusing on the difficulties with it  in this talk and ways that you can overcome one. So to summarize some of the challenges  that I think that we've faced and that you will probably face if you build a large single  page application, let's start with staffing. It doesn't seem like a very technical problem,  but it's kind of the root of many other problems. If you are working so heavily with JavaScript,  it's not enough to have just one developer who's great at JavaScript. You need your entire  team to be great at it, and to all understand the libraries and technologies that you're  using. And then what about architecture? With single page applications, there aren't  any de facto standard architectures, which is an enormous challenge. You've got so many  decisions that you have to make about what technologies you want to use and how to combine  them. And no one's really giving you the answers there, or are they? We'll get to that. And  then page weight. In our case, we've got many megabytes of code. And what are we going to  do? Just ship all that in one big blob down to the browser? Are we going to load every  single file independently? It's very difficult to figure out what the optimal strategy is  there. And then maintenance. All software projects struggle with maintenance to some  extent. But if you are relying primarily on JavaScript and CSS, well, those technologies  are not really known for their easy maintainability. So although it can be done, it can be a challenge.  So we'll look at ways to mitigate that. Library dependencies. Now, I've chosen this Tetris  icon to represent library dependencies, because that really summarizes how I feel about it.  Because on our project, barely a week goes by without someone saying, we now need this  extra third party open source library. Oh, and we need this other one and this other  one. And they've all got to fit together and work together nicely and not blow each other  up in any way at all. So we've got to keep managing that all the time. Build and test  time. Maybe you don't even think that's a big problem for a single page application,  but it was for us. Until a few weeks ago, we had this three minute build cycle between  every time you touched a file and you were able to see it running. And that was horrible,  absolutely horrible. We have thankfully dealt with that now, but unless you're careful,  you could end up in this situation as well. Performance and memory. If you were building  a small single page application, maybe you don't care if it leaks a bit of memory. Maybe  you don't even notice because the user will just leave and do something else in a minute  anyway. But with a massive single page application, you cannot afford to be leaking memory over  time. And that can be a real challenge. Okay, good. So those are some of the difficulties  and we'll look at ways of mitigating many of them through this talk. And as you know  from the talk title, I'm going to be talking quite a lot about knockout. Now I'm not saying  knockout immediately solves all those problems, far from it. There's a lot more you need to  think about, but knockout is the library that we use to build the Azure Management Portal.  It's what runs all of the UI that you've seen there. So let's start by asking, why do you  think we chose to use knockout on that project? And I know that some of you are thinking,  oh, well, it's very obvious why you chose knockout, isn't it? Because you're enormously  biased towards using knockout. So that's why you chose it. But no, that's not the reason,  honestly. So when they chose to use it, I was not on the team. The causality is the other  way around. I joined that team because they chose to use knockout to do some really interesting  things. So why do they, independently of me, choose to use this library? Well, a number  of reasons. Let's go through a few of them. One of them is very deliberately a library.  It's not a framework. Like some of the other larger model view frameworks in JavaScript,  it tries to just be a library. It's not trying to dictate your overall architecture. It's  designed from the beginning to play well with lots of other different components, which  is very useful if you're building a large application and you can't take too much of  a big gamble on any one thing. Another thing, knockout system of observables gives us precise  control over which parts of our data are observable and in what way. And that means that we can  be very confident about scaling to work with enormous amounts of data. Because we know  that when one thing changes, it only affects the immediate things that that changes. The  system doesn't have to recompute 10,000 other unrelated computer properties just to see  if they might have changed. Knockout knows what has changed because it knows the dependency  graph. So that gives us the confidence to scale a lot more. Another thing, well, firstly  this is meant to be a thumbs up icon. I know it looks more like a boxing glove, but that  kind of fits the theme. Anyway, the point is here, knockout is not the best known of  these kind of libraries. There are others, particularly things like Backbone and Angular  that are better known. And so those would have scored more highly on this particular  criteria. But knockout is well known enough that it's no problem for us to find developers  who understand it and it's no problem to find third party resources and libraries to  work with it. So it scores well enough on that point. Finally, on the good points, knockout  has always prized backward compatibility, both with its own previous versions and with older  IE versions. So even the very newest stuff, the new features that I'm going to show you  today that deal with components and custom elements and stuff, it still supports IE  6, which is almost starting to seem ridiculous at this stage. But we just haven't had a reason  to drop backward compatibility. So we're keeping it there for now at least. So yeah, fantastic  compatibility. Now one of the things that knockout hasn't ever really attempted to do  particularly much, and this is a point against it in many people's view, is it doesn't give  you a ready made architecture. It leaves a lot of decisions up to you. But maybe something  I'm going to show you today helps a little bit with that. So let me give you a demo of  something new that's coming to knockout 3.2, which will be released fairly soon. Now I  asked before this talk and most people said they'd use knockout. I think maybe even everybody.  So I'm not going to give you an intro to knockout. This is like a hello world scenario that I'm  going to convert into a component. So you probably all understand this immediately. I've got a  view model with a name property, which is observable, and I'm binding this to my view.  And then I've got a text box here whose value is that name property. And then I'm saying  I want to output the uppercase version of that name into a strong element there. So it'll  show up on the screen. Let's just run it. And it will do exactly what you expect. So when  I enter a name into here, then the uppercase version shows up here and everything stays  in sync. Straight forwards, you've all seen that kind of code before, nothing clever.  Now how can I convert this into a reusable component? Well, let's use the new components  API. So I'm going to say knockout.components.register. And then I'll give a name to my new component.  And I can call it anything I want, but I'm going to call it name editor. And then I give  a configuration for my new component. And a component consists of a template and a view  model. And these can be loaded from many different places. This is all pluggable. You can get  them from AMD or you can hard code them in or whatever you like. For this Hello World  demo, I'm just going to hard code the template straight into my config here. So I'm going  to say template is this string. And I'm just going to cut this out here and drop this in  here. And similarly on this line, I'm just going to drop that in there. Now of course,  normally you would really load from external files. I'll show you that in a minute. But  this is helpful to get started. And then I'll define a view model. And I can define that  in a few different ways. But the way I'm going to do it here is a constructor function. So  here my constructor function is going to define a name property. And I'm going to give that  the same thing that we had before. So here's my name property of my component view model.  Okay, good. So now I don't actually need this old view model at all anymore. And I can get  rid of it from here. And if I want to use my new custom components, I can do it just  like this. Name, editor. Great. A custom element. Let's see how this works then, shall  we? Come back to my browser and reload. And you'll see it's still working as it did before.  And this is now a reusable component. So I can, if I want to, let's say, well, let's  have three name editors. Why not? And then when I go back, I've now got three name editors,  which are all independent. They've all got their own view models and so on. And it's  going to efficiently load the view models and the templates, what's it called, in parallel  as it needs to render that UI there. Okay. So that's all very good. And there's loads  more that we can do with components as well. For example, we can pass parameters into them.  We can get parameters back out of them. We can subclass them. We can load them on demand.  We can preload them. You've got a lot of opportunity there to compose a large application out of  this system. And you may notice that this somewhat resembles the forthcoming web components  notion, where you define custom elements and give behaviors and such to them. And yes,  that's of course exactly what it's inspired by. But rather than waiting another like five  years or whatever until every browser that your customers use supports that, you can  just use that now even right back to IE6 because of the backward compatibility that we prize  so highly. So that's a sort of hello world of components. But in this talk, I don't want  to stop at this hello world level. I want to give you an idea of an application architecture  that's realistic and could actually scale up to build a very large project. And of course,  testing a realistic large architecture involves making a lot of decisions. What libraries  are you going to use? What kind of modular loader are you going to use? What kind of  testing system are you going to use? And there are so many decisions there that you could  spend weeks just thinking about and reading people's blog posts and changing your mind  over and over. So would it be nice if you could just sort of scaffold up a nice happy  starting point just to see how this works and you could even build on that realistically  to make a very large application? So scaffolding systems. What scaffolding systems are there?  Well, there are ones built into things like ASP.net and other server side frameworks.  But besides that, you're probably aware by now that the front end world is kind of a  thing in its own right. Front end developers, that is people who build applications that  run in the browsers, well, we've got our own preferred technology stacks. We've got our  own libraries. We've got our own conventions and culture, our own thought leaders. Front  end development is a thing now. So if you're going to get good at front end development,  you probably do yourself a favor of understanding these front end technologies. And so what  I'm going to show you is how we can use a scaffolding system which is kind of a de facto  standard in the front end world called Yeoman. And this allows us to scaffold our starting  points and different application pieces for many different technologies. So there are  scaffolders for pretty much all the frameworks you've heard of and of course knock out is  one of the things that there are many different scaffolders available for. So let me give you  a little demo of scaffolding something up that produces a realistic architecture for  us with components. So I'm going to, we're going to need a little scenario for an application  that we want to build and it doesn't really matter because this talk is about the architecture  and not about the actual application itself. But just as a happy little gimmick, I decided,  okay, let's make a website for like a cable TV company or something that wants to display  an online TV guide and lets people navigate through channels and see what's on and that  kind of thing just to set us a bit of a scene for us. Now we need a back end that's going  to provide the raw underlying data for that and so I've already implemented that and as  it happens I've did it with web API but the technology there doesn't matter at all. I  could have done it with node or with basic or assembly or whatever like crazy thing that  you want to do as long as it spits out JSON then our front end doesn't care and we're  going to keep the front end totally separate from it. So I want to scaffold up a front  end for this and at first I'm going to need to install the yeoman tool so I'm going to  go NPM node package manager install globally yeoman. So like pretty much all of the other  front end tools, yeoman is built on node.js and so we'll use the node package manager  to install that and this is going to go off and install it for my user account and it  says okay everything's looking good you've installed yeoman well done. Now yeoman doesn't  come with any template or maybe it does I don't know but it doesn't come with all the  templates that you want by default. So let's install the knockout template into it. So  let's say NPM install globally the generator that's what yeoman calls them all called KO  for knockout. So there are various different generators available for knockout and this  one called generator KO that's the one that I've put together so I can vouch that at least  it's sane some of the others are probably really good as well but I don't really know.  Anyway we've got that now so we can use this generator. So let's go into the folder where  we're going to spit out the code. So we'll go into the TV guide project here and I'm  going to make a new directory called TV guide dot front end and I'll change into that directory  and now I'm going to use yeoman. So I'm going to say yeoman I would like you to please scaffold  up a knockout application yo-ko and that's going to go and do its thing now and firstly  it starts with this slightly embarrassing looking ASCII art thing don't blame me for  that that's just what yeoman does by default kind of that's how it rolls we can ignore  that we just have to answer its questions what's the name of your new site okay how  about TV guide that makes sense what language do you want to use ooh we could use typescript  or JavaScript well I'll get on to typescript later let's just do some JavaScript for now  do you want some automated tests with jasmine and karma yes please why not I'm not going  to talk about tests immediately but I will get to them hopefully before the end of this  talk so that is now going off and it's using Bower the JavaScript package manager to fetch  all these libraries that we're going to use knockout jQuery jasmine require js and so  on and it's also installing a test runner called karma that I'll show you in a little  bit alright so that's now gone and done its thing and if I look in this folder now you'll  see there's quite a lot of stuff there but it's a little bit difficult to understand  it through the command line so let's look at it in visual studio now I'm going to do  this slightly naff thing here of doing it as a website project so I'm going to import  these files as a website project and that allows visual studio to just look at the files  that are on disk and not have any actual you know CS project or anything like that now  if you were going to do this for a longer period you probably would want to use a web  application project which would work absolutely fine too you then just have to keep remember  to add files as you go along or of course you can just not use a visual studio at all  you can use sublime or anything else and then you don't have to think about that sort of  stuff but of course this is going to get way better with the new esp net vnext tooling  which is going to take away the need to think about things like project files but anyway  for this demo it's very convenient for me to do it as a web application project in a  real project I would either use web application or I would just use sublime anyway what have  we got in here so we've got some node modules because the build and test system that I'll  show you is like most front end tooling built on node so we've got various things in there  to do with gulp and karma I'll show you that later we've also got a test folder you can  guess what's in there we'll get to that and we've also got some other stuff to do with  build and test that we'll think about later so now let's just look at this source folder  what have we got in there well some stuff is kind of obvious we've got css and html you  know what those do we've also got bower modules this is why bower has installed the javascript  libraries that we're depending on knockout and require js and other stuff and then the  real application code is in these two folders app and components now in app we've got things  to do with the application startup so that's the routing configuration and where the module  should be loaded from and so on and then we've also got components and let me actually run  this before I show you the component source code so if I want to run this all I have to  do is point any web server at all to this source folder because it's just static files  I could use is or anything else I like engine x anything you want but for convenience I'm  just going to use this node based HTTP server which is a command line tool and I'll tell  it to serve up the contents of this source folder so that's running now and I can open  that in my browser so let's go to localhost 8080 and you can see here is my starting  point for my application and let's just check there's no errors there's no errors everything's  good okay so we've got this simple bootstraps based UI here we've got the traditional home  and about pages and as I navigate around it's doing this client side routing there I'll  I think I'll call it routing since I'm British it's doing client side routing there and you  can see that up in the URL and it's got no real functionality other than you can click  this button and it's going to just change a message just to show you how it works so  let's see a bit of code there the about page component is exceptionally simple it's nothing  more than a single static HTML file and that just shows that a component doesn't have to  have any more than just static HTML if that's all you want but of course most components  will have a combination of a view and a view model so the home one for example has got  this view here you can see it's got that message and it's got a button that you can click that  does something and when we look at the code there you can see that what this is is a class  that's got a message property and when you do something it changes the message so that's  how that works and also it's been defined as an AMD module which allows it to be loaded  on demand if that's what we want and we'll get to that in a minute okay so that's our  starting point but let's add some functionality to this I want this to be a TV guide website  so I want to fetch some data about what's on TV and display it in a nice sort of grid  format so I'm going to do this by creating a new component and I'm going to call it a  program grid and then the idea is I can reuse my program grid and give it different parameters  anywhere I'd like in my application so I could create a component if I wanted by creating  the files directly in Visual Studio but it's slightly more easy to scaffold it if I want  so I'm going to go back into this folder and I'm going to ask Yeoman would you mind be  so kind as to create me a new knockout component and we'll call it program grid so that is  going to scaffold up the files needed program grid HTML and JavaScript and it's registered  it in my application startup file so now if we come back to Visual Studio and we reload  you'll see we've got our program grid down here and this is a nice new reusable component  and let's see what's in there not very much currently it's just a sort of hello world  thing where it displays a message and it passes that message from the view so here my constructor  sets a message property with some observable object and that is what gets rendered in the  view it's also got a dispose function on the prototype there which you can use for any  cleanup if you want to but I don't need that in this example so let's get rid of that and  we'll just keep it a bit simpler so if we want to use this program grid from somewhere else  in our application it's very very easy indeed all we have to do is just use a program grid  element now you don't have to use custom elements if you don't want to if you like you can use  the knockout component binding and bind a component into a div or whatever else it is  that you'd like but I quite like using this custom element so that's what I'm going to  do and now I don't need the rest of this view so let's get rid of that and we'll just change  the title to what's on TV okay so now let's go back to the browser and we'll reload and  we should see that the title changes what's on TV and we can see the program grid has  been injected and bound for us just like you would want it to be and the good thing here  is that the home component doesn't need to know anything about the program grid component  at all it's loosely coupled which allows your code your components to be quite easily reused  in different places and it gives you lots of interesting opportunities when it comes  to optimizing your build system as well as I'll talk about in a minute but we can still  do things like pass parameters in and get data back out right then so let's put some  real functionality into this program grid now I want to actually fetch some data from  my back end and render it so this is I'm going to do it in a pretty straightforward way just  because this doesn't need to be complex here's a very simple way of getting and rendering  some data I am just going to define a channels array on my program grid here so this is an  observable array because it can change over time maybe we would use web sockets to push  new information in real time or something it doesn't matter but in any case I'm just  making it observable so it can change and then I'm populating it in an incredibly straightforward  way just do an Ajax request to the back end and stuff the result into the channels array  and we're done let's render this in the view now shall we I'll go over to the view and  I'll just delete the stuff that I had before I'm going to drop in some markup that I've  already prepared so my pre-prepared markup here is going to use an html table and it's  going to say in the body of that table iterate over each of the channels and for each of  the channels let's create a table row and on each row we're going to have two columns  the first column will display an image with the TV channels logo and then in the second  column will iterate horizontally across all of the programs and for each program will  display a div with the title start time and end time and so on so let's see if that works  shall we I think it might not work to see but let's just see so let's hit reload and  we'll see nothing seems to be happening and oh dear we've got a connection refused from  the back end that's just because I haven't started my back end running just yet and I  just realized that a minute ago so let me start my back end running now with a bit of  control f5 magic there and so now I can reload and this time it successfully fetched some  data from the back end there and we can just see all these different TV programs and stuff  but the layout is absolutely horrific right now so let's use a little bit of CSS to end  this up and this talk is not about CSS so of course you can use less or sass or whatever  you like and you can plug that into your build system that I'll show you later but I'm not  really interested in that so I'm just going to dump a bit of ready-made CSS into this  file right now just so that we can move on to something more interesting so here's my  ready-made CSS I'll come back and I'll hit reload and now you'll see it really does look  like an actual grid of TV programs that you would expect to see from your cable TV company  or whatever sorry that the title is a slightly distracting alright so that's good but currently  I've not really shown you anything particularly clever like currently I'm not even passing  any parameters into my grid what if I want to control which channels show up like maybe  we want to show all channels or maybe we just want to show the channels that you'll subscribe  to so let's have a go at passing some parameter into there I'll go back to where the grid actually  gets used and I'm going to say I'll pass a parameter prams equals let's say only my  channels true so now I'm passing that parameter in and if I come back and reload nothing changes  at all because my component doesn't know anything about this particular parameter name so let's  make it aware of that so I'll go into the view model for that and I'm going to define  a new property on my view model here called Fint filter channels and what that's going  to do is it's going to take the existing set of channels and it'll run an observable filter  over that array so that'll keep updated as the underlying array changes and what it does  is it works out whether or not we're currently being asked to run a filter and if we are  then we'll only use the channel if we're subscribed to it and if we're not filtering then we'll  just use all channels so now if I come back and reload then why didn't that do anything  I think it's because I didn't really reload properly then nope not for that reason maybe  I didn't type it correctly some some way only my channels true oh that's right because currently  I'm still binding to the full set of channels I want to bind to just the filtered channels  so now if I reload you'll see we just get the filtered channels there so that's how  we can pass a parameter in and of course it doesn't have to be a hard coded value like  I've shown you here it can be an observable property as well and that will automatically  stay updated and now we've got this we can reuse our grid in various ways with different  parameters so let's have all channels down here and we'll say only my channel is false  and now when I reload we're going to have two grids now we'll just have my channels  at the top and we'll have all channels below it so that makes it very nice and convenient  to reuse okay now let's change our focus slightly let's think about performance for a little  bit or at least performance in terms of how this stuff is delivered to the browser let's  see how many HTTP requests we're currently using so if I go into the about tab here and  I reload then I look at the let's look at the network tab if I zoom in a bit you'll  see we're making 18 HTTP requests to run that page even though it's completely trivial  what HTTP requests are we doing? Well we're loading bootstrap and require and jQuery  and knockout and crossroads and bootstrap and then we're loading all of the components  like we're loading the about page we're loading the navbar template we're loading the navbar  view model everything is loading separately and this is in some ways good and in some  ways bad now it's good in that in the files that we're seeing in the browser dev tools  exactly corresponds to the files that we see on our IDE which is really convenient in development  and another good thing is we've got incremental loading here so if I start on the home page  and I reload and then I clear the list of requests as soon as I switch to the about  screen you'll see it dynamically fetches the template there so we've got automatic dynamic  loading of different views and view models as we go along because it's all built on  required.js so that's in some ways good but it's also really bad because we're just doing  loads of HTTP requests wouldn't it be nice if we could bundle them and minify them you're  all familiar with bundling and minifying right so let's say that we do want to do some bundling  and minifying how can we do that well this brings us on to the topic of JavaScript build  systems and since this talk is not all about knockout I'm also just want to cover some general  principles for writing efficient single page applications let's just think about build systems  for a minute so you are all familiar with other build systems like MS build or enant  or something I don't know what you use how many of you have used either grunt or gulp  before okay reasonable number like 20% okay I'll go through this fairly quickly then because  a lot of you know this so these are JavaScript build systems that are like most front end  tools built on Node.js and the idea is that for example with grunt you run it from the  command line and it's going to go through a series of tasks that you've configured maybe  to do things like link your code to come to bundle it to minify it to output it to a certain  location and you run all that from the command line and that's very convenient and it's all  fully designed to work with front end technologies like things like cof script type script all  that kind of stuff so that's good now let's just compare these two things a little bit  grunt has been around for a little bit longer of the two and what it's like to work with  grunt is like this the configuration system is fairly declarative so if you want to configure  for example a concatenation step you would declare oh you're going to get all the files  from this location you're going to output to them to this other location and you would  use declarative config for all the different tasks that you want it to do and you would  also get it to load the code that executes those tasks from npm that's the node package  manager and then finally you would give names to your tasks for example you say that the  default task involves running the three three different steps in sequence queue in it and  then concat and then minify and this is quite nice actually I do like it I've used it for  over one to two years now this is what we use to build knockout and it generally works pretty  well but there's also this newer thing that's come along more recently called gulp and the  argument with gulp is what about if we don't want to keep dropping all these temporary files  in different locations and picking them up and generally having to figure out different  declarative config syntaxes wouldn't it be nice if we could just stream our files through  a configuration that we define in code and so what it's like to work with gulp is a little  bit more like the following now I've I started using gulp maybe three or four months ago  and I really like it actually this is generally what I'm considering as my default system for  new projects now I do enjoy it but that's not to say that grunt isn't still good so what  it's like to work with gulp is a bit like this you start by declaring some some imports  that you need to execute the various tasks that you want and these will all come from  npm like the code to minify stuff and so on and then you would also declare tasks that  you give a name to so you might say that when I want to process my scripts which is just  an arbitrary string I want you to grab all the files under a certain directory and then  I want you to pipe them through js hint to check for any errors and then pipe the results  from that through a minification process with no temporary files this is all in memory and  running in parallel and then pipe that all through a concatenation step and pipe all  that out back onto disk and similarly for css maybe you'll do a similar thing except  that you pipe it through a less processor and then finally you give names to the the  tasks that you're working with so maybe your default task involves running scripts and  styles in parallel because it's all going in parallel through streams and maybe you  also want it to watch all the files in a certain folder so that when you change something  it's going to rerun certain tasks so that's what it's like to use gulp and I really like  it so that is what this scaffolding system sets up for you by default let's have a go  at using it shall we and before we start I want you to realize and or remember at least  the situation that we're in right now so the situation right now is that when you reload  this about page we've got 18 separate HTTP requests going on to fetch all the different  parts of the application and that is a bit much to be completely honest also notice that  in the application folder we've got a source folder here but we have not got a disk folder  and disk is where we're going to put the build output so we'll see that appear in a second  now we have already got this gulp file that was set up for us I'm not going to go through  every line of it but just to give you a quick overview it's got various tasks things like  processing JS, processing CSS, HTML, cleaning all the build output and then finally it declares  that the default task if you run it with no arguments involves running these three other  tasks simultaneously and then giving this message so I will show you a little bit more  of that in a second but let's just run it first so I'm just going to run gulp on its  own to run the default task and that's going to run these things that have been declared  by the scaffolder so that's doing its thing now it takes a few seconds it's going to  take like seven seconds and of that seven seconds more than six of them are just running  ugly file.js so that's pretty much all the cost of doing that if you just temporarily  comment that out it will all go really fast but I want to have that on for this talk so  that's output everything to the disk folder so if I come back to VS now and I hit reload  we'll see a disk folder has appeared and it hasn't got very much in it really it's got  one CSS file one HTML file one JavaScript file and some web fonts we won't worry about  those things so it's got the what on earth is that supposed to mean go away so it's  got these three files that there's basically all that we need to run our application and  if I want to run that now I'm going to stop my web server that is serving the source folder  and I'm going to start the web server serving the disk folder instead so this is what you  would actually publish to the public internet and people would load to their browsers and  now if I come back to my browser and I hit reload then instead of doing 19 requests it's  now done three requests one HTML file one CSS one JavaScript and everything has been  nicely bundled up into there and I'll show you more about how that works in a second  but we're not completely finished yet because it doesn't quite work if I switch on to the  home screen we'll get an error what's this error then we're getting a 404 not found it's  trying to dynamically load our program grid and it's not there because the program grid  isn't there is a standalone file in the disk folder so why is this is this some kind of  a bug like why didn't include the program grid in the build output it's not a book otherwise  I wouldn't have shown you I would have pretended it wasn't there it's quite deliberate so the  system of components is very deliberately all about being loosely coupled and it's so loosely  coupled that the required JS optimizer that walks through the dependency graph to find  out how all of your code depends on other code doesn't even know that you're using the  component it's just too loosely coupled and also sometimes you're going to want to preload  your components and other times you'll want to dynamically load them so you need to declare  which components are going to be included in the preloaded bundle and that's what I  didn't do just yet so let's do that I'll go to my gulp file and you'll see up here this  is the required JS optimizer config the required JS optimizer is the thing that understands  all the different AMD modules that I've got walks through them understand the dependencies  and is able to output bundles and currently it's including in the default bundle everything  that the app startup file needs so that's all the library code and the routing config  and everything and then I also explicitly have to reference any components that I'm  using that are not known to the startup file so you can see the navbar the home page and  the about component because that's nothing more than an HTML file you have to use a slightly  odd syntax to import it because it has to get converted to a JavaScript wrapper anyway  I want to import I want to include the program grid component here so I'm going to reference  that it's in a folder called program grid and the actual module name there is program  grid so that's now included let's go back and I will rerun gulp there and then that  will hopefully be included in the scripts.js bundle file when it's outputted so now that's  done I'll come back and I'll reload and instead of getting an error this time I will get my  actual application working exactly as it should so that's good or is it's good really let's  just take a step back for a minute so what we've accomplished now is that we're now preloading  absolutely everything in a small number of files and that's kind of cool because we're  doing a small number of HTTP requests but it's also not cool in a certain way because  we're preloading everything even the stuff that the user doesn't even see and this is  a bit of a problem for us on the Azure management portal right now because as it stands we preload  every single thing there is whether or not you are ever going to see it and that is too  much stuff really so we are working on producing a system now where it preloads some things  and dynamically loads other things and out of the stuff that's dynamically loaded you  don't still want to get all the files individually you still want to declare bundles that represent  the sort of units of navigation that a user will normally do so you preloaded the right  stuff and the other stuff comes in appropriately sized bundles can we do that with this build  system of course we can otherwise I wouldn't be talking about it so let's go and have  a look so you can see that we've got this bundles config here now require.js only got  bundles support proper bundles support in the last few months so I'm betting that most  of you haven't really used this bundles feature just yet but it works really well so what  I can declare is arbitrary names for other bundles that will be packaged and loaded  as a unit so let's say that I don't want to load the about page up front I only want  to load that on demand so I'm going to take it out of my list of preloaded things there  now I'm going to create a new bundle and I can call this anything I want let's call  it about stuff alright and I can put an array of all the AMD modules that should be included  in that bundle and I'm just going to put this about page thing in there now it's just a  simple html file but there's no reason it's limited to be that it could be any AMD module  including one with dependencies that have other recursive dependencies and so on and  the bundler will figure all that stuff out for us so now when I come back and I'll reload  gulp again instead of producing just a single scripts.js file when it's finished has it  finished yet not yet here it comes if I come back and I reload my mouse is not working  seriously my mouse is not working what's going on that's strange okay I'll hit reload  now instead of just having scripts.js we've also got about stuff.js so that's been outputted  as well and if we go over to the browser and I come over and I'm on the home page and I  hit reload it currently is loaded everything it needs but it hasn't loaded anything to  do with the about page at all and if I go to the network tab and I clear what it's already  got there and I switch to about you'll see it dynamically fetches about stuff.js because  it knows that the files it needs are in that bundle and inside there you'll see there's  just the stuff that we need to render the about page it's just trivial right now but  it could be a lot more and the important thing to understand here is that this bundle config  has no impact whatsoever on my application architecture in development I do not have  to think about this at all I just work with all the files as they are on disk and then  the choice of bundling strategy is something that you can think about when you're going  to production and as a sort of matter of DevOps so your DevOps team or you if you do DevOps  as well can think about different bundling strategies and try out them different strategies  without affecting your application architecture in any way at all and that's a really powerful  and useful feature of this system.  Okay right so that's one aspect of an important feature when building a large single page application  is thinking about how the content gets delivered to the browser.  Another aspect that it would be rather remiss of me not to mention at all is testing.  Now how many of you test your JavaScript code?  Alright so that's a lot less of you than write JavaScript code and I can understand that  that's something I can definitely relate to because if you're working on a relatively  small project testing JavaScript is an enormous overhead and is it really giving you the value  that you need on a small project arguably not I mean what's the worst that could happen  anyway I mean does it even matter anyway on a large project you don't actually have a  choice because you will fail if you don't have decent tests for your large single page  application and there are lots of different ways that you can do it.  There are so many different choices for example you can do traditional unit level testing  on your classes with mox you can test at a component level if you want to maybe you're  still using mox at that level or maybe you're letting them use real services or you can  even test the entire application all at once with a browser automation tool like Selenium  or something like that.  Now I will not say to you that any one of these things is the right way or that you  should do more of one than another or anything like that because honestly I think it depends  on the type of application you're building and where the value of your application is  where is the business logic does it only make sense at an end to end level does it make  sense on an individual class level that's up to you to decide.  The only strong opinion that I'm going to give to you is please be selective about what  types of tests you write probably the only wrong strategy is to just go let's test all  the things in always possible because that's going to cost you a lot if anybody says you  should just write every possible test of everything then you should probably punch that person  and well I mean I am not a lawyer but legally I think you would be okay doing that I mean  I haven't consulted a lawyer it's just my guess because yeah exactly because it's such  a dumb opinion it's not going to cost you heavily to do that be selective about what  you write tests for and make it match the places where your application has value.  Now I cannot tell you that there's only one right way of doing testing but I can show  you some examples of testing technologies.  So this scaffolding system that I used here that sets up some tests with Jasmine and Karma.  Now the notion of best practices in front end world has a half life of about three months  so by the time anyone watches the recording of this it might have changed but as of today  Jasmine and Karma are very much considered to be best of breed testing technologies so  that's what this is going to use.  So let me show you a little bit of how this works right now.  We've got this test folder and inside the test folder we've got Bower modules to do  with testing like Jasmine and we've also got some stuff to do with running the tests and  then we've also got a sample test for the homepage component.  It's very trivial let me show you what it does right now.  So what it does right now is it uses Required.js to pull in the object that it wants to actually  test then for this example test it creates an instance of homepage view model and it  checks that the initial message is some value then it changes the object and it checks that  the message changes in some way.  So this is obviously trivial and a good quality valuable test would be exercising some kind  of business logic which this does not but this demonstrates the testing technology and  that's as far as we're going to get in this talk.  So let's have a go at running this test shall we.  You can run it in various different ways but the first way I'll show you is running it  in a browser so I'm just going to open the Synglex HTML page in a browser and when that  pops up you'll see here's my test running through the Jasmine browser test runner.  You won't always want to run your tests in a browser but it's really good to be able  to do so because of course you've got your debugger built into the browser there and  that is absolutely invaluable when understanding why your tests are not passing or even worse  why they are passing when they shouldn't be.  So you will use the debugger very slowly to solve that problem but you don't always want  to be working in a browser it can be very convenient to run your tests from the command  line and that is where Karma comes in.  Many of you use Karma, smallish number we're talking 5 maybe 10% at the most there.  Alright so not many people are using this yet but it's growing in popularity and with  good reason because it's really good.  It's a great tool if you are into your single page applications.  It's a command line test runner and so the idea is you run it on the command line it  opens up real browser instances like actual instances of Chrome or IE or something and  then it pushes tests into them and uses web sockets to pull the results out of them so  it can get the tests and the results very very fast and give you really great continuous  feedback as you're coding and of course being command line driven is very easy to factor  into any sort of build or CI process that you've got.  Now if you want to run this you need to define a Karma configuration and that's what has  been declared, that's what's been scaffolded out for us by this system.  Now to be honest with you I'm slightly disappointed with this choice of file name here.  If it's me I would have called it Karma Karma Karma Karma configuration which I think it  would have been cooler but they apparently didn't think of that so it's rather boringly  karma.conf and what that does is it tells Karma where to find everything that you're  using and it's a little bit fiddly to set that up because to get Karma to work with  Require.js, to work with Jasmine, to work with Knockout components, to work with everything  else that you're using simultaneously it's pretty fiddly and it might take you a couple  of hours to get that working or it did me at least but thankfully now I've done that  that's all there in the scaffolder and you can just use it.  So let's have a go at running Karma on the command line.  So let's say Karma start and what that will do is it will fire up a browser instance and  it's going to start pushing tests into that as much as it needs and if we look back at  the command line here you'll see it's executed one of one tests and believe it or not it  passed great.  Okay so that's good but now I want to show you how it gives you feedback as you're working.  So I'm going to move this down to the bottom of the screen here and make it just occupy  this little bit of the bottom there and I'm also going to move my VS window a little bit  so we can still see that.  And now let's write some more tests shall we?  And so let's start with it and then because I don't actually have any business logic in  this application this is obviously very fake so I'm just going to do a silly arithmetic  test but you will understand how you can apply this to exercise your real logic.  So let's do it should do arithmetic.  Bit cheaty but I know.  So let's declare a function here that our test will run and as soon as I press the save  button here I'm going to click now immediately it realized that that test is there and it's  going to run it and now we've got two tests executed and they both passed.  Well done Karma.  Alright let's put an expectation in there.  Expect 1 plus 1, 2 equal 3 because I'm a moron.  So let's try running that now.  I'll press save and then it fails would you believe it?  Oh let's review arithmetic.  We'll fix that and we save it and it's working.  Now the cool thing about this is it's not just watching my test files it's also watching  the files that are being tested.  So if some developer comes along and looks at this home view model and says oh do something  that's not a very descriptive name is it?  Let's change that to something else.  Let's change it to change the message there.  I'm a good programmer I've made the code better.  As soon as they press save they'll go no bad programmer don't change that because the view  depends on it being called do something so it's great to have that feedback so they're  going to go obviously controls add enough times to make it go back and save and then  it's going to be passing again and we know that things are good.  So I would totally recommend trying out the Karma test runner for you.  You can make it so it only runs certain tests and not all of them which you may need to  do if you've got a very large test suite and you can't run them all every time you save  anything.  So that's really good and that's of course all set up for you by this Yeoman package.  Now last thing that we have got time to talk about TypeScript.  I bet everybody in this room has seen TypeScript before.  Is that right?  Hands up if you've seen TypeScript.  Yeah I bet you all have and I bet most of you have at least tried it out as well.  So I'm not actually even going to demonstrate this to you because it would be boring.  All I would do is I would run the same scaffolder as before and when it asks me I would say  yeah I'd like to use TypeScript please and then all the code would come out in TypeScript  and then it would all work exactly the same as before, even the tests except that you  have to compile before you run anything obviously.  But other than that it would all work the same as before.  Now what I think is valuable for me to communicate over the next 10 minutes or something is not  the basics of TypeScript but rather what I think the pros and cons of it are.  So I've been using TypeScript to build this management portal on a very large project  for about a year now and I've got some pretty strong opinions about what's good and bad about  it and I'm going to give you my opinions and hopefully that will be useful when you're  thinking about whether to use it in a project.  And as you will find out these are not marketing opinions.  I would not get this sanctioned by marketing but that's okay because I haven't checked  it with them.  All right so if you haven't seen TypeScript just to refresh your memory it looks like  this.  So TypeScript is compiled so it needs to know where your files are so you use reference  statements like that.  Also if you're using AMD modules you can do these special imports and that fetches an  AMD module asynchronously into your code there.  You can also declare things like modules which are equivalent to namespaces and classes and  when this compiles to JavaScript what we'll have here is an object, oh sorry a function  called myapp.data.transaction repository and it's a function because of course in JavaScript  all functions can act as class constructors so that's what it compiles to.  Then we can define things like private properties on there and give them types.  We can also define a constructor and the contents of that is of course what's going to go into  the body of this function that it gets compiled to.  We can do more.  We can define things like methods just like you do in C-sharp and the parameters and return  type are typed there and TypeScript will of course enforce that type checking at compile  time but the types don't exist at all at runtime it's purely an artifact of compilation.  JavaScript does not know about your types so they just checked compilation time there  and also we can do things like type inference so you see this URL variable there I haven't  declared type for it but the TypeScript compiler knows because it goes oh that's clearly going  to evaluate as a string here that's going to be a string and then it will do all the  type checking with that as a string so that saves you a lot of typing.  Then it's also got some nice syntactical improvements like you see we've got a lambda  function here just like in C-sharp you've got lambdas with the equals bracket thing  and not surprisingly that compiles to a JavaScript function that works as you like and that's  nice and then the final cool thing that it does is that of course it's got so much type  information going around that the tooling can give you good feedback as you're coding  with things like IntelliSense so that refreshes your memory hopefully of what it's like to  write some TypeScript code and that leaves me on to this question is it a good thing  or is it not a good thing?  Now if you had asked me that question six months ago I would have struggled to give  you an honest answer without being at risk of being fired because I did not like it one  little bit. Oh no it was not nice as far as I was concerned I was having a bad time with  TypeScript because I was working on a massive project and every time I typed anything I  would have to wait multiple seconds before my characters would appear in Visual Studio  and then they would probably have red squigglies on them even if it was perfectly valid code  and I would be like what are you doing and I have to close and reopen files and then  I would eventually try and compile my file and then I would immediately open up the Windows  Task Manager and I'd look at the memory usage of TypeScript compiler and it would be like  200 megs, 300 megs, 400 megs, 500 megs, 1 gigabyte, 2 gigabytes and my fan in my laptop  would be screaming and my fingers would be melting onto the keyboard and I'd be like  ah what's going on and eventually it would all finish with this. We're forcibly killing  TypeScript compiler and in my team we got so used to running this command that at one point  somebody was going to get t-shirts printed with this slogan on it and eventually someone  told them that that was a bad idea so they didn't do it but you understand how we felt  at that time. But thankfully since then the TypeScript team have released the version 0.9.7  of their tooling. In fact they've gone to 1.0 since then but 0.9.7 is where everything  changed. You can still hear me right? It's sounding strange to me. Okay so in 0.97 everything  became so much better. It didn't eat up gigabytes of RAM anymore, it wasn't crashing Visual  Studio, the Intellisense actually worked reliably, it was a completely different business after  0.97 so that was an enormous relief to all of us. So generally speaking you can tell  I'm more positive this now but I want to still give you the most honest view of I can of  this. So I would say that if you're using TypeScript on a large project now sometimes  it's bunnies and sunshine and other times it still feels a bit like it's raining blood  onto you. So in the spirit of honesty here are the top five best things in my opinion  about working with TypeScript and the top five worst things that you still deal with.  So let's do the good ones first. The bottom of the list, number five best thing about  working with TypeScript is that you can write a code in a C sharp kind of object or into  a type away. And you probably like that, I mean most people who do it like it I do anyway  so I'm generally positive about this kind of thing. Number four, typo is a very rarely  a problem when you're using TypeScript because of course the compiler is going to catch them  for you. Very unlikely that you're going to get a typo in production that brings your  application down. I appreciate that. Number three, it does have a pretty good syntax,  I really like it, it genuinely improves on native JavaScript. So the fact that we can  do things like modules and lambdas, I really do appreciate that. So thank you TypeScript  team, that's good. Number two, best thing about working with TypeScript, the really  big guns now. This is what TypeScript is all about, the fact that you've got strong typing  and generics. Now the generics in TypeScript is absolutely gorgeous, it works so well and  I really, really appreciate it. So a few weeks ago I was working on some quite complex data  structure code with lots of nested generics and it was so great to know that as I refactored  it it was going to tell me where I'd forgotten to add an extra generic parameter and so on.  So I really, really appreciate that. Number one, best thing of all working with TypeScript,  you don't have to remember your own APIs anymore, you can just intelligently go through the  entire coding experience and you just don't have to keep remembering stuff. And speaking  to someone with limited mental capacity, I really appreciate the fact that I don't have  to remember everything all the time. So that's great. Now there are some things that are  still not all that lovely and on a bad day I can still feel a bit depressed about it.  So number five, not so good thing, well you see I really like JavaScript, I really like  how dynamic it is and I like to do some crazy dynamic stuff with all the sort of dynamic  function invocation and looking at the arguments array and all that stuff and you can still  do that with TypeScript but the only way you do it is by declaring your variables of Type  any which just means don't type check this variable. And so it makes me a little sad  that I can't somehow have both the dynamic and strongly type things together but I guess  that's just a logical limitation, you can't really fix that. But anyway, number four,  thirdparty.ts files. If you use any third party JavaScript library which obviously you  do then TypeScript doesn't know about them. So how does it know what types are in those  files? Well you need to give it these type definition files and it's quite easy to find  type definition files for any third party library you can think of. Now the only problem  with them in my experience is that every single one of them is wrong or is least incomplete  or doesn't match the version of the JavaScript library that you're using. So you'll get very  used to patching these.ts files to correct all the mistakes that the author of them made  and we do that a lot. Okay, number three thing I don't like, very often I'm writing some  code and I'm thinking I know this is going to work at runtime, I totally know what I'm  doing and TypeScript is like I don't really know that there's a property with that name  and then you're oh damn it I've got to go and declare these extra types and just give  all these extra hints to TypeScript. But you know of course it's fundamentally a necessity.  If you want the benefits of strong typing you've got to also pay the price of telling  it what the types of things are. And I kind of would like to live in a world that's not  even logically consistent where I don't have to do that. But unfortunately that's not possible  so you just have to live with that. Okay, number two thing that I don't really like is the  VS tooling, like I said it's got way better than it used to be. It used to be a nightmare,  it's now actually quite decent most of the time. And probably if you're working on a  moderate sized project you will think it's completely flawless and wonderful. But we're  working on a massive project and we still get times when it's given us red squiggly  zoning perfectly valid code or IntelliSense just won't show for no reason today. So I'm  sure that they will fix whatever the remaining issues are. They will make it perfect, I'm  confident but it's just not 100% of the way they are yet. Especially when you compare  it to something like the C-Sharp tooling which is just perfect in every way. Now number  one, worst thing of working with TypeScript that I don't like, the fact that you're compiling  your code at all. I mean if you've spent enough years working with JavaScript and just you  save file, reload, save file, reload, the fact that you're compiling stuff all the time  and every process that you ever have to create has to involve compilation, it's just a bit  annoying. But there are ways of mitigating it. So Visual Studio has got the ability to  compile on save individual TypeScript files and you should definitely do that because  that will make your life suddenly become good as opposed to really miserable if you were  having to rebuild everything every time you touch any file like I did until three weeks  ago. So you will make things better for yourself by doing that. So that's my honest opinion.  Now if I was to summarize this, would I use TypeScript or not? I think that honestly yes,  I would now use it. On a project that gets beyond a few person month's work of work,  I think that the benefits outweigh the drawbacks. Honestly I do now. That's not to say that  there aren't drawbacks. Clearly they are. I just personally think that the benefits  now outweigh them but only on a fairly large project. Now hopefully you can factor that  into your own decisions now. Okay, we're coming up to the end now. I've only got a few moments  left. So let's just summarize what we've talked about in this talk. Some of it was about knockout,  some of it was about general single page application stuff. We talked about difficulties, right?  So with staffing, I would say you can mitigate that by using as much standard front end tooling  as you can and align yourself with the rest of the front end worlds so that you can stay  up to date with modern technologies and you can get people to understand what you're working  on. Two, architectures. Do something modular. For example, the knockout component feature  that's going to help you a lot. Come up with something like that, page weight. Make sure  you've got some system for doing the right amount of incremental loading and the right  amount of upfront loading. I showed you one way of doing it. You may find some other way  but do something like that. Maintenance. There's lots of options there. You could use  TypeScript. You should be doing some kind of testing. You might want to do some kind  of linting. Just do some stuff. It's going to make your life easier. Library dependencies.  Make sure you pull them in from a package manager like Bower and you're not just inventing  your own system for organizing libraries and versions. It will be easy for you. Build and  test. Use the features that are available. If you're doing TypeScript, do compile on save.  If you're using Gulp, look into its ability to stream individual changes as you are working  on your code. It's going to make your life better. Performance and memory. I didn't really  talk about this but one thing I would recommend is don't do what a certain team that built  a large management portal recently did which is wait until two weeks before you go to production  before thinking about memory leaks and then spending two solid weeks day and night in  the Chrome debugging tools tracking down memory leaks. Look at them early on. Consider it  to be part of your QA process. Just do some basic stuff to look for it from the beginning.  Your life will be better. So there we go. Hopefully that will help you in your process  of building a large single page application and you never know. It might even be bunnies  and sunshine for you. I hope it is. That's all we've got time for. We do not have time  for questions. I'm going to be around. Send me tweets if you want to ask some questions  or just tell me what you think about this stuff. Please remember to evaluate your session  on the way out and have a really great rest of your day. Thank you very much.
Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_0_2255.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_2256_3023.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_3024_6419.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_6420_6731.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_6732_6947.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_6948_7019.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_7020_7163.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_7164_7631.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_7632_7679.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_7680_7727.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_7728_7943.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_7944_8651.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_8652_8735.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_8736_8915.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_8916_10043.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_10044_12839.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_12840_17219.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_17220_17279.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_17280_23747.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_23748_24203.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_24204_24263.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_24264_25559.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_25560_25643.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_25644_39899.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_39900_40391.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_40392_41435.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_41436_41591.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_41592_42575.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_42576_46295.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_46296_46379.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_46380_47459.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_47460_49055.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_49056_50975.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_50976_51035.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_51036_52367.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_52368_52991.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_52992_53363.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_53364_53435.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_53436_53567.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_53568_53915.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_53916_54467.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_54468_54863.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_54864_55019.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_55020_57323.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_57324_60407.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_60408_60551.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_60552_60611.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_60612_60911.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_60912_61067.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_61068_61139.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_61140_62555.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_62556_62747.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_62748_65759.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_65760_70979.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_70980_71255.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_71256_71327.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_71328_71423.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_71424_74219.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_74220_74279.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_74280_88919.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_88920_92327.png Steve_Sanderson_-_Architecting_large_Single_Page_Applications_with_Knockout_92328_92393.png
All right then. I think I'll just kick off now. Is that okay? Yeah, ready to start? All right then. So, hello and thank you. Let me start my timer. Thank you for coming to this session. It's really great to see you all. Obviously, it's kind of weird looking up like that at you all, but I will try and maintain good eye contact and be a good presenter in this talk. My name is Steve and I, what do I do? I work for Microsoft. I work on lots of different web stuff for them and I started off this knockout project a few years ago and so that's why this subject matters to me. I work on single page applications. I've got a special interest in knockout, so it matters to me and I think it probably matters to a lot of people actually, the whole single page applications thing because maybe four years ago when we started knockout, people were not really building such massive single page applications. Typically, people were using knockout to do just a little bit of interactivity on a bigger page and that was quite straightforward and knockout solved that problem really well, but things have moved on enormously in a few years since then and now people are building these huge applications that stay in the screen for hours potentially as the user is navigating down around loads of different things without doing any server side page navigation and that presents a load of new challenges and I don't think that we've necessarily provided all that much in the way of examples and docs and such that cover those kind of scenarios. So hopefully I'm going to redress that balance a little bit today. Now then, I should warn you before we get started that sometimes people have said that my presentation style is a little bit like this to the audience and to be honest that's probably fair. It might well feel a bit like this from time to time, but I would just say to you don't worry about it. It's okay because I'm going to talk about lots of different things in this talk and I'll be changing subject like every five to ten minutes. So even if you get a bit lost, it's okay. You can pick it up again as soon as we move on to the next thing. Alright, so don't worry, chill out. Now I'm going to start off with a few slides. I will be doing mostly coding this talk, but I want to also, I want to communicate mostly ideas, concepts, challenges, solutions rather than just going like here's some code, here's some more code, here's some more code. So there will be a little bit of slides to start off with and I hope you'll find this valuable. So I just want to introduce some of the pros and cons of this single page application thing. I'll probably be talking about more about the cons than the pros because I think that's where there's more interesting stuff, but we will start with a bit of positivity. So what's positive about writing single page applications? Well, you know, why are we willing to give up on our 15 years of experience of doing server side page rendering? You know, are we mad? Why are we doing this? Well, you know, there's a few really key benefits and the chief among them is probably that we can produce the best user experience that can be delivered through a web browser. So we can produce applications that are just as responsive and nice to use or even more so than native desktop and mobile applications. But we're not writing native code, we're still writing cross platform code. And these two things together are the absolutely killer features of single page applications and this is pretty much the solid reason why you would be wanting to do this. And everything else is just a small benefit. But I'll just round it off a little bit. A few more smaller benefits are that as a developer, you can really just focus on the one technology. You can just get really good at your HTML and your JavaScript and your CSS and you don't have to spend half of your time doing that and half of it working with some almost unrelated server technology. So that can be nice for you. It also means that as you go further with this, you build more and more of your application that's able to run on the client without having that many server dependencies. And so if you use some kind of client side data store as well, you can even make your application work offline to some extent or at least work very responsively even in the presence of an intermittent network connection. So that's nice. And if you go really far with this and what you end up delivering is basically just static HTML and JavaScript files that talk to back end servers, then you can even deliver that around the world just by throwing it onto any static file host CDN type thing and you will get blazingly fast global distribution for basically no money whatsoever. So that's quite nice as well. But really, the two key things are the user experience and the cross flat formness. Now, my experience in this, I've worked on quite a few different single page applications, but this is the one I'm working on at the moment. How many of you have seen this or used it? Okay, wow, that's good, like a half of you. Right, so this is the new Microsoft Azure Management Portal. And this is a very, very large single page application. And it's quite advanced in many ways. It's got quite an advanced user experience. The user navigates around through these different blades that open up and they can slide back to where they came from. And this is really giving desktop applications a run for their money. I think you wouldn't even expect to do something as good as this in a desktop app. And it's got many other advanced features as well. Obviously, it's pulling in data from many, many, probably hundreds of back end servers to provide all the information about what's going on in your cloud services. And the user can even do things like customize the UI. So for example, here, they're going to pin this file system storage graph onto the home screen there. And then they could go along and say, hmm, I also want to keep an eye on the number of HTTP requests. So I'll pin that to my start board as well. And then maybe they want to customize it a little bit more by resizing things and moving them around. Maybe they don't actually need that giant map that serves no purpose, but just looks pretty for demos. So they're going to make that get a lot smaller and move it away and so on. And as you can imagine, this is a big, big project. We've got dozens of teams in Microsoft contributing code into this thing. So it's kind of massive. And we needed an architecture that was really going to scale very well, both in terms of allowing lots of developers who don't really understand it to contribute good code to it, but also in terms of providing really great performance for the end user. So we're not shipping too much code, and we're being efficient about all aspects of the delivery there. So that's what I'm working on at the moment. And after my experience of working on that, would I say that it's easy to build a single page application? No. I would not say it is easy. I would say it can be very challenging compared with many other types of architectural patterns that you could try and follow. And I will be mainly focusing on the difficulties with it in this talk and ways that you can overcome one. So to summarize some of the challenges that I think that we've faced and that you will probably face if you build a large single page application, let's start with staffing. It doesn't seem like a very technical problem, but it's kind of the root of many other problems. If you are working so heavily with JavaScript, it's not enough to have just one developer who's great at JavaScript. You need your entire team to be great at it, and to all understand the libraries and technologies that you're using. And then what about architecture? With single page applications, there aren't any de facto standard architectures, which is an enormous challenge. You've got so many decisions that you have to make about what technologies you want to use and how to combine them. And no one's really giving you the answers there, or are they? We'll get to that. And then page weight. In our case, we've got many megabytes of code. And what are we going to do? Just ship all that in one big blob down to the browser? Are we going to load every single file independently? It's very difficult to figure out what the optimal strategy is there. And then maintenance. All software projects struggle with maintenance to some extent. But if you are relying primarily on JavaScript and CSS, well, those technologies are not really known for their easy maintainability. So although it can be done, it can be a challenge. So we'll look at ways to mitigate that. Library dependencies. Now, I've chosen this Tetris icon to represent library dependencies, because that really summarizes how I feel about it. Because on our project, barely a week goes by without someone saying, we now need this extra third party open source library. Oh, and we need this other one and this other one. And they've all got to fit together and work together nicely and not blow each other up in any way at all. So we've got to keep managing that all the time. Build and test time. Maybe you don't even think that's a big problem for a single page application, but it was for us. Until a few weeks ago, we had this three minute build cycle between every time you touched a file and you were able to see it running. And that was horrible, absolutely horrible. We have thankfully dealt with that now, but unless you're careful, you could end up in this situation as well. Performance and memory. If you were building a small single page application, maybe you don't care if it leaks a bit of memory. Maybe you don't even notice because the user will just leave and do something else in a minute anyway. But with a massive single page application, you cannot afford to be leaking memory over time. And that can be a real challenge. Okay, good. So those are some of the difficulties and we'll look at ways of mitigating many of them through this talk. And as you know from the talk title, I'm going to be talking quite a lot about knockout. Now I'm not saying knockout immediately solves all those problems, far from it. There's a lot more you need to think about, but knockout is the library that we use to build the Azure Management Portal. It's what runs all of the UI that you've seen there. So let's start by asking, why do you think we chose to use knockout on that project? And I know that some of you are thinking, oh, well, it's very obvious why you chose knockout, isn't it? Because you're enormously biased towards using knockout. So that's why you chose it. But no, that's not the reason, honestly. So when they chose to use it, I was not on the team. The causality is the other way around. I joined that team because they chose to use knockout to do some really interesting things. So why do they, independently of me, choose to use this library? Well, a number of reasons. Let's go through a few of them. One of them is very deliberately a library. It's not a framework. Like some of the other larger model view frameworks in JavaScript, it tries to just be a library. It's not trying to dictate your overall architecture. It's designed from the beginning to play well with lots of other different components, which is very useful if you're building a large application and you can't take too much of a big gamble on any one thing. Another thing, knockout system of observables gives us precise control over which parts of our data are observable and in what way. And that means that we can be very confident about scaling to work with enormous amounts of data. Because we know that when one thing changes, it only affects the immediate things that that changes. The system doesn't have to recompute 10,000 other unrelated computer properties just to see if they might have changed. Knockout knows what has changed because it knows the dependency graph. So that gives us the confidence to scale a lot more. Another thing, well, firstly this is meant to be a thumbs up icon. I know it looks more like a boxing glove, but that kind of fits the theme. Anyway, the point is here, knockout is not the best known of these kind of libraries. There are others, particularly things like Backbone and Angular that are better known. And so those would have scored more highly on this particular criteria. But knockout is well known enough that it's no problem for us to find developers who understand it and it's no problem to find third party resources and libraries to work with it. So it scores well enough on that point. Finally, on the good points, knockout has always prized backward compatibility, both with its own previous versions and with older IE versions. So even the very newest stuff, the new features that I'm going to show you today that deal with components and custom elements and stuff, it still supports IE 6, which is almost starting to seem ridiculous at this stage. But we just haven't had a reason to drop backward compatibility. So we're keeping it there for now at least. So yeah, fantastic compatibility. Now one of the things that knockout hasn't ever really attempted to do particularly much, and this is a point against it in many people's view, is it doesn't give you a ready made architecture. It leaves a lot of decisions up to you. But maybe something I'm going to show you today helps a little bit with that. So let me give you a demo of something new that's coming to knockout 3.2, which will be released fairly soon. Now I asked before this talk and most people said they'd use knockout. I think maybe even everybody. So I'm not going to give you an intro to knockout. This is like a hello world scenario that I'm going to convert into a component. So you probably all understand this immediately. I've got a view model with a name property, which is observable, and I'm binding this to my view. And then I've got a text box here whose value is that name property. And then I'm saying I want to output the uppercase version of that name into a strong element there. So it'll show up on the screen. Let's just run it. And it will do exactly what you expect. So when I enter a name into here, then the uppercase version shows up here and everything stays in sync. Straight forwards, you've all seen that kind of code before, nothing clever. Now how can I convert this into a reusable component? Well, let's use the new components API. So I'm going to say knockout.components.register. And then I'll give a name to my new component. And I can call it anything I want, but I'm going to call it name editor. And then I give a configuration for my new component. And a component consists of a template and a view model. And these can be loaded from many different places. This is all pluggable. You can get them from AMD or you can hard code them in or whatever you like. For this Hello World demo, I'm just going to hard code the template straight into my config here. So I'm going to say template is this string. And I'm just going to cut this out here and drop this in here. And similarly on this line, I'm just going to drop that in there. Now of course, normally you would really load from external files. I'll show you that in a minute. But this is helpful to get started. And then I'll define a view model. And I can define that in a few different ways. But the way I'm going to do it here is a constructor function. So here my constructor function is going to define a name property. And I'm going to give that the same thing that we had before. So here's my name property of my component view model. Okay, good. So now I don't actually need this old view model at all anymore. And I can get rid of it from here. And if I want to use my new custom components, I can do it just like this. Name, editor. Great. A custom element. Let's see how this works then, shall we? Come back to my browser and reload. And you'll see it's still working as it did before. And this is now a reusable component. So I can, if I want to, let's say, well, let's have three name editors. Why not? And then when I go back, I've now got three name editors, which are all independent. They've all got their own view models and so on. And it's going to efficiently load the view models and the templates, what's it called, in parallel as it needs to render that UI there. Okay. So that's all very good. And there's loads more that we can do with components as well. For example, we can pass parameters into them. We can get parameters back out of them. We can subclass them. We can load them on demand. We can preload them. You've got a lot of opportunity there to compose a large application out of this system. And you may notice that this somewhat resembles the forthcoming web components notion, where you define custom elements and give behaviors and such to them. And yes, that's of course exactly what it's inspired by. But rather than waiting another like five years or whatever until every browser that your customers use supports that, you can just use that now even right back to IE6 because of the backward compatibility that we prize so highly. So that's a sort of hello world of components. But in this talk, I don't want to stop at this hello world level. I want to give you an idea of an application architecture that's realistic and could actually scale up to build a very large project. And of course, testing a realistic large architecture involves making a lot of decisions. What libraries are you going to use? What kind of modular loader are you going to use? What kind of testing system are you going to use? And there are so many decisions there that you could spend weeks just thinking about and reading people's blog posts and changing your mind over and over. So would it be nice if you could just sort of scaffold up a nice happy starting point just to see how this works and you could even build on that realistically to make a very large application? So scaffolding systems. What scaffolding systems are there? Well, there are ones built into things like ASP.net and other server side frameworks. But besides that, you're probably aware by now that the front end world is kind of a thing in its own right. Front end developers, that is people who build applications that run in the browsers, well, we've got our own preferred technology stacks. We've got our own libraries. We've got our own conventions and culture, our own thought leaders. Front end development is a thing now. So if you're going to get good at front end development, you probably do yourself a favor of understanding these front end technologies. And so what I'm going to show you is how we can use a scaffolding system which is kind of a de facto standard in the front end world called Yeoman. And this allows us to scaffold our starting points and different application pieces for many different technologies. So there are scaffolders for pretty much all the frameworks you've heard of and of course knock out is one of the things that there are many different scaffolders available for. So let me give you a little demo of scaffolding something up that produces a realistic architecture for us with components. So I'm going to, we're going to need a little scenario for an application that we want to build and it doesn't really matter because this talk is about the architecture and not about the actual application itself. But just as a happy little gimmick, I decided, okay, let's make a website for like a cable TV company or something that wants to display an online TV guide and lets people navigate through channels and see what's on and that kind of thing just to set us a bit of a scene for us. Now we need a back end that's going to provide the raw underlying data for that and so I've already implemented that and as it happens I've did it with web API but the technology there doesn't matter at all. I could have done it with node or with basic or assembly or whatever like crazy thing that you want to do as long as it spits out JSON then our front end doesn't care and we're going to keep the front end totally separate from it. So I want to scaffold up a front end for this and at first I'm going to need to install the yeoman tool so I'm going to go NPM node package manager install globally yeoman. So like pretty much all of the other front end tools, yeoman is built on node.js and so we'll use the node package manager to install that and this is going to go off and install it for my user account and it says okay everything's looking good you've installed yeoman well done. Now yeoman doesn't come with any template or maybe it does I don't know but it doesn't come with all the templates that you want by default. So let's install the knockout template into it. So let's say NPM install globally the generator that's what yeoman calls them all called KO for knockout. So there are various different generators available for knockout and this one called generator KO that's the one that I've put together so I can vouch that at least it's sane some of the others are probably really good as well but I don't really know. Anyway we've got that now so we can use this generator. So let's go into the folder where we're going to spit out the code. So we'll go into the TV guide project here and I'm going to make a new directory called TV guide dot front end and I'll change into that directory and now I'm going to use yeoman. So I'm going to say yeoman I would like you to please scaffold up a knockout application yo-ko and that's going to go and do its thing now and firstly it starts with this slightly embarrassing looking ASCII art thing don't blame me for that that's just what yeoman does by default kind of that's how it rolls we can ignore that we just have to answer its questions what's the name of your new site okay how about TV guide that makes sense what language do you want to use ooh we could use typescript or JavaScript well I'll get on to typescript later let's just do some JavaScript for now do you want some automated tests with jasmine and karma yes please why not I'm not going to talk about tests immediately but I will get to them hopefully before the end of this talk so that is now going off and it's using Bower the JavaScript package manager to fetch all these libraries that we're going to use knockout jQuery jasmine require js and so on and it's also installing a test runner called karma that I'll show you in a little bit alright so that's now gone and done its thing and if I look in this folder now you'll see there's quite a lot of stuff there but it's a little bit difficult to understand it through the command line so let's look at it in visual studio now I'm going to do this slightly naff thing here of doing it as a website project so I'm going to import these files as a website project and that allows visual studio to just look at the files that are on disk and not have any actual you know CS project or anything like that now if you were going to do this for a longer period you probably would want to use a web application project which would work absolutely fine too you then just have to keep remember to add files as you go along or of course you can just not use a visual studio at all you can use sublime or anything else and then you don't have to think about that sort of stuff but of course this is going to get way better with the new esp net vnext tooling which is going to take away the need to think about things like project files but anyway for this demo it's very convenient for me to do it as a web application project in a real project I would either use web application or I would just use sublime anyway what have we got in here so we've got some node modules because the build and test system that I'll show you is like most front end tooling built on node so we've got various things in there to do with gulp and karma I'll show you that later we've also got a test folder you can guess what's in there we'll get to that and we've also got some other stuff to do with build and test that we'll think about later so now let's just look at this source folder what have we got in there well some stuff is kind of obvious we've got css and html you know what those do we've also got bower modules this is why bower has installed the javascript libraries that we're depending on knockout and require js and other stuff and then the real application code is in these two folders app and components now in app we've got things to do with the application startup so that's the routing configuration and where the module should be loaded from and so on and then we've also got components and let me actually run this before I show you the component source code so if I want to run this all I have to do is point any web server at all to this source folder because it's just static files I could use is or anything else I like engine x anything you want but for convenience I'm just going to use this node based HTTP server which is a command line tool and I'll tell it to serve up the contents of this source folder so that's running now and I can open that in my browser so let's go to localhost 8080 and you can see here is my starting point for my application and let's just check there's no errors there's no errors everything's good okay so we've got this simple bootstraps based UI here we've got the traditional home and about pages and as I navigate around it's doing this client side routing there I'll I think I'll call it routing since I'm British it's doing client side routing there and you can see that up in the URL and it's got no real functionality other than you can click this button and it's going to just change a message just to show you how it works so let's see a bit of code there the about page component is exceptionally simple it's nothing more than a single static HTML file and that just shows that a component doesn't have to have any more than just static HTML if that's all you want but of course most components will have a combination of a view and a view model so the home one for example has got this view here you can see it's got that message and it's got a button that you can click that does something and when we look at the code there you can see that what this is is a class that's got a message property and when you do something it changes the message so that's how that works and also it's been defined as an AMD module which allows it to be loaded on demand if that's what we want and we'll get to that in a minute okay so that's our starting point but let's add some functionality to this I want this to be a TV guide website so I want to fetch some data about what's on TV and display it in a nice sort of grid format so I'm going to do this by creating a new component and I'm going to call it a program grid and then the idea is I can reuse my program grid and give it different parameters anywhere I'd like in my application so I could create a component if I wanted by creating the files directly in Visual Studio but it's slightly more easy to scaffold it if I want so I'm going to go back into this folder and I'm going to ask Yeoman would you mind be so kind as to create me a new knockout component and we'll call it program grid so that is going to scaffold up the files needed program grid HTML and JavaScript and it's registered it in my application startup file so now if we come back to Visual Studio and we reload you'll see we've got our program grid down here and this is a nice new reusable component and let's see what's in there not very much currently it's just a sort of hello world thing where it displays a message and it passes that message from the view so here my constructor sets a message property with some observable object and that is what gets rendered in the view it's also got a dispose function on the prototype there which you can use for any cleanup if you want to but I don't need that in this example so let's get rid of that and we'll just keep it a bit simpler so if we want to use this program grid from somewhere else in our application it's very very easy indeed all we have to do is just use a program grid element now you don't have to use custom elements if you don't want to if you like you can use the knockout component binding and bind a component into a div or whatever else it is that you'd like but I quite like using this custom element so that's what I'm going to do and now I don't need the rest of this view so let's get rid of that and we'll just change the title to what's on TV okay so now let's go back to the browser and we'll reload and we should see that the title changes what's on TV and we can see the program grid has been injected and bound for us just like you would want it to be and the good thing here is that the home component doesn't need to know anything about the program grid component at all it's loosely coupled which allows your code your components to be quite easily reused in different places and it gives you lots of interesting opportunities when it comes to optimizing your build system as well as I'll talk about in a minute but we can still do things like pass parameters in and get data back out right then so let's put some real functionality into this program grid now I want to actually fetch some data from my back end and render it so this is I'm going to do it in a pretty straightforward way just because this doesn't need to be complex here's a very simple way of getting and rendering some data I am just going to define a channels array on my program grid here so this is an observable array because it can change over time maybe we would use web sockets to push new information in real time or something it doesn't matter but in any case I'm just making it observable so it can change and then I'm populating it in an incredibly straightforward way just do an Ajax request to the back end and stuff the result into the channels array and we're done let's render this in the view now shall we I'll go over to the view and I'll just delete the stuff that I had before I'm going to drop in some markup that I've already prepared so my pre-prepared markup here is going to use an html table and it's going to say in the body of that table iterate over each of the channels and for each of the channels let's create a table row and on each row we're going to have two columns the first column will display an image with the TV channels logo and then in the second column will iterate horizontally across all of the programs and for each program will display a div with the title start time and end time and so on so let's see if that works shall we I think it might not work to see but let's just see so let's hit reload and we'll see nothing seems to be happening and oh dear we've got a connection refused from the back end that's just because I haven't started my back end running just yet and I just realized that a minute ago so let me start my back end running now with a bit of control f5 magic there and so now I can reload and this time it successfully fetched some data from the back end there and we can just see all these different TV programs and stuff but the layout is absolutely horrific right now so let's use a little bit of CSS to end this up and this talk is not about CSS so of course you can use less or sass or whatever you like and you can plug that into your build system that I'll show you later but I'm not really interested in that so I'm just going to dump a bit of ready-made CSS into this file right now just so that we can move on to something more interesting so here's my ready-made CSS I'll come back and I'll hit reload and now you'll see it really does look like an actual grid of TV programs that you would expect to see from your cable TV company or whatever sorry that the title is a slightly distracting alright so that's good but currently I've not really shown you anything particularly clever like currently I'm not even passing any parameters into my grid what if I want to control which channels show up like maybe we want to show all channels or maybe we just want to show the channels that you'll subscribe to so let's have a go at passing some parameter into there I'll go back to where the grid actually gets used and I'm going to say I'll pass a parameter prams equals let's say only my channels true so now I'm passing that parameter in and if I come back and reload nothing changes at all because my component doesn't know anything about this particular parameter name so let's make it aware of that so I'll go into the view model for that and I'm going to define a new property on my view model here called Fint filter channels and what that's going to do is it's going to take the existing set of channels and it'll run an observable filter over that array so that'll keep updated as the underlying array changes and what it does is it works out whether or not we're currently being asked to run a filter and if we are then we'll only use the channel if we're subscribed to it and if we're not filtering then we'll just use all channels so now if I come back and reload then why didn't that do anything I think it's because I didn't really reload properly then nope not for that reason maybe I didn't type it correctly some some way only my channels true oh that's right because currently I'm still binding to the full set of channels I want to bind to just the filtered channels so now if I reload you'll see we just get the filtered channels there so that's how we can pass a parameter in and of course it doesn't have to be a hard coded value like I've shown you here it can be an observable property as well and that will automatically stay updated and now we've got this we can reuse our grid in various ways with different parameters so let's have all channels down here and we'll say only my channel is false and now when I reload we're going to have two grids now we'll just have my channels at the top and we'll have all channels below it so that makes it very nice and convenient to reuse okay now let's change our focus slightly let's think about performance for a little bit or at least performance in terms of how this stuff is delivered to the browser let's see how many HTTP requests we're currently using so if I go into the about tab here and I reload then I look at the let's look at the network tab if I zoom in a bit you'll see we're making 18 HTTP requests to run that page even though it's completely trivial what HTTP requests are we doing? Well we're loading bootstrap and require and jQuery and knockout and crossroads and bootstrap and then we're loading all of the components like we're loading the about page we're loading the navbar template we're loading the navbar view model everything is loading separately and this is in some ways good and in some ways bad now it's good in that in the files that we're seeing in the browser dev tools exactly corresponds to the files that we see on our IDE which is really convenient in development and another good thing is we've got incremental loading here so if I start on the home page and I reload and then I clear the list of requests as soon as I switch to the about screen you'll see it dynamically fetches the template there so we've got automatic dynamic loading of different views and view models as we go along because it's all built on required.js so that's in some ways good but it's also really bad because we're just doing loads of HTTP requests wouldn't it be nice if we could bundle them and minify them you're all familiar with bundling and minifying right so let's say that we do want to do some bundling and minifying how can we do that well this brings us on to the topic of JavaScript build systems and since this talk is not all about knockout I'm also just want to cover some general principles for writing efficient single page applications let's just think about build systems for a minute so you are all familiar with other build systems like MS build or enant or something I don't know what you use how many of you have used either grunt or gulp before okay reasonable number like 20% okay I'll go through this fairly quickly then because a lot of you know this so these are JavaScript build systems that are like most front end tools built on Node.js and the idea is that for example with grunt you run it from the command line and it's going to go through a series of tasks that you've configured maybe to do things like link your code to come to bundle it to minify it to output it to a certain location and you run all that from the command line and that's very convenient and it's all fully designed to work with front end technologies like things like cof script type script all that kind of stuff so that's good now let's just compare these two things a little bit grunt has been around for a little bit longer of the two and what it's like to work with grunt is like this the configuration system is fairly declarative so if you want to configure for example a concatenation step you would declare oh you're going to get all the files from this location you're going to output to them to this other location and you would use declarative config for all the different tasks that you want it to do and you would also get it to load the code that executes those tasks from npm that's the node package manager and then finally you would give names to your tasks for example you say that the default task involves running the three three different steps in sequence queue in it and then concat and then minify and this is quite nice actually I do like it I've used it for over one to two years now this is what we use to build knockout and it generally works pretty well but there's also this newer thing that's come along more recently called gulp and the argument with gulp is what about if we don't want to keep dropping all these temporary files in different locations and picking them up and generally having to figure out different declarative config syntaxes wouldn't it be nice if we could just stream our files through a configuration that we define in code and so what it's like to work with gulp is a little bit more like the following now I've I started using gulp maybe three or four months ago and I really like it actually this is generally what I'm considering as my default system for new projects now I do enjoy it but that's not to say that grunt isn't still good so what it's like to work with gulp is a bit like this you start by declaring some some imports that you need to execute the various tasks that you want and these will all come from npm like the code to minify stuff and so on and then you would also declare tasks that you give a name to so you might say that when I want to process my scripts which is just an arbitrary string I want you to grab all the files under a certain directory and then I want you to pipe them through js hint to check for any errors and then pipe the results from that through a minification process with no temporary files this is all in memory and running in parallel and then pipe that all through a concatenation step and pipe all that out back onto disk and similarly for css maybe you'll do a similar thing except that you pipe it through a less processor and then finally you give names to the the tasks that you're working with so maybe your default task involves running scripts and styles in parallel because it's all going in parallel through streams and maybe you also want it to watch all the files in a certain folder so that when you change something it's going to rerun certain tasks so that's what it's like to use gulp and I really like it so that is what this scaffolding system sets up for you by default let's have a go at using it shall we and before we start I want you to realize and or remember at least the situation that we're in right now so the situation right now is that when you reload this about page we've got 18 separate HTTP requests going on to fetch all the different parts of the application and that is a bit much to be completely honest also notice that in the application folder we've got a source folder here but we have not got a disk folder and disk is where we're going to put the build output so we'll see that appear in a second now we have already got this gulp file that was set up for us I'm not going to go through every line of it but just to give you a quick overview it's got various tasks things like processing JS, processing CSS, HTML, cleaning all the build output and then finally it declares that the default task if you run it with no arguments involves running these three other tasks simultaneously and then giving this message so I will show you a little bit more of that in a second but let's just run it first so I'm just going to run gulp on its own to run the default task and that's going to run these things that have been declared by the scaffolder so that's doing its thing now it takes a few seconds it's going to take like seven seconds and of that seven seconds more than six of them are just running ugly file.js so that's pretty much all the cost of doing that if you just temporarily comment that out it will all go really fast but I want to have that on for this talk so that's output everything to the disk folder so if I come back to VS now and I hit reload we'll see a disk folder has appeared and it hasn't got very much in it really it's got one CSS file one HTML file one JavaScript file and some web fonts we won't worry about those things so it's got the what on earth is that supposed to mean go away so it's got these three files that there's basically all that we need to run our application and if I want to run that now I'm going to stop my web server that is serving the source folder and I'm going to start the web server serving the disk folder instead so this is what you would actually publish to the public internet and people would load to their browsers and now if I come back to my browser and I hit reload then instead of doing 19 requests it's now done three requests one HTML file one CSS one JavaScript and everything has been nicely bundled up into there and I'll show you more about how that works in a second but we're not completely finished yet because it doesn't quite work if I switch on to the home screen we'll get an error what's this error then we're getting a 404 not found it's trying to dynamically load our program grid and it's not there because the program grid isn't there is a standalone file in the disk folder so why is this is this some kind of a bug like why didn't include the program grid in the build output it's not a book otherwise I wouldn't have shown you I would have pretended it wasn't there it's quite deliberate so the system of components is very deliberately all about being loosely coupled and it's so loosely coupled that the required JS optimizer that walks through the dependency graph to find out how all of your code depends on other code doesn't even know that you're using the component it's just too loosely coupled and also sometimes you're going to want to preload your components and other times you'll want to dynamically load them so you need to declare which components are going to be included in the preloaded bundle and that's what I didn't do just yet so let's do that I'll go to my gulp file and you'll see up here this is the required JS optimizer config the required JS optimizer is the thing that understands all the different AMD modules that I've got walks through them understand the dependencies and is able to output bundles and currently it's including in the default bundle everything that the app startup file needs so that's all the library code and the routing config and everything and then I also explicitly have to reference any components that I'm using that are not known to the startup file so you can see the navbar the home page and the about component because that's nothing more than an HTML file you have to use a slightly odd syntax to import it because it has to get converted to a JavaScript wrapper anyway I want to import I want to include the program grid component here so I'm going to reference that it's in a folder called program grid and the actual module name there is program grid so that's now included let's go back and I will rerun gulp there and then that will hopefully be included in the scripts.js bundle file when it's outputted so now that's done I'll come back and I'll reload and instead of getting an error this time I will get my actual application working exactly as it should so that's good or is it's good really let's just take a step back for a minute so what we've accomplished now is that we're now preloading absolutely everything in a small number of files and that's kind of cool because we're doing a small number of HTTP requests but it's also not cool in a certain way because we're preloading everything even the stuff that the user doesn't even see and this is a bit of a problem for us on the Azure management portal right now because as it stands we preload every single thing there is whether or not you are ever going to see it and that is too much stuff really so we are working on producing a system now where it preloads some things and dynamically loads other things and out of the stuff that's dynamically loaded you don't still want to get all the files individually you still want to declare bundles that represent the sort of units of navigation that a user will normally do so you preloaded the right stuff and the other stuff comes in appropriately sized bundles can we do that with this build system of course we can otherwise I wouldn't be talking about it so let's go and have a look so you can see that we've got this bundles config here now require.js only got bundles support proper bundles support in the last few months so I'm betting that most of you haven't really used this bundles feature just yet but it works really well so what I can declare is arbitrary names for other bundles that will be packaged and loaded as a unit so let's say that I don't want to load the about page up front I only want to load that on demand so I'm going to take it out of my list of preloaded things there now I'm going to create a new bundle and I can call this anything I want let's call it about stuff alright and I can put an array of all the AMD modules that should be included in that bundle and I'm just going to put this about page thing in there now it's just a simple html file but there's no reason it's limited to be that it could be any AMD module including one with dependencies that have other recursive dependencies and so on and the bundler will figure all that stuff out for us so now when I come back and I'll reload gulp again instead of producing just a single scripts.js file when it's finished has it finished yet not yet here it comes if I come back and I reload my mouse is not working seriously my mouse is not working what's going on that's strange okay I'll hit reload now instead of just having scripts.js we've also got about stuff.js so that's been outputted as well and if we go over to the browser and I come over and I'm on the home page and I hit reload it currently is loaded everything it needs but it hasn't loaded anything to do with the about page at all and if I go to the network tab and I clear what it's already got there and I switch to about you'll see it dynamically fetches about stuff.js because it knows that the files it needs are in that bundle and inside there you'll see there's just the stuff that we need to render the about page it's just trivial right now but it could be a lot more and the important thing to understand here is that this bundle config has no impact whatsoever on my application architecture in development I do not have to think about this at all I just work with all the files as they are on disk and then the choice of bundling strategy is something that you can think about when you're going to production and as a sort of matter of DevOps so your DevOps team or you if you do DevOps as well can think about different bundling strategies and try out them different strategies without affecting your application architecture in any way at all and that's a really powerful and useful feature of this system. Okay right so that's one aspect of an important feature when building a large single page application is thinking about how the content gets delivered to the browser. Another aspect that it would be rather remiss of me not to mention at all is testing. Now how many of you test your JavaScript code? Alright so that's a lot less of you than write JavaScript code and I can understand that that's something I can definitely relate to because if you're working on a relatively small project testing JavaScript is an enormous overhead and is it really giving you the value that you need on a small project arguably not I mean what's the worst that could happen anyway I mean does it even matter anyway on a large project you don't actually have a choice because you will fail if you don't have decent tests for your large single page application and there are lots of different ways that you can do it. There are so many different choices for example you can do traditional unit level testing on your classes with mox you can test at a component level if you want to maybe you're still using mox at that level or maybe you're letting them use real services or you can even test the entire application all at once with a browser automation tool like Selenium or something like that. Now I will not say to you that any one of these things is the right way or that you should do more of one than another or anything like that because honestly I think it depends on the type of application you're building and where the value of your application is where is the business logic does it only make sense at an end to end level does it make sense on an individual class level that's up to you to decide. The only strong opinion that I'm going to give to you is please be selective about what types of tests you write probably the only wrong strategy is to just go let's test all the things in always possible because that's going to cost you a lot if anybody says you should just write every possible test of everything then you should probably punch that person and well I mean I am not a lawyer but legally I think you would be okay doing that I mean I haven't consulted a lawyer it's just my guess because yeah exactly because it's such a dumb opinion it's not going to cost you heavily to do that be selective about what you write tests for and make it match the places where your application has value. Now I cannot tell you that there's only one right way of doing testing but I can show you some examples of testing technologies. So this scaffolding system that I used here that sets up some tests with Jasmine and Karma. Now the notion of best practices in front end world has a half life of about three months so by the time anyone watches the recording of this it might have changed but as of today Jasmine and Karma are very much considered to be best of breed testing technologies so that's what this is going to use. So let me show you a little bit of how this works right now. We've got this test folder and inside the test folder we've got Bower modules to do with testing like Jasmine and we've also got some stuff to do with running the tests and then we've also got a sample test for the homepage component. It's very trivial let me show you what it does right now. So what it does right now is it uses Required.js to pull in the object that it wants to actually test then for this example test it creates an instance of homepage view model and it checks that the initial message is some value then it changes the object and it checks that the message changes in some way. So this is obviously trivial and a good quality valuable test would be exercising some kind of business logic which this does not but this demonstrates the testing technology and that's as far as we're going to get in this talk. So let's have a go at running this test shall we. You can run it in various different ways but the first way I'll show you is running it in a browser so I'm just going to open the Synglex HTML page in a browser and when that pops up you'll see here's my test running through the Jasmine browser test runner. You won't always want to run your tests in a browser but it's really good to be able to do so because of course you've got your debugger built into the browser there and that is absolutely invaluable when understanding why your tests are not passing or even worse why they are passing when they shouldn't be. So you will use the debugger very slowly to solve that problem but you don't always want to be working in a browser it can be very convenient to run your tests from the command line and that is where Karma comes in. Many of you use Karma, smallish number we're talking 5 maybe 10% at the most there. Alright so not many people are using this yet but it's growing in popularity and with good reason because it's really good. It's a great tool if you are into your single page applications. It's a command line test runner and so the idea is you run it on the command line it opens up real browser instances like actual instances of Chrome or IE or something and then it pushes tests into them and uses web sockets to pull the results out of them so it can get the tests and the results very very fast and give you really great continuous feedback as you're coding and of course being command line driven is very easy to factor into any sort of build or CI process that you've got. Now if you want to run this you need to define a Karma configuration and that's what has been declared, that's what's been scaffolded out for us by this system. Now to be honest with you I'm slightly disappointed with this choice of file name here. If it's me I would have called it Karma Karma Karma Karma configuration which I think it would have been cooler but they apparently didn't think of that so it's rather boringly karma.conf and what that does is it tells Karma where to find everything that you're using and it's a little bit fiddly to set that up because to get Karma to work with Require.js, to work with Jasmine, to work with Knockout components, to work with everything else that you're using simultaneously it's pretty fiddly and it might take you a couple of hours to get that working or it did me at least but thankfully now I've done that that's all there in the scaffolder and you can just use it. So let's have a go at running Karma on the command line. So let's say Karma start and what that will do is it will fire up a browser instance and it's going to start pushing tests into that as much as it needs and if we look back at the command line here you'll see it's executed one of one tests and believe it or not it passed great. Okay so that's good but now I want to show you how it gives you feedback as you're working. So I'm going to move this down to the bottom of the screen here and make it just occupy this little bit of the bottom there and I'm also going to move my VS window a little bit so we can still see that. And now let's write some more tests shall we? And so let's start with it and then because I don't actually have any business logic in this application this is obviously very fake so I'm just going to do a silly arithmetic test but you will understand how you can apply this to exercise your real logic. So let's do it should do arithmetic. Bit cheaty but I know. So let's declare a function here that our test will run and as soon as I press the save button here I'm going to click now immediately it realized that that test is there and it's going to run it and now we've got two tests executed and they both passed. Well done Karma. Alright let's put an expectation in there. Expect 1 plus 1, 2 equal 3 because I'm a moron. So let's try running that now. I'll press save and then it fails would you believe it? Oh let's review arithmetic. We'll fix that and we save it and it's working. Now the cool thing about this is it's not just watching my test files it's also watching the files that are being tested. So if some developer comes along and looks at this home view model and says oh do something that's not a very descriptive name is it? Let's change that to something else. Let's change it to change the message there. I'm a good programmer I've made the code better. As soon as they press save they'll go no bad programmer don't change that because the view depends on it being called do something so it's great to have that feedback so they're going to go obviously controls add enough times to make it go back and save and then it's going to be passing again and we know that things are good. So I would totally recommend trying out the Karma test runner for you. You can make it so it only runs certain tests and not all of them which you may need to do if you've got a very large test suite and you can't run them all every time you save anything. So that's really good and that's of course all set up for you by this Yeoman package. Now last thing that we have got time to talk about TypeScript. I bet everybody in this room has seen TypeScript before. Is that right? Hands up if you've seen TypeScript. Yeah I bet you all have and I bet most of you have at least tried it out as well. So I'm not actually even going to demonstrate this to you because it would be boring. All I would do is I would run the same scaffolder as before and when it asks me I would say yeah I'd like to use TypeScript please and then all the code would come out in TypeScript and then it would all work exactly the same as before, even the tests except that you have to compile before you run anything obviously. But other than that it would all work the same as before. Now what I think is valuable for me to communicate over the next 10 minutes or something is not the basics of TypeScript but rather what I think the pros and cons of it are. So I've been using TypeScript to build this management portal on a very large project for about a year now and I've got some pretty strong opinions about what's good and bad about it and I'm going to give you my opinions and hopefully that will be useful when you're thinking about whether to use it in a project. And as you will find out these are not marketing opinions. I would not get this sanctioned by marketing but that's okay because I haven't checked it with them. All right so if you haven't seen TypeScript just to refresh your memory it looks like this. So TypeScript is compiled so it needs to know where your files are so you use reference statements like that. Also if you're using AMD modules you can do these special imports and that fetches an AMD module asynchronously into your code there. You can also declare things like modules which are equivalent to namespaces and classes and when this compiles to JavaScript what we'll have here is an object, oh sorry a function called myapp.data.transaction repository and it's a function because of course in JavaScript all functions can act as class constructors so that's what it compiles to. Then we can define things like private properties on there and give them types. We can also define a constructor and the contents of that is of course what's going to go into the body of this function that it gets compiled to. We can do more. We can define things like methods just like you do in C-sharp and the parameters and return type are typed there and TypeScript will of course enforce that type checking at compile time but the types don't exist at all at runtime it's purely an artifact of compilation. JavaScript does not know about your types so they just checked compilation time there and also we can do things like type inference so you see this URL variable there I haven't declared type for it but the TypeScript compiler knows because it goes oh that's clearly going to evaluate as a string here that's going to be a string and then it will do all the type checking with that as a string so that saves you a lot of typing. Then it's also got some nice syntactical improvements like you see we've got a lambda function here just like in C-sharp you've got lambdas with the equals bracket thing and not surprisingly that compiles to a JavaScript function that works as you like and that's nice and then the final cool thing that it does is that of course it's got so much type information going around that the tooling can give you good feedback as you're coding with things like IntelliSense so that refreshes your memory hopefully of what it's like to write some TypeScript code and that leaves me on to this question is it a good thing or is it not a good thing? Now if you had asked me that question six months ago I would have struggled to give you an honest answer without being at risk of being fired because I did not like it one little bit. Oh no it was not nice as far as I was concerned I was having a bad time with TypeScript because I was working on a massive project and every time I typed anything I would have to wait multiple seconds before my characters would appear in Visual Studio and then they would probably have red squigglies on them even if it was perfectly valid code and I would be like what are you doing and I have to close and reopen files and then I would eventually try and compile my file and then I would immediately open up the Windows Task Manager and I'd look at the memory usage of TypeScript compiler and it would be like 200 megs, 300 megs, 400 megs, 500 megs, 1 gigabyte, 2 gigabytes and my fan in my laptop would be screaming and my fingers would be melting onto the keyboard and I'd be like ah what's going on and eventually it would all finish with this. We're forcibly killing TypeScript compiler and in my team we got so used to running this command that at one point somebody was going to get t-shirts printed with this slogan on it and eventually someone told them that that was a bad idea so they didn't do it but you understand how we felt at that time. But thankfully since then the TypeScript team have released the version 0.9.7 of their tooling. In fact they've gone to 1.0 since then but 0.9.7 is where everything changed. You can still hear me right? It's sounding strange to me. Okay so in 0.97 everything became so much better. It didn't eat up gigabytes of RAM anymore, it wasn't crashing Visual Studio, the Intellisense actually worked reliably, it was a completely different business after 0.97 so that was an enormous relief to all of us. So generally speaking you can tell I'm more positive this now but I want to still give you the most honest view of I can of this. So I would say that if you're using TypeScript on a large project now sometimes it's bunnies and sunshine and other times it still feels a bit like it's raining blood onto you. So in the spirit of honesty here are the top five best things in my opinion about working with TypeScript and the top five worst things that you still deal with. So let's do the good ones first. The bottom of the list, number five best thing about working with TypeScript is that you can write a code in a C sharp kind of object or into a type away. And you probably like that, I mean most people who do it like it I do anyway so I'm generally positive about this kind of thing. Number four, typo is a very rarely a problem when you're using TypeScript because of course the compiler is going to catch them for you. Very unlikely that you're going to get a typo in production that brings your application down. I appreciate that. Number three, it does have a pretty good syntax, I really like it, it genuinely improves on native JavaScript. So the fact that we can do things like modules and lambdas, I really do appreciate that. So thank you TypeScript team, that's good. Number two, best thing about working with TypeScript, the really big guns now. This is what TypeScript is all about, the fact that you've got strong typing and generics. Now the generics in TypeScript is absolutely gorgeous, it works so well and I really, really appreciate it. So a few weeks ago I was working on some quite complex data structure code with lots of nested generics and it was so great to know that as I refactored it it was going to tell me where I'd forgotten to add an extra generic parameter and so on. So I really, really appreciate that. Number one, best thing of all working with TypeScript, you don't have to remember your own APIs anymore, you can just intelligently go through the entire coding experience and you just don't have to keep remembering stuff. And speaking to someone with limited mental capacity, I really appreciate the fact that I don't have to remember everything all the time. So that's great. Now there are some things that are still not all that lovely and on a bad day I can still feel a bit depressed about it. So number five, not so good thing, well you see I really like JavaScript, I really like how dynamic it is and I like to do some crazy dynamic stuff with all the sort of dynamic function invocation and looking at the arguments array and all that stuff and you can still do that with TypeScript but the only way you do it is by declaring your variables of Type any which just means don't type check this variable. And so it makes me a little sad that I can't somehow have both the dynamic and strongly type things together but I guess that's just a logical limitation, you can't really fix that. But anyway, number four, thirdparty.ts files. If you use any third party JavaScript library which obviously you do then TypeScript doesn't know about them. So how does it know what types are in those files? Well you need to give it these type definition files and it's quite easy to find type definition files for any third party library you can think of. Now the only problem with them in my experience is that every single one of them is wrong or is least incomplete or doesn't match the version of the JavaScript library that you're using. So you'll get very used to patching these.ts files to correct all the mistakes that the author of them made and we do that a lot. Okay, number three thing I don't like, very often I'm writing some code and I'm thinking I know this is going to work at runtime, I totally know what I'm doing and TypeScript is like I don't really know that there's a property with that name and then you're oh damn it I've got to go and declare these extra types and just give all these extra hints to TypeScript. But you know of course it's fundamentally a necessity. If you want the benefits of strong typing you've got to also pay the price of telling it what the types of things are. And I kind of would like to live in a world that's not even logically consistent where I don't have to do that. But unfortunately that's not possible so you just have to live with that. Okay, number two thing that I don't really like is the VS tooling, like I said it's got way better than it used to be. It used to be a nightmare, it's now actually quite decent most of the time. And probably if you're working on a moderate sized project you will think it's completely flawless and wonderful. But we're working on a massive project and we still get times when it's given us red squiggly zoning perfectly valid code or IntelliSense just won't show for no reason today. So I'm sure that they will fix whatever the remaining issues are. They will make it perfect, I'm confident but it's just not 100% of the way they are yet. Especially when you compare it to something like the C-Sharp tooling which is just perfect in every way. Now number one, worst thing of working with TypeScript that I don't like, the fact that you're compiling your code at all. I mean if you've spent enough years working with JavaScript and just you save file, reload, save file, reload, the fact that you're compiling stuff all the time and every process that you ever have to create has to involve compilation, it's just a bit annoying. But there are ways of mitigating it. So Visual Studio has got the ability to compile on save individual TypeScript files and you should definitely do that because that will make your life suddenly become good as opposed to really miserable if you were having to rebuild everything every time you touch any file like I did until three weeks ago. So you will make things better for yourself by doing that. So that's my honest opinion. Now if I was to summarize this, would I use TypeScript or not? I think that honestly yes, I would now use it. On a project that gets beyond a few person month's work of work, I think that the benefits outweigh the drawbacks. Honestly I do now. That's not to say that there aren't drawbacks. Clearly they are. I just personally think that the benefits now outweigh them but only on a fairly large project. Now hopefully you can factor that into your own decisions now. Okay, we're coming up to the end now. I've only got a few moments left. So let's just summarize what we've talked about in this talk. Some of it was about knockout, some of it was about general single page application stuff. We talked about difficulties, right? So with staffing, I would say you can mitigate that by using as much standard front end tooling as you can and align yourself with the rest of the front end worlds so that you can stay up to date with modern technologies and you can get people to understand what you're working on. Two, architectures. Do something modular. For example, the knockout component feature that's going to help you a lot. Come up with something like that, page weight. Make sure you've got some system for doing the right amount of incremental loading and the right amount of upfront loading. I showed you one way of doing it. You may find some other way but do something like that. Maintenance. There's lots of options there. You could use TypeScript. You should be doing some kind of testing. You might want to do some kind of linting. Just do some stuff. It's going to make your life easier. Library dependencies. Make sure you pull them in from a package manager like Bower and you're not just inventing your own system for organizing libraries and versions. It will be easy for you. Build and test. Use the features that are available. If you're doing TypeScript, do compile on save. If you're using Gulp, look into its ability to stream individual changes as you are working on your code. It's going to make your life better. Performance and memory. I didn't really talk about this but one thing I would recommend is don't do what a certain team that built a large management portal recently did which is wait until two weeks before you go to production before thinking about memory leaks and then spending two solid weeks day and night in the Chrome debugging tools tracking down memory leaks. Look at them early on. Consider it to be part of your QA process. Just do some basic stuff to look for it from the beginning. Your life will be better. So there we go. Hopefully that will help you in your process of building a large single page application and you never know. It might even be bunnies and sunshine for you. I hope it is. That's all we've got time for. We do not have time for questions. I'm going to be around. Send me tweets if you want to ask some questions or just tell me what you think about this stuff. Please remember to evaluate your session on the way out and have a really great rest of your day. Thank you very much.
examples and docs and such that cover those kind introduce some of the pros and cons of this is the new Microsoft Azure Management Portal. And that, would I say that it's easy to build a probably face if you build a large single page maintenance to some extent. But if you are afford to be leaking memory over time. And that other larger model view frameworks in JavaScript, other different components, which is very useful hello world scenario that I'm going to convert loaded from many different places. This is all get started. And then I'll define a view model. application pieces for many different really matter because this talk is about the project in a real project I would either use web that when you change something it's going to actually have any business logic in this going to demonstrate this to you because it would using TypeScript to build this management portal project. And as you will find out these are not special imports and that fetches an AMD module I would immediately open up the Windows Task help you in your process of building a large