 Okay then, so hi, my name is Tejas, I'm going to be speaking about horrible mistakes in isomorphic rendering. I know there's already been like about a dozen talks today that speak about isomorphic rendering or universal rendering in some form or the other, but I hope that at least my, like I'm not going to hopefully cover what everyone else has already covered. So before I start, a little bit about myself, that's my Twitter, that's my GitHub. My team doesn't let me actually write any code anymore because every time I do, like everything goes flat. So yeah, there's that. And I currently work at Quintype and we're a pubtech platform. We have like a dozen publishers that we need to isomorphically render UIs for them. We're in the media space, so server-side rendering is very, very important to us. Oh, and it's our two-year anniversary today, so hooray for us. Well, actually technically it's yesterday. This brings me to another point that I tend to be very factually inaccurate at a number of points, but well, please adjust. Yeah, so why are we all here? So fundamentally the web moves pretty fast, right? Oops, and so do my slides. So once upon a time everything was server-only, right? And it's even hard to imagine this day when everything was just rendered server-side and every time you would click an email in Hotmail, it would take you to a completely new page, right? Around 2000, we got the XML HTTP request, maybe 2003. And so this really was a game changer, obviously, right? And this was made famous by Gmail, which would render your email really fast. And the next major advancement towards what I would call isomorphic rendering came with Google Web Toolkit. Now, this is not a thing a lot of people speak about these days because it's not as commonly used. But in essence, what this would let you do is it would let you write both your backend and your front-end code in Java, right? And it would somehow do some magic and the Java that you wrote on the backend would be magically compiled into HTML views on the front-end. And so for me, this was the first people really trying to do this isomorphic rendering. And then finally came isomorphic rendering, as we know it, made incredibly popular by React even though a lot of people have been doing it in various forms the years before that. And those are some of the things that I'll talk about. And of course, I mean universal rendering. This seems to be the term that's come up at, well, the first time I heard it is actually at this conference. I'm guessing the difference is that universal rendering also covers native applications. And I'm going to speak about, yeah, and beyond isomorphic rendering are your progressive web apps and the bright future that we're all moving towards. So what is isomorphic? Basically, similar in form and relation. That's a Wikipedia definition. I really don't know how that relates. But what it means is that you're rendering the same thing, server side and client side, right? And that's what I want to speak about different patterns for this, right? So why did we specifically need this is sorry, and I'm showing like something from Quintype again, is we render publishers front-end. This is a news site. And, you know, it needs to be completely rendered server side. But in our CMS, we want to let you see what your story is going to look like as you as you type stuff. So we kind of have like, you know, as you type, it, it updates an iframe and, you know, things, things move, right? And of course, this has to happen without duplication, right? You don't want to rewrite everything and have it exactly the same across your back end and front end and possibly different languages. And in fact, I'd love to meet the programmers who enjoy this amount of duplication, right? And it's not just for weird previews, like, and one-off use cases, like here's, here's like at least a bunch of reasons for this. Why you'd want this, including things like a load more infinite scroll, reloading the page, or even on horribly slow networks for sometimes your JavaScript doesn't load. And you don't want to give those people an awful experience, right? So a lot of talks in this conference have been about, yes, we tried this and, you know, every everything worked. My talks pretty much going to be the exact opposite. It's going to be how I tried all these things and we failed miserably. And, you know, why you should try this and fail in the same way or not. Yeah, so actually, this looked like I was supposed to talk about 55 patterns. I'm not I'm going to cover just about seven, right? So before I actually get into too much server-side rendering, I know this has kind of been touched, especially by Ankur yesterday, but do you even need server-side rendering? It's actually very interesting because we've arrived at a place where 10 years ago, client-side rendering wasn't even really possible, well, 15, client-side rendering wasn't even possible. But today you can, client-side rendering is almost a given. And the real question is, do you even need to do server-side, right? And this has actually become a very acceptable pattern, right? People have spoken about this quite a bit. I'm not going to cover this in too much detail, but in essence, this is what you would do if you're rendering something client-side. You'd have your layout, you'd have a container, you just have nothing in the container. And then server-side, you render, you know, you boot React or Angular or whatever framework you would like, right? And this has, you know, some benefits. It's great for internal apps and things when you need to log in. And it really solves our problem. There's no duplication. It's, everything is completely, you know, there's just a single source of truth. And with the usual problem, it's slower and it doesn't support people who don't work for JavaScript. And, you know, you're, in essence, you're relying on meta tags for SEO. So how can we improve this? What can we do for two of these problems? We've already spoken about how you can load a layout only, right? Facebook actually used to do this quite a bit. You'll see that not only is the layout loaded, there's one empty story that's rendered over here. And quite frankly, we also used to do this for quite a while. What we would do is once a week, we would just do a React DOM server to render the string. And we'd save this in a text file somewhere, right? And then the next time, I'll just use that straight, plain text file, right? And again, it's an empty layout. It's just showing you boxes with nothing in it. So that doesn't need to change very often. So, but this kind of relies on you defining an empty object. So for us, that was a story with no headline. That's, that's my empty object, which I can render without any problem. And now that your layout only, you know, the next step is a progressive web app. This is, this is like kind of the step just before that because you can easily catch this. And now you can move towards a progressive web app. And the other problem that we actually had was, you know, how we only have meta tags for SEO, right? So we actually thought, okay, let's cheat a bit. Let's, let's just stick on, let's just stick on, like, you know, a div saying content for bots. And this will get wiped out once the component actually loads. And what we tried to do over there was we even put it like, you know, opacity at like 4% so that, so that no one can see this ugly, unstyled content. But of course that never works. And in reality, someone complained because they could see our ugly, unstyled content. And I don't know if you can actually see it as too faded. So what does isomorphic rendering actually look like? So let's talk about Node.js. That's what everyone seems to be using these days. Yeah, it's really easy to isomorphically render stuff in Node.js in a sense. And I know again, I'm kind of mentioned some of these things, but you just do a render to string with the same components that you would that you will mount later. And of course, virtual DOM, it's the greatest thing since Nutella. And it will, it'll basically take over. You don't have to pay that penalty for reloading your entire, your entire DOM. Yeah, so the only, the only two problems that I've kind of have come into this is it's hard to do this after the fact. When you already have a JavaScript, there's enough, you will have done enough hacks and stuff which would be very browser specific such that it's hard, sometimes hard to port this to Node. And I'm also calling you can actually crash your entire server if, if, if you, if you have badly maintained badly written front end code in this model because it's the same code running. So I think, I think one of the mistakes that we continuously do is you need to remember the importance between a component will mount and a component did mount and remember that the first one runs on the server. So if you're trying to access something, you can actually take down your entire, you know, your Node app. Oh yeah, you can, it'll get relaunched and stuff, but you'll start noticing that your requests per second are dropping pretty drastically. So for this also, we had a small solution. You can play with, with the Node ships with a, with a module called VM, which allows you to actually load untrusted code inside a sandbox and you can, yeah, and you can run your code that way. Okay. So anyone think of the Ruby developers? This is my, this is, this is really the, where I'm actually starting the real important thing of my talk. So how many people are using Node.js in for their back end, like show of hands? Yeah, it's about 20% of my audience, right? So, so, so what about everyone else? What, what is everyone doing? And I was just joking that the node people are just stealing jobs from hardworking Ruby developers, right? So let's get to all the anti patterns that you can do in this world, you know, when you're running a different language at the back, at the back end, and hopefully we'll get to some patterns as well. So the first is HTML APIs, right? And this is the first one I see every single programmer coming in doing on every single project. They will always do something to this effect. And I'm going to switch to Ruby for a bit of time, right? So in essence, this is what it looks like. So I'm going to render, when I come to the story page, I'm going to render the story page with a layout. And then when somebody calls the API for the same page, I'm going to render the exact same story with no layout, and I'm going to return this as a JSON object, right? This looks actually, it looks like it works because it works really well on your development laptop, right? And it's great because there's no duplication, but it's widely considered a anti pattern. So why? Well, all of a sudden you, well, so first of all, you get to have fun playing this new game that you magically invented called how did this HTML get over here, right? And you're continuously looking at the various calls because you're in essence rendering bits of HTML from a server and embedding it somewhere else without like context. And you'll continuously be wondering how did your HTML get over there? And as a second added benefit, your super fast API call is now ridiculously slow, right? The slowest thing about Ruby on Rails typically tends to be server side rendering. I mean, you're rendering of your views, right? So you're in essence making your APIs also start to render views. And this is horribly slow. So you will increase your Amazon bill by double and you won't know why. Yeah. PJAX and turbo links is in essence the same thing. How many people are familiar with PJAX or turbo links? Yeah, very few. Anyway, so in essence, what you'll do is you'll make a, AJAX request and get an entire new page and you'll strip out everything outside the body or the container and you'll just dump it right onto the page. The argument here is that reloading the whole page without reloading the JavaScript and CSS is a lot faster than actually doing a new page load. It is very true, but it's fundamentally the same thing. And for that reason, you will still see the loss of performance based on your, based on your network calls and your rendering. So that brings me to pattern number four, which is moustache, handlebars, and liquid. This actually is pretty viable. And so when I was talking about different patterns of isomorphic rendering in the non-react world or the non-angular world, this is actually what people do. These became incredibly popular after, I think, Ryan Bates from Railscast did a quick Railscast on how to just do an infinite scroll with moustache and an API. So in essence, your moustache code looks like this. It's logicless. And I'm going to speak a little bit about this logicless and why it's very important to us, but in essence, this is what it looks like. It looks pretty, if you're familiar with other templates, it's good. One difference that I wanted to call out is this is actually rendering a string. So unlike JSX or unlike other React-based things, this is actually not rendering a virtual tree. So if you want to do any virtual DOMs type stuff, you will need to do that yourself. So the benefits of this is it works across every single language. And you can even try out for little bits of it. You just have one component that you want to turn into moustache. You don't need to rewrite your entire architecture. You can just move that one component into moustache and render it isomorphically. And I'm going to say it's incredibly secure. So what do I mean by it's secure? On my first slide, I was mentioning that we're actually running tens and 20 templates, some of which are not even written by us. So what stops any of these templates from suddenly throwing an exception and taking down chunks of my server or overriding some global object? Moustache, handlebars, liquid, twig, these things don't let you run arbitrary functions, arbitrary code. They're very well defined and they have a certain way of accessing data. And of course that comes to the price. They're amazingly hard to write. It takes a long time. More than once I've been tearing out my hair going like, oh my God, why is this, how do I write this loop in a certain way? But there's also a bunch of practical problems that come with them, not least of which is that handlebars, for example, is very tight to javascript. So even the Ruby on Rails version actually moves and kind of uses javascript to run it. So this brings me to the fifth pattern that you could use, which is to, in a sense, bring your own language to the front end. And this was made incredibly popular by ClojureScript. And this was important to us because we at Quintype were also a Clojure shop. In essence, what this does is it's, this is also built on React. I think this is using rum, which is one of the ClojureScript built on top of React components. But what this has in essence done is it's introduced a second level of, in essence, JSX. It's represented a second level of, to represent this DOM tree. And this uses syntax, which is known as hiccup, I've just put that over there. This pretty much works exactly as you would expect it to. It does work. But again, there are a bunch of advantages and disadvantages. This is not a goldmine. You can even generate CSS, by the way, from Clojure. But it's impossible to A, find people who do this side note that we're hiring. And you'll end up passing Clojure objects around. So again, this is another one of those things that when you get started, it looks like it's really great. It's like, I have an ordered set on my Clojure Java backend. And when I pass this to ClojureScript, I magically have the same ordered set. But as this gets deeper and deeper, you'll realize that there are very fundamental problems with this. Another one of the reasons that GWT kind of fell out of favor was that it very much blurs the interaction between the front end and the back end. And when you kind of hide that, what's a network call and what's a local call, you'll start writing very, very unperformant code. Again, these are very problems that you can solve by training, but it's still, you know, there's still problems. And the tools and debugging is also pretty slow. I mean, pretty hard to use at times because what you have in your browser is a Clojure object, which is represented by an array of JavaScript objects. And unless you know the Clojure thing very well, you're not going to use it. And as an added bonus, you get to add line again to the list of great package managers that, you know, that you use for JavaScript. Okay. And so what we finally ended up doing mostly is use in essence a rendering server, right? And so yes, in part, this is again, just relying on node.js, but I'm going to speak about two or three different attempts we, we did at this, right? So the first is actually kind of well, well explored, which is phantom.js. A lot of people use phantom.js for testing, but it's also widely used in the Ruby community for, for rendering HTML as well. What it actually does is that it just takes a HTML body and it actually evaluates whatever JavaScript you've written. It actually has its own DOM in memory. It has, it does everything. And because it does all of this, it's actually a little bit resource intensive, right? But you can cache this for content that's not moving very fast. It is very easy to render with phantom.js and, and cache this content so that you, you know, you don't have to worry about it again. But we thought, can we do a little bit better? Can we just take the exact same architecture and use some of React's inherent, you know, benefits, right? So we tried building our own rendering server, which is, yeah. Internally, we still use this for quite a few things. But in essence, what it's really not that many lines of code. We, I've removed some of the VM stuff, but in essence, what I'm just doing is I'm listening on some port. It's a Node.js app. And really what I'm doing is every request, I just look at what page do you want me to render. If so, I just render to string with whatever arguments you want. So fundamentally, what I do over here is I, is I send my rendering server JSON, I get back HTML, and I munch this with the HTML from my layout, and I, and I return it back. And I was pretty impressed with, with, this will, this is actually pretty fast on very cheap Amazon hardware. Yeah. If you're on the same machine, you can like, kind of sort of get almost like five or six milliseconds for this or less. Yeah. Okay. So the only problem is it's, it's a bit tough to maintain. You need to put this into your asset pipeline. And if you come to our booth, maybe I can talk a little bit more about that. But in essence, what we have to do is after you pre-compile stuff, you need to bundle this server to use the latest version of your assets and make sure there's no discrepancy between the assets that you serve and the assets that are statically rendering stuff. Otherwise it'll get very confusing. And if you have 10s or 20 themes, this also starts becoming incredibly hard to maintain. Right. And one more, one more, actually this is an open source app called a shunter. This fundamentally takes all the same ideas, except it switches around the direction of, of what's going on. Yeah. By default, you're rendering server that is shunter acts as a proxy. Yeah. And just forward all requests back to your API server, web server, whatever it is that's, that's behind it. And in case you respond with a magic header, in this case a magic content type, then it'll render its, its layout right there. So in many ways, this again just becomes, it's a very good separation of concerns because you can, you can split your API out and, and just, you know, have a server dedicated for the view thing. So it also forces you to separate your code base in, in a very clean way. Oops. And of course, the logical extension of this is to just coming back all the way to the circle is to have a service oriented architecture where your APIs are served by whatever your front end is either with JavaScript or whatever. But just keep in mind, this also is not some kind of, doesn't solve all your problems because you might, the problems with large service applications kind of come up in which case now you have 10 services and each one needs to manage their own caches and figure out when to invalidate. And yeah. So, so that, that's sort of my summary. Choose what you'd like carefully. I didn't come here to tell you that this one way of doing it is better than the others. And yeah, it looks like I'm making up for lost time. So does anyone have any questions? Okay. I guess that's no questions then or no questions. Okay. Thank you.