Rendering JavaScript on the Server: Angular Universal
Pieszak, Mark
The web has gone from back-end server-rendered pages, to client-side SPAs,... and back again?? Let's take a deep dive into how server-rendered Angular applications work, and why you might want to consider using it for your next application. Learn how to bring great search engine optimization, social media previews, deep-linking, and improved perceived performance by rendering your application on the server.
 I'm Mark Pysack. I'm the founder and CTO of Dev Help Online. It's a consulting, development, training firm. We're located in Florida right now, but work with a lot of different startups, the Fortune Drive, and our companies right now trying to help them upgrade their Angular projects and basically get their teams up to speed, things like that. Today we're going to talk about Angular Universal. Before I get into that, I wanted to give you guys just a general background and a nice basically history of the web. Let's talk about server-side rendering, JavaScript in general. I think to me it's like the future of the web, or at least for some of it. Anyway, like I said, I'm Mark. Check out our website, Dev Help Online. It's still in the works, so right now it's very bare-bone. There's a really serious photo of me. I'm actually a phone guy. I don't know why. I think I need to update that. I'm actually also part of the Angular Universal team. I work with a couple of guys from the Google Angular core team and a lot of open source people to kind of build upon and improve the Angular Universal, which if anyone's ever heard of it, it's basically rendering Angular in Node. So get into that. So just so you remember my name because it's kind of silly, it's Mark Pizak, but just felt funny. It's Polish, so go figure. You can find me online at markpizak. I try to blog as much as I can, hopefully more soon. But if you want to talk about anything Angular in general, just hit me up on Twitter, always for your chat. All right, so story time. I kind of wanted to start out with talking about, in general terms, the web, right? Where we came from, where we've been, and kind of at least where I see it going. And to me, it kind of, obviously, it started way before this, but everything started out kind of server rendered, right? So we had things like PHP.net, anything, a JSP, whatever, right? And there was a lot of pros to that, a lot of cons. So kind of to get started, let's say, I'm just going to generalize the whole period of time and call it server-side rendered, right? Obviously, it's gotten a lot better since then, but I kind of wanted to have some laughs and how bad it used to be, right? So this used to be Google, pretty ugly, right? I mean, this was Amazon, if anyone remembers. And we used to do a lot of chatting. There was instant messenger. There was chat rooms. And some things have changed, but some things kind of stay the same, right? Everything's been replaced. Now, we have Facebook Messenger. We have Slack. And we've almost gone full circle, right? It's pretty strange, but it's the way the world works, right? So some of the things with server-side rendering that I thought was always really beneficial and they did well was, you know, we didn't realize how good we had it back then when, let's say, you're doing a PHP app or whatever. SEO is as easy as just basically adding a bunch of tags, right? Just meta tags or title. It was super simple, right? It was great for static sites, a lot of other things, right? But some of the things that, you know, it was lacking, right, was mainly user experience. You know, we had to get to any page. You had to do a full reload, right? Everything constantly. So, like, it wasn't that rich immersive experience, you know? So, you know, and everything, there was a lot more server requests in general, right? So, you know, what did the web do? You know, flipped everything upside down and all of a sudden the cool thing was single-page applications, right? So, whether you did a hybrid with a little jQuery or you went full react or Angular, you know, what have you, single-page applications now are cool, right? Kind of cool. So I'm going to call them client-side rendering from now on, like CSR. So if you've never seen these acronyms, don't worry. I think we made them up. So, but with single-page applications, basically this happened and we had this massive ecosystem which is basically a nightmare to work with and every few weeks you kind of felt like this, right? I mean, you're all, you kind of were never sure of yourself. It's like, am I making the right choice, you know? One day Angular, next day View, then there's React, then there's a million other ones. So you get a little frustrating. But some of the things that client-side rendering does really well, of course, is user experience, right? So that's kind of why everyone switched, right? So we got that really immersive experience, you know, everything you could immediately see when things were happening, right? The really quick page transitions. It's perfect for really complex web apps and things with real-time data. And you know, the best thing is really you just, it feels like things are happening, right? And maybe a modal moves, there's animations, right? You can't do that with server-side rendering. So a lot of good stuff. But some of the downside, right, of course, is no SEO, right? So typically when you, you know, view source on any front-end app, this is what you see, right? You just basically nothing. And it's not personalized for that exact route or anything, right? So basically nothing. And of course, it generally longer load time. So you get to that route, and then you have to load, you know, megabytes of JavaScript files. And then all of those have to run and process and then bootstrap your app. So you see this a lot. And that's also kind of a con, right? I mean, if someone is on a slower network, let's say 3G, and it takes five seconds for your app to start up, you know, Google's done experiments and stuff on this. Maybe if a page takes longer than three seconds, most people will actually leave. So you actually get a lot of bounce rate because of that. So once again, kind of not a good thing, right? So with all this together, you know, you basically just rewrote your app. Now you did it in React or Angular. All of a sudden you realize this isn't good either, and your boss is pissed, and then you're throwing your phone on the ground. You know, so what do we do from here? So the goal really, ideally what we want is we want the best of both worlds, right? We want SEO. We want that really quick paint. You know, you see the application right away. We want, you know, if I copy and paste the link to Twitter or Facebook, you want to see that preview with the image and metadata. You know, we want the user experience. We want it to be interactive. It almost sounds delusional, right, if it's possible. So, you know, can we get that, right? So the next kind of shift that I noticed in, like, the web in general was someone in, I think, 2013 coined the term isomorphic JavaScript, which sounds kind of like a weird chemistry experiment. I think it's a crazy word. I prefer the word universal, and I think that's why the creators of it called it that. I mean, the idea of it is basically you want it to run on both environments, right? The browser and the server. In general, like, the how it all works, right? You have your JavaScript code, and we want that same code to run on a server and on the browser. So that's basically isomorphic or universal, whatever you want to call it, which to me sounded like a fairy tale, because I was like, how could you ever do that? Like, there must be a million, you know, that's kind of how I felt. This was years ago when I first heard of it, and I thought it was a joke, you know, I thought there's no way that's possible. You know, I have to see it first, right, to believe it. But someone then explained to me what it really was. So it's basically the code, you have your code, you send it to the server, it's supposed to serialize it, right? So it takes your entire app at whatever URL or whatever portion of it you're at, creates all the HTML for that, sending it to the browser. The browser then in the background, since it has those big bundles, starts downloading them bootstrapping, and at the end of the day, everything finishes, and all of a sudden you have a client side out. Did everybody catch that or did it go too quick? We'll be going over it in a second anyway. So here comes Angular Universal. So I came about to the project about two years ago, and Angular Universal was their solution to kind of handle this and make this work. Because if you remember an AngularJS, which is the older version, right, it wasn't possible to do this because AngularJS was really tied to the browser, right? Everything was based on the DOM and things like that. The new Angular is very abstract. So that's why everything is done using all these abstract syntax trees and things like that. So you're able to create your app in different environments. So if you've ever used native script as well, it's done similarly, right? So native script takes your app and basically renders it on a mobile device for iOS or Android, and it's able to do this because of how abstract it is. So they basically create their own engine on top of Angular's. So Universal does the same thing. The founders of our creators were Patrick Stapleton, you might know him as PatrickJS, and Jeff Welpley, really good friends of mine. So they created this project because they needed this for their projects, right? And Jeff Welpley actually has created a, I think, he has it working in production, but for AngularJS, he actually has a way to server render it. So if you want to find him on Twitter, bug him about it, I think it's online somewhere, I forget the link. So anyway, so these guys actually created it. And to me, it's kind of amazing because the whole project actually didn't come from the Angular core team itself. It's originated by people like us, right? Just random open source people, and then eventually got moved into core this year. So some of the other people on the team, me, of course, right? Jason Jean, who doesn't put his picture online, Alex Rickva and Vikram from the Angular core team, Jeff Cross, who was also used to be on the core team, now he's at Norwalk, and Wessie Cheggman from Saphir, and a lot of other people, a lot of big contributors. But yeah, so like I was saying, it was open source, it was its own repo, and now it's actually part of Angular. So if you've ever tried to use it in the past, it's a lot safer now. It's a lot more tested. And it's actually within the same code base. So you can kind of, it's really production ready now. It was before, but not really. So kind of like we were just showing, so the way we handle it, right, is you take your Angular app, right? So that's your root component, everything inside of it. You're going to run it on Node using something called render module factory, right? This is just like an overview. Don't worry. We're going to take the whole app, basically turn it to a long string, send it to the browser. In the background, we load all of your Angular bundles, everything, and then platform browser does its thing, and then, whoop, and then boom. So everything you've already known, right? Now we have a normal single page application with Angular, right? And actually recently, Jason Jean from Forbes got Angular, the CLI integrated with Universal. So this actually makes it a lot easier to start. And if you even want to take a look at it now, if you're on a computer, just go to Angular slash Universal starter. Just make sure you go to the CLI folder, because there's two different versions on there. So now with the CLI, it's a lot easier. All of the crazy web pack stuff is hidden, and it's a lot easier to get started, right? And you can see there's two different ways to get it running and everything like, I'll get into those in a second. Oh, and if you already have an Angular CLI, has anybody used the CLI before? I haven't got a few. Awesome. So if you already have an Angular app written in it, you can check out the CLI wiki. It's actually a really long link. I tried to shorten it. Check it out there, because it has how you can get started with it easily. So before I get into how it works, I wanted to show you guys what it is. So you know what I'm talking about, right? So this is right here, a static, like this is a regular Angular app, this one, right? And what I'm going to do is I'm going to slow it down a little bit to do like a fast 3G, and just so we can see the transition a little better, and I'm just going to reload real quick. So this is kind of what you're used to, right? You get that loading screen, this is also a really simple app. So the fact that it even takes a few seconds is crazy enough, right? So you can see we get that loading, which is kind of ugly, right? Sorry I didn't style this very much. And you can see it took about like four seconds on a fast 3G just to finish bootstrapping the app. So like we were saying earlier, if certain people will leave a site within a few seconds, if they don't see something they can work with, start scrolling, interacting with it. So this is just a regular Angular CLI loading, everything client-side rendering, right? Right over here, we have the same exact app, but we're going to do fast 3G as well, and we're going to... Hopefully this is the right one. There it is. Okay. So we have it using Universal. In this case, I don't really have much going on in this app, so it took 100 milliseconds for it to get that initial paint. So basically the device... It's usually a little slower than that, but I'm obviously a local host. Yeah, so I mean, we basically hit the server, the server rendered it so quickly, and the device immediately got a painted app, which is great. And then you could see behind the scenes, it was then creating it, and it also took 3.5 seconds for it to become a client-side app. But anyone looking at your app or on a device or on the web, they got the impression and like the perception, right, that it's really quick, and there's something there. And I mean, no one's going to go to it and immediately start clicking on stuff. So even if it takes a few seconds, you're fine, you know? And more importantly, if we do view source for both of these, this is the client-side rendered one. And can you guys see that? It's obviously all truncated, this is like production, right? You can see there's really nothing in here. We have this app root, and I statically put in this loading text, right? We don't have... We have the meta viewport, but there's no title. The title is the original index title. We don't have any meta tags or anything, right? We go over to the universal version, same exact thing, but now you can actually see the whole app is... Oh, maybe you can't see it. There it is. Is that better? Right? So now you can see everything actually got rendered. So inside of this app root, you can see we took the H1s, the image, all the URLs, the code that we got from Node, and even some of the meta tags. You can see the title changed to Plone Fanpage Home. I don't know if I added any metas. I'll show you. This one has some. Bear with me. Here we go. So this is just a different route. So you can see in here, I actually loaded it up with all the meta tags. And it's literally just as easy as it used to be. There's an Angular service called meta. Just include it in any component. You can have it be part of the router, whatever. And you basically just update tags in there, and you say, for meta, name, Twitter card, I want it to be this. For Twitter site, I want it to be my hashtag, whatever. So you can see everything here. We got Plone Conf, Lazy Loading Page. Later on today, I'm going to post this whole example, so you guys can take a look and mess around with it. It's really easy to use. And, you know, does that make sense? Right? Pretty cool, I thought. All right, so behind the scenes, basically it's a lot of dependency injection, right? Which does anyone unfamiliar with dependency injection? Right? It's, you know, you're basically swapping things out. So you're saying every time I want to use logger, swap it out for super logger, right? And you don't have to change your code base at all. All your code can stay the same because it still reference logger, but behind the scenes is actually going to call super logger, right? And a lot of these things that I was saying earlier are possible because Angular's compiler and the renderer, they're not based on the browser, right? So we're able to swap these things out and say instead of creating the app for a browser, create it from Node, right? And, of course, a little bit of magic. So these are some of the things that are typical, you know, when you're making, when an app's being created, right? Like the renderer, you have, anytime you're doing HTTP calls, typically going to call browser HTTP, right? Platform location is anytime the route changes, things like that. And obviously the way all of your styles are rendered, right? Because on the browser, there's native, you can emulate things. So what we do for Universal is basically swap them out and provide something different, right? So anytime the app is about to render things, we use a server renderer, which is, it knows you're a Node land, so it creates them differently, right? And anytime you make an HTTP call, we're actually going to use Node's XHR to make the request in Node, but, you know, everything's wrapped in zones, right? Which is a part of the Angular library. And zones is basically like, it's just a wrapper around, let's say, timeouts, anything async. It lets you know when things are done, when things go wrong, right? And we wrap everything around in that so we're aware of it, right? So if any of your HTTP calls make an error, like when they're done, we're Angular knows, and basically this is how the app knows it's finished rendering, right? Because let's say you get to an app and you make two HTTP calls, one for products and one for to see if they're authenticated, right? Because of this, we're able to be aware of it in Node when they're both done, and since the rendering, everything else finished, all the HTML, your HTTP is done, we say, okay, we're all set, and then we send it off to the browser, you know? So kind of a long story there, sorry. I don't know if anybody cares. You know, and then a lot of other fun stuff like document has been changed to domino, which is just an abstract syntax tree. It's just a different, it's like a JSON representation, not JSON, it's like a long object of your HTML, right? So think of your whole app as objects, you know? So you have like your body tag and then it has children, and that's all of your divs and everything in there. So, you know, like I said, things are different in Node, right? And the other two, same kind of thing, we're just making sure we know how to deal with styles and how to deal with routes changing. So sorry, that was a little behind the scenes, right? So this is the typical Angular app, right? You've got your app module, you have your main TypeScript file, and then platform browser. So basically with Universal, all we're doing is forking it, right? We have two different branches of it. So we're going to have an app server module, a main server, and platform server, right? And this is for our Node server. Everything in Angular app is basically your main component and your normal app, so you don't have to touch anything there. You're basically just creating a little bit different starting point for your app, right? Based on the environment. And this would be really similar if you, like I was saying, if you've done native script, that's done similarly. So just to dig in a little deeper, right? Normally you're using browser module, right? So an app server, we're actually going to import everything that your app module has. So you can see it's like an extension of your normal app. And then we're going to import server module, right? And what all server module is doing is a lot of that dependency injection we were just talking about. So in there, this is like in the actual code, these providers are like, there's like 30 things inside of there. They're basically just dependency injecting over top of everything normal, right? You don't have to worry about this. I'm just showing you in case you're curious. So this is all you need, but behind the scenes it's doing all the magic, right? I'm just trying to make it not as mysterious, you know? And so the other thing that's cool is with something like this, there's two options you can go, right? You can statically generate all of your pages at build time, or you can do them at run time, right? And so what does that mean? Like if you wanted to generate static ones, you could think of like a CMS, right? And your pages aren't that dynamic, or there's maybe only certain pages you want to generate. So in this case, I'm statically going to generate index, about, and contact us, right? And once you create them with Universal, they're just going to toss them in your disk folder, and you can literally just serve that up however you'd like. And those will be regular HTML pages, but they'll be fully rendered versions of your app. Actually rendering is done at run time, right? So in this case, we're actually going to have that node server, and every request that comes in for whatever route, for homepage, for about us, for products, it's going to do it at run time because let's say you're Amazon, you know, you can't statically generate bicycles, right? Every time it's going to be completely different. So this is usually the use case most people are going to go down, you know? And I'll get into this. This is kind of the gist of it. Don't use this code right here because it's kind of just mock. But you can see right here, so basically saying for every request, this is a node server, by the way, for Express, for every request, I'm just going to pass in that AOT Angular module, right? And AOT just means ahead of time compiled. I'm going to pass in that original index HTML page, which usually is very blank, or it just has your app route, the current URL, and when it's finished, I'm just going to pass the HTML to the browser. So really it's nothing fancy. This is kind of all you need. And then a few things, like I was showing in the previous slide, it takes more than a few minutes, but if you download the starter, all this will be hooked up for you. You don't have to worry about it. It's pretty well documented as well. So in there, you can kind of get a good idea of where to start, what's what, you know, what's the purpose of everything. So this is doing everything manually and with render module factory, but I'd recommend just use it. We created an Express engine, which kind of does some of this piping for you. You can find an Angular slash universal. And there's actually more libraries in there, and there's more to come. So this namespace, and this is actually where the old universal used to be, it's going to be, now it's going to be filled with like third party and open source modules, things that make your apps better, pretty much anything for universal, anything you'd want. So keep an eye on that. And using the engines, look, it's a lot cleaner. We pass in that app server module, and that's it. And you can see right here, we're actually passing in the same thing. So for every request, we're just rendering the engine. If you're not familiar with Express engines, don't worry about it, but it's doing what we did on that last page and some just behind the scenes. And we're actually passing in every single request and response. So why does this matter? What's nice is now, because we're doing that, inside of your Angular app, you can actually, using the injector, you can grab these things. So you can grab the current, during a server render, you can actually grab the request and response. So let's say you have cookies or authentication data or anything, you could pass in anything through Node and access it within your app. So let's say they're already logged in and you want the server render to say, welcome Matt or whatever. Using this, you can grab all that data and actually make it within your app. Everybody with me so far? Sorry if it's a bit much. I know it's a little crazy. It's worth it. So I kind of want these, some of these, the next few slides are basically, I wanted to go over typical gotchas and problems with SSR. So these will happen no matter how you do it. So no matter what framework or anything, one important thing to realize is that each one is going to render. So when you hit the server, it's going to render your app, it's going to do it one more time on the client side, right? So why does that matter? If you make an HTTP call and component, let's say component C here, it's going to trigger it again on the client. And the reason it's something like that might matter is because it's actually going to flicker. So first you're going to get all those bicycles, let's say, then they're going to disappear right before bootstraps or when it does bootstrap, and they're going to appear again. So not only are you hitting the server twice, you're getting kind of a bad user experience, things like that. And I'll show how to fix that in a second. If you use anything like window or document inside your app, it's not going to end well, right? Those things exist in the browser, but Node is just going to throw a real sweet error that doesn't really explain anything and just shut down. So no bueno. So how can we take care of some of these problems, right? So coming up in the newest N5.0 is actually going to be something called transfer state. So right now that's an RC, I don't think it came out just yet. But what this is going to do is automatic, you can either manually set things to transfer or using the transfer HTTP cache module, it'll automatically do all of that wiring for you. And it's as easy as literally adding these few imports. So for your app module and your app server module, you just include the cache module. You could see there's one for the browser and one for the server, right? Now when we make that call, it's actually going to send all of that data down over the wire in the index file as like a JSON blob. And it's going to reuse it on the client. So it's kind of nice. So not only did you save or, you know, you didn't make two round trips to the server, you actually got rid of the flicker and the user once again had no idea. They just think your app's crazy fast. So yeah, like another one I was saying, be careful with the window, right? It's only on the browser. But with dependency injection, you could take advantage of it in your app and do whatever you want. So right over here, I kind of just made a, this is kind of like a window, right? Very mock. You could put as much or as little as you want in here. And in here you can see I just kind of stubbed a few things, right? For the browser, I'm going to use dependency injection and provide the actual window. And you can see I'm doing type of window. You want to make sure it's not undefined. Otherwise, you know, you don't want the server to use this because like if I just had window there, once again, no one would have blown up. So this is kind of like a work around hack, right? So for the browser, we're actually getting the window. This whole server has actually got replaced with the massive window object with everything that's normally in there. For the server, you can see we're actually providing and using that mock. So because, you know, in the server, we don't want to touch the navigator. We don't want to do location. We want to make sure anytime someone does window, nothing happens, right? And that line's a little there. Don't worry about it. Right in here, another big, I'd say, pro tip is with Universal, we have something called is platform browser. So whenever you want in your code, you can actually make tests to see and make sure which platform you're in. So you can see here, I'm taking advantage of a couple of things, right? So one, we're making sure we're in the browser. And then I'm using that window service to do something crazy like use jQuery, right? Which everyone, you're not supposed to do with Angular, but people do. Apps sometimes need certain things, right? The world's not perfect. But by doing this, we can actually do whatever we want. So this code basically is completely ignored on the server. But in this case, in the browser, I'm going to do something to the window or to the body, sorry. So kind of cool. It's just a way of basically ignoring things, like hiding it from Node. You know? No, it's pretty strict. And also something new in 5.0 is you can actually use that document that is provided in the Node environment, the one I was talking about that's like an object, JavaScript object. Anywhere you want, you can actually use it like almost like it's the browser. So in here, I'm actually querying a selector. And so anything you normally could do, you could do, and this would actually work in Node. Which is kind of cool. So this kind of just shows what we were just talking about. So this is the same thing, component using it, the browser can that actually uses Window, but because of this, Node keeps running, we don't actually use Window in here. So far so good? Is anybody really confused or not yet? One other big gotcha is just make sure, you know, with any, this is the same thing with any framework, really be careful with set timeouts and intervals, right? Because these things are going to slow down your server render, right? If you put a set timeout or an interval that just never ends, you're never going to get a server render, right? It's just going to keep going in Node and never stop. So same thing, wrap them with this browser. If you want to be really careful, which I usually like to just use that Window service just to make sure you're using the right one. And this, like I said before, just ignores it in Node. That way you get that really fast paint. Because if, you know, let's say in your code you have a little set timeout of a second and then you do some kind of animation. There's no animations in Node, so, you know, might as well ignore it, right? And of course, if you guys want more, there's a bunch of more gotchas and definitely more documentation coming soon. We know that's one of our biggest problems right now. So check out Angular Universal if you want to see a little bit more on that. Let me see. Oh, yep. So in conclusion, you know, I think with all this you can get, I think the beauty of it now is we can get SEO, we got social media previews. We can, oh, why is it missing some of my stuff? Of course. There was a couple more in there. Sorry about that. But basically, now I think we can get the best of both worlds. We can, you have SEO, you have really fast initial paint of your application. That is still really interactive, right? So, yeah, rich user experience. You can post it on Twitter, all everything is there you want as long as you provide it. You know, just be really careful of what you do. So, you know, if you're used to doing kind of things, however, it's a little more strict, you know, but that's okay. The good thing is by doing this, you're at the end of the day is cleaner, it's more platform performance and more reliant, right? And at the same time, you can even take your app and move it to something like native scripts, which has done a lot of these things applied to native scripts. So, if you get used to these things, you can really easily make your app mobile as well. So they have server render, mobile, everything. And one thing I can't stress, be really careful with third party libraries, because if you pick, I don't know, Joe Schmo's random library, he could have window everywhere and it will just blow up. You know, and when something like that happens, you have to actually use Webpack and swap it out and that gets a little confusing. So try to find ones like, you know, ng bootstrap. Material is like almost compliant. Like there are certain libraries that are, they really do things carefully and you won't have any problems with, right? Oh, there they are. All right. That's strange. So with server side render, we also got rid of that loading splash screen, right? Which I think, I don't know if we saw in the demo. All right. So this is the server side render one. When I push F5, immediately we see the app, right? Right over here. Get that loading. So now that's gone. Which normally doesn't matter. If you have a quick internet or anything like that, it's fine. But you know, most of the world has 3G, right? If your customers are using 3G, the stuff should matter. It's going to be a lot better for them. They're going to have that perception. Even if it takes a few seconds for them to get that render, they're used to it probably taking 15 for some complex site to load. And a nice, very loose metric is typically it'll be like two to three times faster for like an initial paint. So depending on what you have going on. Just remember if you have, you know, an HTTP call that takes five seconds, it's going to wait five seconds for it to render, right? So doing some of those tricks we were showing earlier, you can actually, maybe make sure you ignore that call on the server, things like that. So we went from this to this ugly thing. But now we have all of our code, right? We got our titles, our metas. You can see down at the bottom even like, that's like some of the HTTP call that was cached and sent along with it. So like we were saying earlier, can we get the best of both worlds? I mean, I think yes, but it takes a little bit of work, but I think it's worth it. And thank you guys. Thank you.
 I'm Mark Pysack.  I'm the founder and CTO of Dev Help Online.  It's a consulting, development, training firm.  We're located in Florida right now, but work with a lot of different startups, the Fortune  Drive, and our companies right now trying to help them upgrade their Angular projects  and basically get their teams up to speed, things like that.  Today we're going to talk about Angular Universal.  Before I get into that, I wanted to give you guys just a general background and a nice  basically history of the web.  Let's talk about server-side rendering, JavaScript in general.  I think to me it's like the future of the web, or at least for some of it.  Anyway, like I said, I'm Mark.  Check out our website, Dev Help Online.  It's still in the works, so right now it's very bare-bone.  There's a really serious photo of me.  I'm actually a phone guy.  I don't know why.  I think I need to update that.  I'm actually also part of the Angular Universal team.  I work with a couple of guys from the Google Angular core team and a lot of open source  people to kind of build upon and improve the Angular Universal, which if anyone's ever  heard of it, it's basically rendering Angular in Node.  So get into that.  So just so you remember my name because it's kind of silly, it's Mark Pizak, but just felt  funny.  It's Polish, so go figure.  You can find me online at markpizak.  I try to blog as much as I can, hopefully more soon.  But if you want to talk about anything Angular in general, just hit me up on Twitter, always  for your chat.  All right, so story time.  I kind of wanted to start out with talking about, in general terms, the web, right?  Where we came from, where we've been, and kind of at least where I see it going.  And to me, it kind of, obviously, it started way before this, but everything started out  kind of server rendered, right?  So we had things like PHP.net, anything, a JSP, whatever, right?  And there was a lot of pros to that, a lot of cons.  So kind of to get started, let's say, I'm just going to generalize the whole period  of time and call it server-side rendered, right?  Obviously, it's gotten a lot better since then, but I kind of wanted to have some laughs  and how bad it used to be, right?  So this used to be Google, pretty ugly, right?  I mean, this was Amazon, if anyone remembers.  And we used to do a lot of chatting.  There was instant messenger.  There was chat rooms.  And some things have changed, but some things kind of stay the same, right?  Everything's been replaced.  Now, we have Facebook Messenger.  We have Slack.  And we've almost gone full circle, right?  It's pretty strange, but it's the way the world works, right?  So some of the things with server-side rendering that I thought was always really beneficial  and they did well was, you know, we didn't realize how good we had it back then when,  let's say, you're doing a PHP app or whatever.  SEO is as easy as just basically adding a bunch of tags, right?  Just meta tags or title.  It was super simple, right?  It was great for static sites, a lot of other things, right?  But some of the things that, you know, it was lacking, right, was mainly user experience.  You know, we had to get to any page.  You had to do a full reload, right?  Everything constantly.  So, like, it wasn't that rich immersive experience, you know?  So, you know, and everything, there was a lot more server requests in general, right?  So, you know, what did the web do?  You know, flipped everything upside down and all of a sudden the cool thing was single-page  applications, right?  So, whether you did a hybrid with a little jQuery or you went full react or Angular,  you know, what have you, single-page applications now are cool, right?  Kind of cool.  So I'm going to call them client-side rendering from now on, like CSR.  So if you've never seen these acronyms, don't worry.  I think we made them up.  So, but with single-page applications, basically this happened and we had this massive ecosystem  which is basically a nightmare to work with and every few weeks you kind of felt like this,  right?  I mean, you're all, you kind of were never sure of yourself.  It's like, am I making the right choice, you know?  One day Angular, next day View, then there's React, then there's a million other ones.  So you get a little frustrating.  But some of the things that client-side rendering does really well, of course, is user experience,  right?  So that's kind of why everyone switched, right?  So we got that really immersive experience, you know, everything you could immediately  see when things were happening, right?  The really quick page transitions.  It's perfect for really complex web apps and things with real-time data.  And you know, the best thing is really you just, it feels like things are happening,  right?  And maybe a modal moves, there's animations, right?  You can't do that with server-side rendering.  So a lot of good stuff.  But some of the downside, right, of course, is no SEO, right?  So typically when you, you know, view source on any front-end app, this is what you see,  right?  You just basically nothing.  And it's not personalized for that exact route or anything, right?  So basically nothing.  And of course, it generally longer load time.  So you get to that route, and then you have to load, you know, megabytes of JavaScript  files.  And then all of those have to run and process and then bootstrap your app.  So you see this a lot.  And that's also kind of a con, right?  I mean, if someone is on a slower network, let's say 3G, and it takes five seconds for  your app to start up, you know, Google's done experiments and stuff on this.  Maybe if a page takes longer than three seconds, most people will actually leave.  So you actually get a lot of bounce rate because of that.  So once again, kind of not a good thing, right?  So with all this together, you know, you basically just rewrote your app.  Now you did it in React or Angular.  All of a sudden you realize this isn't good either, and your boss is pissed, and then you're  throwing your phone on the ground.  You know, so what do we do from here?  So the goal really, ideally what we want is we want the best of both worlds, right?  We want SEO.  We want that really quick paint.  You know, you see the application right away.  We want, you know, if I copy and paste the link to Twitter or Facebook, you want to see  that preview with the image and metadata.  You know, we want the user experience.  We want it to be interactive.  It almost sounds delusional, right, if it's possible.  So, you know, can we get that, right?  So the next kind of shift that I noticed in, like, the web in general was someone in, I  think, 2013 coined the term isomorphic JavaScript, which sounds kind of like a weird chemistry  experiment.  I think it's a crazy word.  I prefer the word universal, and I think that's why the creators of it called it that.  I mean, the idea of it is basically you want it to run on both environments, right?  The browser and the server.  In general, like, the how it all works, right?  You have your JavaScript code, and we want that same code to run on a server and on the  browser.  So that's basically isomorphic or universal, whatever you want to call it, which to me  sounded like a fairy tale, because I was like, how could you ever do that?  Like, there must be a million, you know, that's kind of how I felt.  This was years ago when I first heard of it, and I thought it was a joke, you know, I thought  there's no way that's possible.  You know, I have to see it first, right, to believe it.  But someone then explained to me what it really was.  So it's basically the code, you have your code, you send it to the server, it's supposed  to serialize it, right?  So it takes your entire app at whatever URL or whatever portion of it you're at, creates  all the HTML for that, sending it to the browser.  The browser then in the background, since it has those big bundles, starts downloading  them bootstrapping, and at the end of the day, everything finishes, and all of a sudden  you have a client side out.  Did everybody catch that or did it go too quick?  We'll be going over it in a second anyway.  So here comes Angular Universal.  So I came about to the project about two years ago, and Angular Universal was their solution  to kind of handle this and make this work.  Because if you remember an AngularJS, which is the older version, right, it wasn't possible  to do this because AngularJS was really tied to the browser, right?  Everything was based on the DOM and things like that.  The new Angular is very abstract.  So that's why everything is done using all these abstract syntax trees and things like  that.  So you're able to create your app in different environments.  So if you've ever used native script as well, it's done similarly, right?  So native script takes your app and basically renders it on a mobile device for iOS or Android,  and it's able to do this because of how abstract it is.  So they basically create their own engine on top of Angular's.  So Universal does the same thing.  The founders of our creators were Patrick Stapleton, you might know him as PatrickJS,  and Jeff Welpley, really good friends of mine.  So they created this project because they needed this for their projects, right?  And Jeff Welpley actually has created a, I think, he has it working in production, but  for AngularJS, he actually has a way to server render it.  So if you want to find him on Twitter, bug him about it, I think it's online somewhere,  I forget the link.  So anyway, so these guys actually created it.  And to me, it's kind of amazing because the whole project actually didn't come from the  Angular core team itself.  It's originated by people like us, right?  Just random open source people, and then eventually got moved into core this year.  So some of the other people on the team, me, of course, right?  Jason Jean, who doesn't put his picture online, Alex Rickva and Vikram from the Angular core  team, Jeff Cross, who was also used to be on the core team, now he's at Norwalk, and  Wessie Cheggman from Saphir, and a lot of other people, a lot of big contributors.  But yeah, so like I was saying, it was open source, it was its own repo, and now it's  actually part of Angular.  So if you've ever tried to use it in the past, it's a lot safer now.  It's a lot more tested.  And it's actually within the same code base.  So you can kind of, it's really production ready now.  It was before, but not really.  So kind of like we were just showing, so the way we handle it, right, is you take your  Angular app, right?  So that's your root component, everything inside of it.  You're going to run it on Node using something called render module factory, right?  This is just like an overview.  Don't worry.  We're going to take the whole app, basically turn it to a long string, send it to the browser.  In the background, we load all of your Angular bundles, everything, and then platform browser  does its thing, and then, whoop, and then boom.  So everything you've already known, right?  Now we have a normal single page application with Angular, right?  And actually recently, Jason Jean from Forbes got Angular, the CLI integrated with Universal.  So this actually makes it a lot easier to start.  And if you even want to take a look at it now, if you're on a computer, just go to Angular  slash Universal starter.  Just make sure you go to the CLI folder, because there's two different versions on there.  So now with the CLI, it's a lot easier.  All of the crazy web pack stuff is hidden, and it's a lot easier to get started, right?  And you can see there's two different ways to get it running and everything like, I'll  get into those in a second.  Oh, and if you already have an Angular CLI, has anybody used the CLI before?  I haven't got a few.  Awesome.  So if you already have an Angular app written in it, you can check out the CLI wiki.  It's actually a really long link.  I tried to shorten it.  Check it out there, because it has how you can get started with it easily.  So before I get into how it works, I wanted to show you guys what it is.  So you know what I'm talking about, right?  So this is right here, a static, like this is a regular Angular app, this one, right?  And what I'm going to do is I'm going to slow it down a little bit to do like a fast 3G,  and just so we can see the transition a little better, and I'm just going to reload real  quick.  So this is kind of what you're used to, right?  You get that loading screen, this is also a really simple app.  So the fact that it even takes a few seconds is crazy enough, right?  So you can see we get that loading, which is kind of ugly, right?  Sorry I didn't style this very much.  And you can see it took about like four seconds on a fast 3G just to finish bootstrapping the  app.  So like we were saying earlier, if certain people will leave a site within a few seconds,  if they don't see something they can work with, start scrolling, interacting with it.  So this is just a regular Angular CLI loading, everything client-side rendering, right?  Right over here, we have the same exact app, but we're going to do fast 3G as well, and  we're going to...  Hopefully this is the right one.  There it is.  Okay.  So we have it using Universal.  In this case, I don't really have much going on in this app, so it took 100 milliseconds  for it to get that initial paint.  So basically the device...  It's usually a little slower than that, but I'm obviously a local host.  Yeah, so I mean, we basically hit the server, the server rendered it so quickly, and the  device immediately got a painted app, which is great.  And then you could see behind the scenes, it was then creating it, and it also took 3.5  seconds for it to become a client-side app.  But anyone looking at your app or on a device or on the web, they got the impression and  like the perception, right, that it's really quick, and there's something there.  And I mean, no one's going to go to it and immediately start clicking on stuff.  So even if it takes a few seconds, you're fine, you know?  And more importantly, if we do view source for both of these, this is the client-side  rendered one.  And can you guys see that?  It's obviously all truncated, this is like production, right?  You can see there's really nothing in here.  We have this app root, and I statically put in this loading text, right?  We don't have...  We have the meta viewport, but there's no title.  The title is the original index title.  We don't have any meta tags or anything, right?  We go over to the universal version, same exact thing, but now you can actually see  the whole app is...  Oh, maybe you can't see it.  There it is.  Is that better?  Right?  So now you can see everything actually got rendered.  So inside of this app root, you can see we took the H1s, the image, all the URLs, the  code that we got from Node, and even some of the meta tags.  You can see the title changed to Plone Fanpage Home.  I don't know if I added any metas.  I'll show you.  This one has some.  Bear with me.  Here we go.  So this is just a different route.  So you can see in here, I actually loaded it up with all the meta tags.  And it's literally just as easy as it used to be.  There's an Angular service called meta.  Just include it in any component.  You can have it be part of the router, whatever.  And you basically just update tags in there, and you say, for meta, name, Twitter card,  I want it to be this.  For Twitter site, I want it to be my hashtag, whatever.  So you can see everything here.  We got Plone Conf, Lazy Loading Page.  Later on today, I'm going to post this whole example, so you guys can take a look and mess  around with it.  It's really easy to use.  And, you know, does that make sense?  Right?  Pretty cool, I thought.  All right, so behind the scenes, basically it's a lot of dependency injection, right?  Which does anyone unfamiliar with dependency injection?  Right?  It's, you know, you're basically swapping things out.  So you're saying every time I want to use logger, swap it out for super logger, right?  And you don't have to change your code base at all.  All your code can stay the same because it still reference logger, but behind the scenes  is actually going to call super logger, right?  And a lot of these things that I was saying earlier are possible because Angular's compiler  and the renderer, they're not based on the browser, right?  So we're able to swap these things out and say instead of creating the app for a browser,  create it from Node, right?  And, of course, a little bit of magic.  So these are some of the things that are typical, you know, when you're making, when an app's  being created, right?  Like the renderer, you have, anytime you're doing HTTP calls, typically going to call  browser HTTP, right?  Platform location is anytime the route changes, things like that.  And obviously the way all of your styles are rendered, right?  Because on the browser, there's native, you can emulate things.  So what we do for Universal is basically swap them out and provide something different,  right?  So anytime the app is about to render things, we use a server renderer, which is, it knows  you're a Node land, so it creates them differently, right?  And anytime you make an HTTP call, we're actually going to use Node's XHR to make the request  in Node, but, you know, everything's wrapped in zones, right?  Which is a part of the Angular library.  And zones is basically like, it's just a wrapper around, let's say, timeouts, anything async.  It lets you know when things are done, when things go wrong, right?  And we wrap everything around in that so we're aware of it, right?  So if any of your HTTP calls make an error, like when they're done, we're Angular knows,  and basically this is how the app knows it's finished rendering, right?  Because let's say you get to an app and you make two HTTP calls, one for products and  one for to see if they're authenticated, right?  Because of this, we're able to be aware of it in Node when they're both done, and since  the rendering, everything else finished, all the HTML, your HTTP is done, we say, okay,  we're all set, and then we send it off to the browser, you know?  So kind of a long story there, sorry.  I don't know if anybody cares.  You know, and then a lot of other fun stuff like document has been changed to domino,  which is just an abstract syntax tree.  It's just a different, it's like a JSON representation, not JSON, it's like a long object of your  HTML, right?  So think of your whole app as objects, you know?  So you have like your body tag and then it has children, and that's all of your divs  and everything in there.  So, you know, like I said, things are different in Node, right?  And the other two, same kind of thing, we're just making sure we know how to deal with  styles and how to deal with routes changing.  So sorry, that was a little behind the scenes, right?  So this is the typical Angular app, right?  You've got your app module, you have your main TypeScript file, and then platform browser.  So basically with Universal, all we're doing is forking it, right?  We have two different branches of it.  So we're going to have an app server module, a main server, and platform server, right?  And this is for our Node server.  Everything in Angular app is basically your main component and your normal app, so you  don't have to touch anything there.  You're basically just creating a little bit different starting point for your app, right?  Based on the environment.  And this would be really similar if you, like I was saying, if you've done native script,  that's done similarly.  So just to dig in a little deeper, right?  Normally you're using browser module, right?  So an app server, we're actually going to import everything that your app module has.  So you can see it's like an extension of your normal app.  And then we're going to import server module, right?  And what all server module is doing is a lot of that dependency injection we were just  talking about.  So in there, this is like in the actual code, these providers are like, there's like 30  things inside of there.  They're basically just dependency injecting over top of everything normal, right?  You don't have to worry about this.  I'm just showing you in case you're curious.  So this is all you need, but behind the scenes it's doing all the magic, right?  I'm just trying to make it not as mysterious, you know?  And so the other thing that's cool is with something like this, there's two options  you can go, right?  You can statically generate all of your pages at build time, or you can do them at run time,  right?  And so what does that mean?  Like if you wanted to generate static ones, you could think of like a CMS, right?  And your pages aren't that dynamic, or there's maybe only certain pages you want to generate.  So in this case, I'm statically going to generate index, about, and contact us, right?  And once you create them with Universal, they're just going to toss them in your disk folder,  and you can literally just serve that up however you'd like.  And those will be regular HTML pages, but they'll be fully rendered versions of your  app.  Actually rendering is done at run time, right?  So in this case, we're actually going to have that node server, and every request that comes  in for whatever route, for homepage, for about us, for products, it's going to do it at run  time because let's say you're Amazon, you know, you can't statically generate bicycles,  right?  Every time it's going to be completely different.  So this is usually the use case most people are going to go down, you know?  And I'll get into this.  This is kind of the gist of it.  Don't use this code right here because it's kind of just mock.  But you can see right here, so basically saying for every request, this is a node server,  by the way, for Express, for every request, I'm just going to pass in that AOT Angular  module, right?  And AOT just means ahead of time compiled.  I'm going to pass in that original index HTML page, which usually is very blank, or it just  has your app route, the current URL, and when it's finished, I'm just going to pass the  HTML to the browser.  So really it's nothing fancy.  This is kind of all you need.  And then a few things, like I was showing in the previous slide, it takes more than a  few minutes, but if you download the starter, all this will be hooked up for you.  You don't have to worry about it.  It's pretty well documented as well.  So in there, you can kind of get a good idea of where to start, what's what, you know,  what's the purpose of everything.  So this is doing everything manually and with render module factory, but I'd recommend  just use it.  We created an Express engine, which kind of does some of this piping for you.  You can find an Angular slash universal.  And there's actually more libraries in there, and there's more to come.  So this namespace, and this is actually where the old universal used to be, it's going to  be, now it's going to be filled with like third party and open source modules, things  that make your apps better, pretty much anything for universal, anything you'd want.  So keep an eye on that.  And using the engines, look, it's a lot cleaner.  We pass in that app server module, and that's it.  And you can see right here, we're actually passing in the same thing.  So for every request, we're just rendering the engine.  If you're not familiar with Express engines, don't worry about it, but it's doing what  we did on that last page and some just behind the scenes.  And we're actually passing in every single request and response.  So why does this matter?  What's nice is now, because we're doing that, inside of your Angular app, you can actually,  using the injector, you can grab these things.  So you can grab the current, during a server render, you can actually grab the request  and response.  So let's say you have cookies or authentication data or anything, you could pass in anything  through Node and access it within your app.  So let's say they're already logged in and you want the server render to say, welcome  Matt or whatever.  Using this, you can grab all that data and actually make it within your app.  Everybody with me so far?  Sorry if it's a bit much.  I know it's a little crazy.  It's worth it.  So I kind of want these, some of these, the next few slides are basically, I wanted to  go over typical gotchas and problems with SSR.  So these will happen no matter how you do it.  So no matter what framework or anything, one important thing to realize is that each one  is going to render.  So when you hit the server, it's going to render your app, it's going to do it one more  time on the client side, right?  So why does that matter?  If you make an HTTP call and component, let's say component C here, it's going to trigger  it again on the client.  And the reason it's something like that might matter is because it's actually going to flicker.  So first you're going to get all those bicycles, let's say, then they're going to disappear  right before bootstraps or when it does bootstrap, and they're going to appear again.  So not only are you hitting the server twice, you're getting kind of a bad user experience,  things like that.  And I'll show how to fix that in a second.  If you use anything like window or document inside your app, it's not going to end well,  right?  Those things exist in the browser, but Node is just going to throw a real sweet error  that doesn't really explain anything and just shut down.  So no bueno.  So how can we take care of some of these problems, right?  So coming up in the newest N5.0 is actually going to be something called transfer state.  So right now that's an RC, I don't think it came out just yet.  But what this is going to do is automatic, you can either manually set things to transfer  or using the transfer HTTP cache module, it'll automatically do all of that wiring for you.  And it's as easy as literally adding these few imports.  So for your app module and your app server module, you just include the cache module.  You could see there's one for the browser and one for the server, right?  Now when we make that call, it's actually going to send all of that data down over the  wire in the index file as like a JSON blob.  And it's going to reuse it on the client.  So it's kind of nice.  So not only did you save or, you know, you didn't make two round trips to the server,  you actually got rid of the flicker and the user once again had no idea.  They just think your app's crazy fast.  So yeah, like another one I was saying, be careful with the window, right?  It's only on the browser.  But with dependency injection, you could take advantage of it in your app and do whatever  you want.  So right over here, I kind of just made a, this is kind of like a window, right?  Very mock.  You could put as much or as little as you want in here.  And in here you can see I just kind of stubbed a few things, right?  For the browser, I'm going to use dependency injection and provide the actual window.  And you can see I'm doing type of window.  You want to make sure it's not undefined.  Otherwise, you know, you don't want the server to use this because like if I just had window  there, once again, no one would have blown up.  So this is kind of like a work around hack, right?  So for the browser, we're actually getting the window.  This whole server has actually got replaced with the massive window object with everything  that's normally in there.  For the server, you can see we're actually providing and using that mock.  So because, you know, in the server, we don't want to touch the navigator.  We don't want to do location.  We want to make sure anytime someone does window, nothing happens, right?  And that line's a little there.  Don't worry about it.  Right in here, another big, I'd say, pro tip is with Universal, we have something called  is platform browser.  So whenever you want in your code, you can actually make tests to see and make sure which  platform you're in.  So you can see here, I'm taking advantage of a couple of things, right?  So one, we're making sure we're in the browser.  And then I'm using that window service to do something crazy like use jQuery, right?  Which everyone, you're not supposed to do with Angular, but people do.  Apps sometimes need certain things, right?  The world's not perfect.  But by doing this, we can actually do whatever we want.  So this code basically is completely ignored on the server.  But in this case, in the browser, I'm going to do something to the window or to the body,  sorry.  So kind of cool.  It's just a way of basically ignoring things, like hiding it from Node.  You know?  No, it's pretty strict.  And also something new in 5.0 is you can actually use that document that is provided in the  Node environment, the one I was talking about that's like an object, JavaScript object.  Anywhere you want, you can actually use it like almost like it's the browser.  So in here, I'm actually querying a selector.  And so anything you normally could do, you could do, and this would actually work in  Node.  Which is kind of cool.  So this kind of just shows what we were just talking about.  So this is the same thing, component using it, the browser can that actually uses Window,  but because of this, Node keeps running, we don't actually use Window in here.  So far so good?  Is anybody really confused or not yet?  One other big gotcha is just make sure, you know, with any, this is the same thing with  any framework, really be careful with set timeouts and intervals, right?  Because these things are going to slow down your server render, right?  If you put a set timeout or an interval that just never ends, you're never going to get  a server render, right?  It's just going to keep going in Node and never stop.  So same thing, wrap them with this browser.  If you want to be really careful, which I usually like to just use that Window service  just to make sure you're using the right one.  And this, like I said before, just ignores it in Node.  That way you get that really fast paint.  Because if, you know, let's say in your code you have a little set timeout of a second  and then you do some kind of animation.  There's no animations in Node, so, you know, might as well ignore it, right?  And of course, if you guys want more, there's a bunch of more gotchas and definitely more  documentation coming soon.  We know that's one of our biggest problems right now.  So check out Angular Universal if you want to see a little bit more on that.  Let me see.  Oh, yep.  So in conclusion, you know, I think with all this you can get, I think the beauty of it  now is we can get SEO, we got social media previews.  We can, oh, why is it missing some of my stuff?  Of course.  There was a couple more in there.  Sorry about that.  But basically, now I think we can get the best of both worlds.  We can, you have SEO, you have really fast initial paint of your application.  That is still really interactive, right?  So, yeah, rich user experience.  You can post it on Twitter, all everything is there you want as long as you provide it.  You know, just be really careful of what you do.  So, you know, if you're used to doing kind of things, however, it's a little more strict,  you know, but that's okay.  The good thing is by doing this, you're at the end of the day is cleaner, it's more platform  performance and more reliant, right?  And at the same time, you can even take your app and move it to something like native scripts,  which has done a lot of these things applied to native scripts.  So, if you get used to these things, you can really easily make your app mobile as well.  So they have server render, mobile, everything.  And one thing I can't stress, be really careful with third party libraries, because if you  pick, I don't know, Joe Schmo's random library, he could have window everywhere and it will  just blow up.  You know, and when something like that happens, you have to actually use Webpack and swap  it out and that gets a little confusing.  So try to find ones like, you know, ng bootstrap.  Material is like almost compliant.  Like there are certain libraries that are, they really do things carefully and you won't  have any problems with, right?  Oh, there they are.  All right.  That's strange.  So with server side render, we also got rid of that loading splash screen, right?  Which I think, I don't know if we saw in the demo.  All right.  So this is the server side render one.  When I push F5, immediately we see the app, right?  Right over here.  Get that loading.  So now that's gone.  Which normally doesn't matter.  If you have a quick internet or anything like that, it's fine.  But you know, most of the world has 3G, right?  If your customers are using 3G, the stuff should matter.  It's going to be a lot better for them.  They're going to have that perception.  Even if it takes a few seconds for them to get that render, they're used to it probably  taking 15 for some complex site to load.  And a nice, very loose metric is typically it'll be like two to three times faster for  like an initial paint.  So depending on what you have going on.  Just remember if you have, you know, an HTTP call that takes five seconds, it's going to  wait five seconds for it to render, right?  So doing some of those tricks we were showing earlier, you can actually, maybe make sure  you ignore that call on the server, things like that.  So we went from this to this ugly thing.  But now we have all of our code, right?  We got our titles, our metas.  You can see down at the bottom even like, that's like some of the HTTP call that was  cached and sent along with it.  So like we were saying earlier, can we get the best of both worlds?  I mean, I think yes, but it takes a little bit of work, but I think it's worth it.  And thank you guys.  Thank you.
Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_0_131.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_132_251.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_252_863.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_864_3347.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_3348_4307.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_4308_4703.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_4704_5531.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_5532_6419.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_6420_6791.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_6792_8891.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_8892_9911.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_9912_10175.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_10176_10907.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_10908_11495.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_11496_12275.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_12276_12335.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_12336_12395.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_12396_12443.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_12444_12491.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_12492_13319.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_13320_13643.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_13644_16271.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_16272_16811.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_16812_18311.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_18312_18719.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_18720_19175.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_19176_19799.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_19800_19967.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_19968_24119.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_24120_31475.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_31476_32723.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_32724_33095.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_33096_33311.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_33312_34427.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_34428_36623.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_36624_37475.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_37476_39311.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_39312_39983.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_39984_41159.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_41160_41867.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_41868_42239.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_42240_42839.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_42840_42887.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_42888_44267.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_44268_45983.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_45984_48455.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_48456_48851.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_48852_48959.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_48960_49319.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_49320_49403.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_49404_51947.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_51948_54155.png Day_3__Mark_Pieszak_-_Rendering_JavaScript_on_the__8hN6cMqmrUY_54156_54270.png
I'm Mark Pysack. I'm the founder and CTO of Dev Help Online. It's a consulting, development, training firm. We're located in Florida right now, but work with a lot of different startups, the Fortune Drive, and our companies right now trying to help them upgrade their Angular projects and basically get their teams up to speed, things like that. Today we're going to talk about Angular Universal. Before I get into that, I wanted to give you guys just a general background and a nice basically history of the web. Let's talk about server-side rendering, JavaScript in general. I think to me it's like the future of the web, or at least for some of it. Anyway, like I said, I'm Mark. Check out our website, Dev Help Online. It's still in the works, so right now it's very bare-bone. There's a really serious photo of me. I'm actually a phone guy. I don't know why. I think I need to update that. I'm actually also part of the Angular Universal team. I work with a couple of guys from the Google Angular core team and a lot of open source people to kind of build upon and improve the Angular Universal, which if anyone's ever heard of it, it's basically rendering Angular in Node. So get into that. So just so you remember my name because it's kind of silly, it's Mark Pizak, but just felt funny. It's Polish, so go figure. You can find me online at markpizak. I try to blog as much as I can, hopefully more soon. But if you want to talk about anything Angular in general, just hit me up on Twitter, always for your chat. All right, so story time. I kind of wanted to start out with talking about, in general terms, the web, right? Where we came from, where we've been, and kind of at least where I see it going. And to me, it kind of, obviously, it started way before this, but everything started out kind of server rendered, right? So we had things like PHP.net, anything, a JSP, whatever, right? And there was a lot of pros to that, a lot of cons. So kind of to get started, let's say, I'm just going to generalize the whole period of time and call it server-side rendered, right? Obviously, it's gotten a lot better since then, but I kind of wanted to have some laughs and how bad it used to be, right? So this used to be Google, pretty ugly, right? I mean, this was Amazon, if anyone remembers. And we used to do a lot of chatting. There was instant messenger. There was chat rooms. And some things have changed, but some things kind of stay the same, right? Everything's been replaced. Now, we have Facebook Messenger. We have Slack. And we've almost gone full circle, right? It's pretty strange, but it's the way the world works, right? So some of the things with server-side rendering that I thought was always really beneficial and they did well was, you know, we didn't realize how good we had it back then when, let's say, you're doing a PHP app or whatever. SEO is as easy as just basically adding a bunch of tags, right? Just meta tags or title. It was super simple, right? It was great for static sites, a lot of other things, right? But some of the things that, you know, it was lacking, right, was mainly user experience. You know, we had to get to any page. You had to do a full reload, right? Everything constantly. So, like, it wasn't that rich immersive experience, you know? So, you know, and everything, there was a lot more server requests in general, right? So, you know, what did the web do? You know, flipped everything upside down and all of a sudden the cool thing was single-page applications, right? So, whether you did a hybrid with a little jQuery or you went full react or Angular, you know, what have you, single-page applications now are cool, right? Kind of cool. So I'm going to call them client-side rendering from now on, like CSR. So if you've never seen these acronyms, don't worry. I think we made them up. So, but with single-page applications, basically this happened and we had this massive ecosystem which is basically a nightmare to work with and every few weeks you kind of felt like this, right? I mean, you're all, you kind of were never sure of yourself. It's like, am I making the right choice, you know? One day Angular, next day View, then there's React, then there's a million other ones. So you get a little frustrating. But some of the things that client-side rendering does really well, of course, is user experience, right? So that's kind of why everyone switched, right? So we got that really immersive experience, you know, everything you could immediately see when things were happening, right? The really quick page transitions. It's perfect for really complex web apps and things with real-time data. And you know, the best thing is really you just, it feels like things are happening, right? And maybe a modal moves, there's animations, right? You can't do that with server-side rendering. So a lot of good stuff. But some of the downside, right, of course, is no SEO, right? So typically when you, you know, view source on any front-end app, this is what you see, right? You just basically nothing. And it's not personalized for that exact route or anything, right? So basically nothing. And of course, it generally longer load time. So you get to that route, and then you have to load, you know, megabytes of JavaScript files. And then all of those have to run and process and then bootstrap your app. So you see this a lot. And that's also kind of a con, right? I mean, if someone is on a slower network, let's say 3G, and it takes five seconds for your app to start up, you know, Google's done experiments and stuff on this. Maybe if a page takes longer than three seconds, most people will actually leave. So you actually get a lot of bounce rate because of that. So once again, kind of not a good thing, right? So with all this together, you know, you basically just rewrote your app. Now you did it in React or Angular. All of a sudden you realize this isn't good either, and your boss is pissed, and then you're throwing your phone on the ground. You know, so what do we do from here? So the goal really, ideally what we want is we want the best of both worlds, right? We want SEO. We want that really quick paint. You know, you see the application right away. We want, you know, if I copy and paste the link to Twitter or Facebook, you want to see that preview with the image and metadata. You know, we want the user experience. We want it to be interactive. It almost sounds delusional, right, if it's possible. So, you know, can we get that, right? So the next kind of shift that I noticed in, like, the web in general was someone in, I think, 2013 coined the term isomorphic JavaScript, which sounds kind of like a weird chemistry experiment. I think it's a crazy word. I prefer the word universal, and I think that's why the creators of it called it that. I mean, the idea of it is basically you want it to run on both environments, right? The browser and the server. In general, like, the how it all works, right? You have your JavaScript code, and we want that same code to run on a server and on the browser. So that's basically isomorphic or universal, whatever you want to call it, which to me sounded like a fairy tale, because I was like, how could you ever do that? Like, there must be a million, you know, that's kind of how I felt. This was years ago when I first heard of it, and I thought it was a joke, you know, I thought there's no way that's possible. You know, I have to see it first, right, to believe it. But someone then explained to me what it really was. So it's basically the code, you have your code, you send it to the server, it's supposed to serialize it, right? So it takes your entire app at whatever URL or whatever portion of it you're at, creates all the HTML for that, sending it to the browser. The browser then in the background, since it has those big bundles, starts downloading them bootstrapping, and at the end of the day, everything finishes, and all of a sudden you have a client side out. Did everybody catch that or did it go too quick? We'll be going over it in a second anyway. So here comes Angular Universal. So I came about to the project about two years ago, and Angular Universal was their solution to kind of handle this and make this work. Because if you remember an AngularJS, which is the older version, right, it wasn't possible to do this because AngularJS was really tied to the browser, right? Everything was based on the DOM and things like that. The new Angular is very abstract. So that's why everything is done using all these abstract syntax trees and things like that. So you're able to create your app in different environments. So if you've ever used native script as well, it's done similarly, right? So native script takes your app and basically renders it on a mobile device for iOS or Android, and it's able to do this because of how abstract it is. So they basically create their own engine on top of Angular's. So Universal does the same thing. The founders of our creators were Patrick Stapleton, you might know him as PatrickJS, and Jeff Welpley, really good friends of mine. So they created this project because they needed this for their projects, right? And Jeff Welpley actually has created a, I think, he has it working in production, but for AngularJS, he actually has a way to server render it. So if you want to find him on Twitter, bug him about it, I think it's online somewhere, I forget the link. So anyway, so these guys actually created it. And to me, it's kind of amazing because the whole project actually didn't come from the Angular core team itself. It's originated by people like us, right? Just random open source people, and then eventually got moved into core this year. So some of the other people on the team, me, of course, right? Jason Jean, who doesn't put his picture online, Alex Rickva and Vikram from the Angular core team, Jeff Cross, who was also used to be on the core team, now he's at Norwalk, and Wessie Cheggman from Saphir, and a lot of other people, a lot of big contributors. But yeah, so like I was saying, it was open source, it was its own repo, and now it's actually part of Angular. So if you've ever tried to use it in the past, it's a lot safer now. It's a lot more tested. And it's actually within the same code base. So you can kind of, it's really production ready now. It was before, but not really. So kind of like we were just showing, so the way we handle it, right, is you take your Angular app, right? So that's your root component, everything inside of it. You're going to run it on Node using something called render module factory, right? This is just like an overview. Don't worry. We're going to take the whole app, basically turn it to a long string, send it to the browser. In the background, we load all of your Angular bundles, everything, and then platform browser does its thing, and then, whoop, and then boom. So everything you've already known, right? Now we have a normal single page application with Angular, right? And actually recently, Jason Jean from Forbes got Angular, the CLI integrated with Universal. So this actually makes it a lot easier to start. And if you even want to take a look at it now, if you're on a computer, just go to Angular slash Universal starter. Just make sure you go to the CLI folder, because there's two different versions on there. So now with the CLI, it's a lot easier. All of the crazy web pack stuff is hidden, and it's a lot easier to get started, right? And you can see there's two different ways to get it running and everything like, I'll get into those in a second. Oh, and if you already have an Angular CLI, has anybody used the CLI before? I haven't got a few. Awesome. So if you already have an Angular app written in it, you can check out the CLI wiki. It's actually a really long link. I tried to shorten it. Check it out there, because it has how you can get started with it easily. So before I get into how it works, I wanted to show you guys what it is. So you know what I'm talking about, right? So this is right here, a static, like this is a regular Angular app, this one, right? And what I'm going to do is I'm going to slow it down a little bit to do like a fast 3G, and just so we can see the transition a little better, and I'm just going to reload real quick. So this is kind of what you're used to, right? You get that loading screen, this is also a really simple app. So the fact that it even takes a few seconds is crazy enough, right? So you can see we get that loading, which is kind of ugly, right? Sorry I didn't style this very much. And you can see it took about like four seconds on a fast 3G just to finish bootstrapping the app. So like we were saying earlier, if certain people will leave a site within a few seconds, if they don't see something they can work with, start scrolling, interacting with it. So this is just a regular Angular CLI loading, everything client-side rendering, right? Right over here, we have the same exact app, but we're going to do fast 3G as well, and we're going to... Hopefully this is the right one. There it is. Okay. So we have it using Universal. In this case, I don't really have much going on in this app, so it took 100 milliseconds for it to get that initial paint. So basically the device... It's usually a little slower than that, but I'm obviously a local host. Yeah, so I mean, we basically hit the server, the server rendered it so quickly, and the device immediately got a painted app, which is great. And then you could see behind the scenes, it was then creating it, and it also took 3.5 seconds for it to become a client-side app. But anyone looking at your app or on a device or on the web, they got the impression and like the perception, right, that it's really quick, and there's something there. And I mean, no one's going to go to it and immediately start clicking on stuff. So even if it takes a few seconds, you're fine, you know? And more importantly, if we do view source for both of these, this is the client-side rendered one. And can you guys see that? It's obviously all truncated, this is like production, right? You can see there's really nothing in here. We have this app root, and I statically put in this loading text, right? We don't have... We have the meta viewport, but there's no title. The title is the original index title. We don't have any meta tags or anything, right? We go over to the universal version, same exact thing, but now you can actually see the whole app is... Oh, maybe you can't see it. There it is. Is that better? Right? So now you can see everything actually got rendered. So inside of this app root, you can see we took the H1s, the image, all the URLs, the code that we got from Node, and even some of the meta tags. You can see the title changed to Plone Fanpage Home. I don't know if I added any metas. I'll show you. This one has some. Bear with me. Here we go. So this is just a different route. So you can see in here, I actually loaded it up with all the meta tags. And it's literally just as easy as it used to be. There's an Angular service called meta. Just include it in any component. You can have it be part of the router, whatever. And you basically just update tags in there, and you say, for meta, name, Twitter card, I want it to be this. For Twitter site, I want it to be my hashtag, whatever. So you can see everything here. We got Plone Conf, Lazy Loading Page. Later on today, I'm going to post this whole example, so you guys can take a look and mess around with it. It's really easy to use. And, you know, does that make sense? Right? Pretty cool, I thought. All right, so behind the scenes, basically it's a lot of dependency injection, right? Which does anyone unfamiliar with dependency injection? Right? It's, you know, you're basically swapping things out. So you're saying every time I want to use logger, swap it out for super logger, right? And you don't have to change your code base at all. All your code can stay the same because it still reference logger, but behind the scenes is actually going to call super logger, right? And a lot of these things that I was saying earlier are possible because Angular's compiler and the renderer, they're not based on the browser, right? So we're able to swap these things out and say instead of creating the app for a browser, create it from Node, right? And, of course, a little bit of magic. So these are some of the things that are typical, you know, when you're making, when an app's being created, right? Like the renderer, you have, anytime you're doing HTTP calls, typically going to call browser HTTP, right? Platform location is anytime the route changes, things like that. And obviously the way all of your styles are rendered, right? Because on the browser, there's native, you can emulate things. So what we do for Universal is basically swap them out and provide something different, right? So anytime the app is about to render things, we use a server renderer, which is, it knows you're a Node land, so it creates them differently, right? And anytime you make an HTTP call, we're actually going to use Node's XHR to make the request in Node, but, you know, everything's wrapped in zones, right? Which is a part of the Angular library. And zones is basically like, it's just a wrapper around, let's say, timeouts, anything async. It lets you know when things are done, when things go wrong, right? And we wrap everything around in that so we're aware of it, right? So if any of your HTTP calls make an error, like when they're done, we're Angular knows, and basically this is how the app knows it's finished rendering, right? Because let's say you get to an app and you make two HTTP calls, one for products and one for to see if they're authenticated, right? Because of this, we're able to be aware of it in Node when they're both done, and since the rendering, everything else finished, all the HTML, your HTTP is done, we say, okay, we're all set, and then we send it off to the browser, you know? So kind of a long story there, sorry. I don't know if anybody cares. You know, and then a lot of other fun stuff like document has been changed to domino, which is just an abstract syntax tree. It's just a different, it's like a JSON representation, not JSON, it's like a long object of your HTML, right? So think of your whole app as objects, you know? So you have like your body tag and then it has children, and that's all of your divs and everything in there. So, you know, like I said, things are different in Node, right? And the other two, same kind of thing, we're just making sure we know how to deal with styles and how to deal with routes changing. So sorry, that was a little behind the scenes, right? So this is the typical Angular app, right? You've got your app module, you have your main TypeScript file, and then platform browser. So basically with Universal, all we're doing is forking it, right? We have two different branches of it. So we're going to have an app server module, a main server, and platform server, right? And this is for our Node server. Everything in Angular app is basically your main component and your normal app, so you don't have to touch anything there. You're basically just creating a little bit different starting point for your app, right? Based on the environment. And this would be really similar if you, like I was saying, if you've done native script, that's done similarly. So just to dig in a little deeper, right? Normally you're using browser module, right? So an app server, we're actually going to import everything that your app module has. So you can see it's like an extension of your normal app. And then we're going to import server module, right? And what all server module is doing is a lot of that dependency injection we were just talking about. So in there, this is like in the actual code, these providers are like, there's like 30 things inside of there. They're basically just dependency injecting over top of everything normal, right? You don't have to worry about this. I'm just showing you in case you're curious. So this is all you need, but behind the scenes it's doing all the magic, right? I'm just trying to make it not as mysterious, you know? And so the other thing that's cool is with something like this, there's two options you can go, right? You can statically generate all of your pages at build time, or you can do them at run time, right? And so what does that mean? Like if you wanted to generate static ones, you could think of like a CMS, right? And your pages aren't that dynamic, or there's maybe only certain pages you want to generate. So in this case, I'm statically going to generate index, about, and contact us, right? And once you create them with Universal, they're just going to toss them in your disk folder, and you can literally just serve that up however you'd like. And those will be regular HTML pages, but they'll be fully rendered versions of your app. Actually rendering is done at run time, right? So in this case, we're actually going to have that node server, and every request that comes in for whatever route, for homepage, for about us, for products, it's going to do it at run time because let's say you're Amazon, you know, you can't statically generate bicycles, right? Every time it's going to be completely different. So this is usually the use case most people are going to go down, you know? And I'll get into this. This is kind of the gist of it. Don't use this code right here because it's kind of just mock. But you can see right here, so basically saying for every request, this is a node server, by the way, for Express, for every request, I'm just going to pass in that AOT Angular module, right? And AOT just means ahead of time compiled. I'm going to pass in that original index HTML page, which usually is very blank, or it just has your app route, the current URL, and when it's finished, I'm just going to pass the HTML to the browser. So really it's nothing fancy. This is kind of all you need. And then a few things, like I was showing in the previous slide, it takes more than a few minutes, but if you download the starter, all this will be hooked up for you. You don't have to worry about it. It's pretty well documented as well. So in there, you can kind of get a good idea of where to start, what's what, you know, what's the purpose of everything. So this is doing everything manually and with render module factory, but I'd recommend just use it. We created an Express engine, which kind of does some of this piping for you. You can find an Angular slash universal. And there's actually more libraries in there, and there's more to come. So this namespace, and this is actually where the old universal used to be, it's going to be, now it's going to be filled with like third party and open source modules, things that make your apps better, pretty much anything for universal, anything you'd want. So keep an eye on that. And using the engines, look, it's a lot cleaner. We pass in that app server module, and that's it. And you can see right here, we're actually passing in the same thing. So for every request, we're just rendering the engine. If you're not familiar with Express engines, don't worry about it, but it's doing what we did on that last page and some just behind the scenes. And we're actually passing in every single request and response. So why does this matter? What's nice is now, because we're doing that, inside of your Angular app, you can actually, using the injector, you can grab these things. So you can grab the current, during a server render, you can actually grab the request and response. So let's say you have cookies or authentication data or anything, you could pass in anything through Node and access it within your app. So let's say they're already logged in and you want the server render to say, welcome Matt or whatever. Using this, you can grab all that data and actually make it within your app. Everybody with me so far? Sorry if it's a bit much. I know it's a little crazy. It's worth it. So I kind of want these, some of these, the next few slides are basically, I wanted to go over typical gotchas and problems with SSR. So these will happen no matter how you do it. So no matter what framework or anything, one important thing to realize is that each one is going to render. So when you hit the server, it's going to render your app, it's going to do it one more time on the client side, right? So why does that matter? If you make an HTTP call and component, let's say component C here, it's going to trigger it again on the client. And the reason it's something like that might matter is because it's actually going to flicker. So first you're going to get all those bicycles, let's say, then they're going to disappear right before bootstraps or when it does bootstrap, and they're going to appear again. So not only are you hitting the server twice, you're getting kind of a bad user experience, things like that. And I'll show how to fix that in a second. If you use anything like window or document inside your app, it's not going to end well, right? Those things exist in the browser, but Node is just going to throw a real sweet error that doesn't really explain anything and just shut down. So no bueno. So how can we take care of some of these problems, right? So coming up in the newest N5.0 is actually going to be something called transfer state. So right now that's an RC, I don't think it came out just yet. But what this is going to do is automatic, you can either manually set things to transfer or using the transfer HTTP cache module, it'll automatically do all of that wiring for you. And it's as easy as literally adding these few imports. So for your app module and your app server module, you just include the cache module. You could see there's one for the browser and one for the server, right? Now when we make that call, it's actually going to send all of that data down over the wire in the index file as like a JSON blob. And it's going to reuse it on the client. So it's kind of nice. So not only did you save or, you know, you didn't make two round trips to the server, you actually got rid of the flicker and the user once again had no idea. They just think your app's crazy fast. So yeah, like another one I was saying, be careful with the window, right? It's only on the browser. But with dependency injection, you could take advantage of it in your app and do whatever you want. So right over here, I kind of just made a, this is kind of like a window, right? Very mock. You could put as much or as little as you want in here. And in here you can see I just kind of stubbed a few things, right? For the browser, I'm going to use dependency injection and provide the actual window. And you can see I'm doing type of window. You want to make sure it's not undefined. Otherwise, you know, you don't want the server to use this because like if I just had window there, once again, no one would have blown up. So this is kind of like a work around hack, right? So for the browser, we're actually getting the window. This whole server has actually got replaced with the massive window object with everything that's normally in there. For the server, you can see we're actually providing and using that mock. So because, you know, in the server, we don't want to touch the navigator. We don't want to do location. We want to make sure anytime someone does window, nothing happens, right? And that line's a little there. Don't worry about it. Right in here, another big, I'd say, pro tip is with Universal, we have something called is platform browser. So whenever you want in your code, you can actually make tests to see and make sure which platform you're in. So you can see here, I'm taking advantage of a couple of things, right? So one, we're making sure we're in the browser. And then I'm using that window service to do something crazy like use jQuery, right? Which everyone, you're not supposed to do with Angular, but people do. Apps sometimes need certain things, right? The world's not perfect. But by doing this, we can actually do whatever we want. So this code basically is completely ignored on the server. But in this case, in the browser, I'm going to do something to the window or to the body, sorry. So kind of cool. It's just a way of basically ignoring things, like hiding it from Node. You know? No, it's pretty strict. And also something new in 5.0 is you can actually use that document that is provided in the Node environment, the one I was talking about that's like an object, JavaScript object. Anywhere you want, you can actually use it like almost like it's the browser. So in here, I'm actually querying a selector. And so anything you normally could do, you could do, and this would actually work in Node. Which is kind of cool. So this kind of just shows what we were just talking about. So this is the same thing, component using it, the browser can that actually uses Window, but because of this, Node keeps running, we don't actually use Window in here. So far so good? Is anybody really confused or not yet? One other big gotcha is just make sure, you know, with any, this is the same thing with any framework, really be careful with set timeouts and intervals, right? Because these things are going to slow down your server render, right? If you put a set timeout or an interval that just never ends, you're never going to get a server render, right? It's just going to keep going in Node and never stop. So same thing, wrap them with this browser. If you want to be really careful, which I usually like to just use that Window service just to make sure you're using the right one. And this, like I said before, just ignores it in Node. That way you get that really fast paint. Because if, you know, let's say in your code you have a little set timeout of a second and then you do some kind of animation. There's no animations in Node, so, you know, might as well ignore it, right? And of course, if you guys want more, there's a bunch of more gotchas and definitely more documentation coming soon. We know that's one of our biggest problems right now. So check out Angular Universal if you want to see a little bit more on that. Let me see. Oh, yep. So in conclusion, you know, I think with all this you can get, I think the beauty of it now is we can get SEO, we got social media previews. We can, oh, why is it missing some of my stuff? Of course. There was a couple more in there. Sorry about that. But basically, now I think we can get the best of both worlds. We can, you have SEO, you have really fast initial paint of your application. That is still really interactive, right? So, yeah, rich user experience. You can post it on Twitter, all everything is there you want as long as you provide it. You know, just be really careful of what you do. So, you know, if you're used to doing kind of things, however, it's a little more strict, you know, but that's okay. The good thing is by doing this, you're at the end of the day is cleaner, it's more platform performance and more reliant, right? And at the same time, you can even take your app and move it to something like native scripts, which has done a lot of these things applied to native scripts. So, if you get used to these things, you can really easily make your app mobile as well. So they have server render, mobile, everything. And one thing I can't stress, be really careful with third party libraries, because if you pick, I don't know, Joe Schmo's random library, he could have window everywhere and it will just blow up. You know, and when something like that happens, you have to actually use Webpack and swap it out and that gets a little confusing. So try to find ones like, you know, ng bootstrap. Material is like almost compliant. Like there are certain libraries that are, they really do things carefully and you won't have any problems with, right? Oh, there they are. All right. That's strange. So with server side render, we also got rid of that loading splash screen, right? Which I think, I don't know if we saw in the demo. All right. So this is the server side render one. When I push F5, immediately we see the app, right? Right over here. Get that loading. So now that's gone. Which normally doesn't matter. If you have a quick internet or anything like that, it's fine. But you know, most of the world has 3G, right? If your customers are using 3G, the stuff should matter. It's going to be a lot better for them. They're going to have that perception. Even if it takes a few seconds for them to get that render, they're used to it probably taking 15 for some complex site to load. And a nice, very loose metric is typically it'll be like two to three times faster for like an initial paint. So depending on what you have going on. Just remember if you have, you know, an HTTP call that takes five seconds, it's going to wait five seconds for it to render, right? So doing some of those tricks we were showing earlier, you can actually, maybe make sure you ignore that call on the server, things like that. So we went from this to this ugly thing. But now we have all of our code, right? We got our titles, our metas. You can see down at the bottom even like, that's like some of the HTTP call that was cached and sent along with it. So like we were saying earlier, can we get the best of both worlds? I mean, I think yes, but it takes a little bit of work, but I think it's worth it. And thank you guys. Thank you.
web. Let's talk about server-side rendering, client-side rendering from now on, like CSR. So like that. The new Angular is very abstract. So to start. And if you even want to take a look at with it easily. So before I get into how it imports. So for your app module and your app this is the same thing, component using it, the social media previews. We can, oh, why is it ignore that call on the server, things like that.