 fel y g ceremoniol Monika, addysg salaries nine hundred years he, you have to say to me I blitz through this in 13 minutes ninety one slide in rehearsal and that's the they said just cool it down. So, hi. My name's Robyn Glen and you can find me on Twitter I'm Ariel Leggs and I'm going to talk about a journey from components to applications. With being where we are and if I say to you that I'm from the big L you all know where I mean right? That's slGood Rydyn ni'n dweud bod yn Llandon o yo'r Lll Lqc, fel hyn gyntelol i'r Llandall. Rydyn ni'n dweud bod y company o'r unrhyw gyrtaeth uxneth porte. Rydyn ni'n unrhyw gyrtaeth agnod. Mae gennym ochr o wefbcyddol, phogsofyn a wyllfau'r mlynedd yn yr unrhyw. Cyngor i wych yn ystod, roeddwn ni wedi bod yn y cyfrannu gwysig yn hond o'r polmau cyngor. Rydyn ni'n hond o'r polmau inni, felly rwy'n credu yn ddweud y pobl maen nhw'n meddwl, sy'n meddwl i'r pwysig, ond ond nesaf'r sy'n meddwl. Rwy'n meddwl chi'n meddwl am yma, ac felly rydw i'n meddwl am y cwmddiadau a nhw'n meddwl. Felly, mae'r ffordd o'r cyffredinol yw'r cyffredinol a'r ysbyddiadau i'r ysbyddiadau a'r dweud o'r cyffredinol. Felly, mae'r ffordd i'n meddwl am y cyffredinol, mae'n meddwl i'n meddwl. I want to talk about Y Web Components, but I want to take a different stance and not talk about it as a technologist or a developer, but I want to talk about it from a designer UX perspective. So previously our design team would, they would submit this for a sign off. So they would design a page, this is an example of a listing page, and they would pass it to the company to get sign off so we could go ahead and build it. What they found was the comments could be quite subjective. People would like, okay, we like this here, but maybe we'll change this H1. And then what you get is, well, bottlenecks, but designing consistencies. So what they wanted to do is move towards a design pattern coined by Brad Frost called atomic design. We build in small atoms and then a collection of atoms become a molecule, a collection of molecules become an organism. And they wanted to move towards this pattern so they could eliminate these bottlenecks but also get consistency across their designs. So they were looking to get something like this signed off instead. So a collection of components, and that's what they would get signed off. And then when they wanted to build something, they would just structure a few of these together. So this led us, the designer UX team, to come up with this concept called atomic components. So we wanted to move the front end to align with the new design pattern that the back end was doing. So I wanted to go over the principles, sorry. I wanted to go over the principles of atomic components. First of all is standardising the rhetoric. So what I mean by that is the front end team, the UX, the design, all the way to the API teams are talking about the same thing in the same way. What this helps us do is get a better understanding of each other's problems, promote collaboration, but then instead of thinking in technology problems, we think in customer focus problems, the next is granular thinking. So we wanted to break everything down to its finite point. There's a talk that Apple say which is using the simple stick, so you just break everything down into its smallest piece. So using those principles, I'm going to talk you through an actual component which is called NAT product summary. And we're going to use these principles to build this component up together. So the first part is the nucleus. As a designer and a developer you're probably used to this point where you break things down like what's on the page. So first of all is product image. We've got a badge which identifies what type of product it is, designer name, product description and price. Those are just the primitives of this component that we need to build it. So next thing we layer some more stuff on. So let's look at states. This component will have some states. The first is a skeleton state. This is the preloaded state. Before the product data has come back or it's rendered completely, this is how it will look. And then you have a loaded state, which is the next state on top. So next thing is interactions. So now we're starting to build interactions into the component. So the most basic one is the link. So it generates an SEO friendly URL for the HRF of where this product will take you. Next is some kind of interaction of hover or tap. So it's like a rollover state to show two different product imagery. We're going to build on again and we're going to add some behaviors and rules. So we've got a behavior for if the image is broken. For some reason the image hasn't been uploaded. We don't want the standard broken image so we style it up a bit. We also use responsive images using image source set. So that's another behavior. And we use schema tags to identify what the product is. I'm going to go into that in more detail later. So let's add another one. It's a testing. It's really important for the component to be tested. And so we can abstract some of the complexity away from the end testing. So we do a couple of different types of tests. We do unit tests. This is just to make sure that the product is working how we expect it to. So does the product behave how we expect it to when we run these tests on source labs for multiple browser operations? We also do SEO tests. SEO tests are to... Sorry. Can I have a glass of water? SEO tests are just to make sure that the product looks exactly how we think it does for rich media snippets. Finally is visual testing. So what we do is with a level of tolerance we test across different browsers just to make sure that the product looks the same on every single browser. Sorry about this. OK. So that's our testing done. Next is documentation. Documentation is really important for our consumers and our other clients to adopt this component. So self-documenting using the polymer standards. It's also got a demo. So how do you use this component? Versioning. So we add versioning so different consumers can change the component but then subscribe to the changes when they want. Sorry. Next is Mondrin. I'm sorry. Next is Mondrin. Does this component need some way of registering how it's performing in the wild? And then all of those together make an atom. So you can see this onion skin in effect of all the different things that we want to apply to the component building up and you abstract complexity away. So using these principles let's build something. I am nowhere near brave enough to do this in front of you. So in blue Peter style. Here's one I built earlier and this repo is available and open. So if anyone wants to check this out and apply this work that I've done feel free. The repo is there. My GitHub is the RG so you can get it. So we're going to build a simple product component. So it's the net port a one I showed but we've just removed a few parts. Okay. It's going to be code heavy here. This is how you would use the component. There's a product attribute and that has a string of five bit of Jason and that's the data contract for that component that everything that it needs is inside there. I don't expect you to understand it all but this is how you line up with your back end teams to make sure that you get this data through. So here's the template. This is how you'd use it. You can see there's a bunch of product dot image or different product product attributes are just being passed through from the attribute we previously seen. I want to focus on one specifically. Which is price. You can see that we never pass price through. Let's look about how this works. Surprise is a property but it's a computed property which means it's going to get generated before the component actually gets rendered. You can see a simple private method there. Compute localized price. You pass it the product price and the locale. Let's have a look how that works. So here's a simple method as private. It's documented at the top. This is how you if you want the self documenting code if you write like this you'll get it all for free. So what does it do? It's basically just returning the price but using locale string to put the currency and depending on the country where you put the comma or the full stop. So that's that's all that methods doing. Let's look about how we might go about testing this and we do two different types of testing. The first we'll call it a unit test. So we use a web component tester as you've probably heard people talk about today and we also use fixtures to stamp that in the DOM to make sure it's clean every time we run a test. And what we're actually testing here is we're calling the private method, stubbing some data in there and just making sure it works how expected to. So it's like this is a unit test. The next type of test, however, is a component test. This is to see does it work inside the component? Is the component doing what it's expected to look like? So you can see here we're doing a simple assertion again using fixture. The assertion is checking the text content inside a selector making sure it's the right value. And we're using this element dollar dollar notation. And the reason we do that is if you just did a query selector directly when you try and run these tests in shadow DOM it can't pass the shadow boundary so it'll fail. So we use that as shorthand for Polymer DOM just to inspect. The next is structured data. So structured data is a way of identifying what a product is, what it looks like so Google can come along and see what it is. There's a link there to a product schema so that how you mark up a product. And basically the two minimum things you need to do is you need to say hey this is a product and this is the name. And then you can pass this to Google's structured data testing tool and it will validate it for you like it's done here. Is that correct? So what we need to do first is put on the host attribute that it's a product. So this is all this is doing. The host attributes inside your Polymer constructor will allow you to do this. The next is we're going to mark the name as the name with this item prop which is saying that property name is the name of the product. So we want to be able to do this at CI level though, right? We want to run these tests at automation. We don't want to just copy and paste into Google's structured data tool. So there's a module here that we created that will act as a proxy and do that for you. So if you want to automate this testing you can. So again it's on my GitHub and if you've got that repo you can do it. And I'll just explain quickly how it works. So this bit of code when you're setting up your tests you grab the entire outer HTML and you're going to pass it into this method that's basically going to proxy a call off to the API returning back some JSON that you can run some assertions on. So you just need to get all of your HTML and pass it straight into this module. And then you can run some assertions. So these assertions are saying are there any errors? Is it a product? Is the product name correct? So now we've got automation testing of rich snippets which is awesome. So we built a little component. We want to get to applications now. So this is a simple listing application. Again built. It's on GitHub that's available for you to check out. It's got full automation tests and you can play around with it. It's pretty ugly, I'm sorry, but I just wanted to show you some simple features that you can do. So this is the template. You can see it's got a few sub-components. So we use an INA jacks as a wrap around XHR requests. We've got a thing of product list header. So that's just the name of the list. We've got pagination, which is the controls. And we've got a list of products. So you can see how we've broken apart these sub-components. And each one of these sub-components can have their own levels of tests. So they can be tested in isolation so you don't have to test everything together. Just how you expect it to work. Let's look through some of the things on here. So we've got auto on INA jacks. What this will do is it will automatically make the XHR request for you. And then if you make a change to the API call, it will again automatically make that call. So we've got URL. Again, I just want to look into this because it's going to be important when I build up this structure. Again, the computed style. And we're going to pass in products per page and page number. The page number here is the key part that we're interested in. So just picture this and I'll build it all back up. But just so you know, so page number here is going to pagination. And it's got two curly brackets, which means it's got two-way data binding. And that's again going to be really important when we build up this application. So let's look at some of the components. The header one, all it's doing is generating the title. So I'm not going to go into that. But the one below is pagination, which I've just tried to highlight for you there. So let's look into that component. So what's it got? Some buttons, previous, next. It's got a description to tell you what page you're on. And then on the buttons, we've got some on-click events. And let's look into those. So we're going to call pagination next. So when we click it, we're going to set page number, and we're just going to increment it by one. So that's all we're doing. We're just saying, hey, when we click that, update the page number by one, and that's it. So what does that do? Page number's got this notify property on. So I know that there was a Dataflow talk yesterday, so people might be kind of aware of this now. So this notify is just going to say, hey, I've changed. Alert my parent that something's happened. So now let's look at the list. The list here is a collection of products. But it's in a DOM repeat. So what we're going to do is we get an array of products back, and we're going to iterate through each one of those and pass them into our simple product component. So we had that big stringify JSON earlier. What we're going to do now is we're just going to pass this reference directly into that. And this is called the mediator pattern. And I'm going to try and talk it through so it's hard to understand, so I'm going to try and build it back up. So in pagination, you hit next. It increments that page number. That's alerting the application above. So the application's wrapping around these two subcomponents. So pagination tells application the page number's changed. The page number's computed URL, then. Automatically updates the API call and Ion Ajax on auto goes and makes the call. So it's gone and made the call, got some more data. It's then passed it down to the application, and then the applications pass it down to its children. So you can see the list would update. OK. So now we need some more real-world stuff. So we've had some pagination, but our customers want to know, or our clients want to know, hey, is anyone using pagination? Let's add some tracking so we can do that with behaviors. So what we're going to do is we're going to file this event, pagination, and pass the page number. Then in our pagination component, we're going to inherit this behavior. So we're going to add this behavior called product tracking behavior. So when you create a behavior, I'm going to show you how you do that here. It's just another HTML import, and you define it like this. So you're saying, OK, let's create a new behavior, add this property, and inside there we'll have a listener. And the listener is going to listen for pagination, and when it gets it, it's going to file track event pagination. And here there's just a simple example of how you could use request idle callback to do some beacon in pagination. Paul Lewis has actually got a great article on this. It's linked in the GitHub, and it's here, but it's how you'd use request idle callback now to track that analytics. So using these principles, that's all we had, these kind of patterns, it was how we created our new listening application, which is here. So this is currently being rolled out and beta to a couple of a few high-end customers who try out specific products for us first. But if anyone wants to see it, come and talk to me after this, and I can show you where it's working. So I want to talk about some specific parts of this, and look at how some of them work and what we build on top of it. So this is a sample of the application, and I know there's a lot of stuff so don't worry about reading what's there. But what I wanted to show you is it's multiple components all broken down on top of this one. So we have stuff for errors, we have stuff for certain customers and personalisation, we have things for loading states, we have a rotor, we have a header. All of these sub-components build up this application and each one is tested in isolation so you don't need to worry about that complexity. It's all abstracted away from you. So I want to talk about some of the more exciting bits in this application that I think are quite exciting. So the first thing is performance. So we try and adhere to the rail guidelines and I want to focus on a couple of things. I'm going to leave it run because it's actually quite hard to talk when it's happening and show you and then I'll explain the theory. So it's a short gif. So this is skeleton CSS. This is the loading approach that we took. So when there's no product data we want to show something. So we get something on the screen as quick as we can and we don't know what it's going to be so we just scaffold out the page. And in testing what we did is we put this versus a spinner with artificial latency and showed it to customers and people thought the one with the spinner was actually slower even though it's the same artificial latency. So it's just to get sending on screen as quick as we can. OK, so the next one is pagination. I'll leave you watching and try and explain what happens. OK. So what we do is when we're going forward product data and load images and we put a spinner only when it takes more than 400 milliseconds based on Rails guidelines. So what it's actually doing as well is the spinner is only there and it cares about the images that are in the user's viewport so they don't care if the bottom image hasn't loaded. They only care about what they're looking at. So the spinner is based on the promise of the image loading that's inside their viewport. And when they go back you can see that it's instantaneously moving back and so we don't show the spinner or any transition, it's just to keep it going. Again, this is to adhere to the guidelines of Rails. Next I want to talk about telemetry. Or is it working? If so, how well is it working? If you've ever looked into the Web Components polyfill, you'll see that it fires an event called Web Components Ready when it's bootstrapped itself. You can actually latch onto that and we do something that's quite clever with it where we add an event listener for Web Components Ready. When Web Components Ready happens we run this try catch. So we look for the component on the listing page and we look for this .is method and the .is method, if the construct has been upgraded will become available. However, if it's not available it will fail and throw this error. So what we're doing is we're saying has that component been upgraded to a polymer component? If it hasn't, let's catch that error and then we've beacon some data back. We say, is polymer defined? Has the HTML import for that component successfully been imported? Then this just allows us to understand what's happening in the wild. Is it working? If it's not working how do we debug it? When you move a lot of stuff to client you lose all of the logging that you would have gotten on server so you need to compensate for that somehow. This is one of the ways we do it. Also we do some API availability and performance checks. So this is like, okay, did the API fail when we tried to get products? So you can see that there's some errors rates there. If it did fail, what's the status code? What was the reason that that API failed? Then we have some API latency. So it's like, how long did it take to make that API call and come back? These are great as developers. We can debug and we can look and we can delve deeper into what's going on with our application. But they're not great for our business customers how well is this performing for our customers? So we also have some other metrics. So this is customer performance metrics where it's more tailored about how it's working for our customers. So the first one is time to remove skeleton. So when you saw the skeleton state and when the products come in, that's how long it's taken. But not since you landed on the page since the first network request came to our site it's rendered, painted and then removed that skeleton. How long is that taken? So we can tell our product owners OK, we can say it's within like under three seconds, three seconds-ish that they will see products from first trying to land on that page. And then there's time to load paginated products. So this is when you go right, I've clicked next I'm waiting for the spinner and that's removed. And we can have metrics on that as how long it takes them. So the summary. I went a little bit fast, I'm sorry. I hope that all made sense. But there was a lot in there. But I just want to kind of summarise these things. Invest time into reusable, accessible, tested granular components. And what I'll help you do is promote code reuse. Your developers will be able to find this code, adopt it and not reinvent the wheel every time you create something. This also helps for design and experience consistency. So your site works and behaves the same each and every time. It also allows you to abstract complexity away from your applications. So because you've put all of this testing effort into these small little components your applications don't need to have as much coverage. Plug and play components strain to your application so you can spend more time on customer experience collecting an understanding customer focus metrics and do the fun stuff. You don't want to reinvent the wheel every single time. No one wants to write fetch or XHR request multiple times. You can use that component and plug it straight in. I thought of a really nice way to summarise this as we're in London as well because if you look after the pennies the pounds will look after themselves. Thanks for listening. That's me, Robin.