 Hey there, polycasters. Rob here. Welcome back to the show. So it's been a little while since we last talked. In the previous episode, we started off a series using carbon route to build an application. And actually, since we did that episode, the Polymer team has renamed that element to app route. So we're going to be picking up where we left off last time. This time, they will be using app route to continue working on our blog. And what we're going to do is we're going to make sure that we can lazy load content on this blog. And we can also manage the flash of unstyled content that we see when we switch between pages on a slower connection. So to grok what I'm talking about here, let's switch over to the laptop. And you'll see that I've got the blog, as we left it last time, showing here. And I'm going to just go over to the network panel. And I will click this tab right here. And this will let me actually throttle my connection down. Let me zoom in on this a little bit so it's easier to see. So I'll go to the network tab. I will go over to right over here where it's just throttling. And we can set our connection to something like regular 3G. So this is what someone on a typical cell phone connection is going to experience when they're trying to use our site. So maybe I go and I click on the film section. And maybe I go and click on one of these posts. And I go back to the art section. And you just see how there was kind of like a moment where we saw a flash of the old film section when we switched to the art section. That's kind of the thing that I want to address today. I want to deal with that flash of unstyled content. Make sure that when our users are using our application, the only thing that they're seeing is kind of the relevant page and something that's really fresh and up-to-date. So to do that, we're going to switch over to our code editor. And this is where we left the project last time. And I've already gone ahead and renamed and downloaded our app route, renamed it throughout our project. So we don't have to do anything there. Any place you see carbon route in the old project, we can just update that to app route. The API and everything is still essentially the same, just kind of a small name change. So thankfully, we don't have to do a lot of work there. Now one thing that we do need to do, which I noticed in the previous episode is I made a little mistake in this blog app element. So if you see down here, when we set up our iron selector menu, in the previous episode, I was passing category data as this two-way binding like this. And while this is cool in it, this approach did actually work, what was happening was it was creating this weird situation where when you clicked on this binding, because it was a two-way binding, what happened was, first, it would look down at this data page element, and it would say, oh, you're trying to go to the film section. So I'm just going to update carbon location to slash film. Then it would see that, well, actually, we clicked on an anchor, so we want to go to slash film slash list. And it'd say, OK, cool. Well, I'll update it to slash film slash list. Now, what would happen then is we would change the URL twice, really, really fast, so fast that no one would notice it if they were just looking at the site. But if you hit the back button, it would go back to slash film. We don't actually have a film page, so everything would just break. So the fix there is pretty simple. What we want to do is we just want to change this to a one-way binding. So basically, the menu always gets its information passed down to it from carbon location. And if you click an anchor or something, it'll dispatch that event. That'll go back up through carbon location, back down to our elements. This nice one-way loop. And that solves that bug. Now, the next thing we want to do is we want to tackle that funky, weird, flashy one-styled content. And there's two things that are going on here. The first is I'm loading new JSON for the page, so our text is going to swap. And the second is we're loading new paths for our images. And those actually have to go out and fetch the images and sort of redownload them. So I want to tackle each of these problems individually. I'll start with what to do so we don't display kind of like stale or outdated text. And my thinking here is I'm probably going to display an overlay over the screen with a little spinner. So that way, the user doesn't see a weird swaperoo with our headings. They just see a spinner page. And then when that content's finally ready, it just sort of reveals the new heading and the new paragraph content. So to do that, I'll go over to this blog pages element. And I'm just going to go ahead and drop in a div. I'm going to call this overlay. And inside of here, I will drop in a paper spinner. And I'll just leave it with this active attribute. And I need to go up to the top and make sure that I have imported paper spinner, so far so good there. And then I'm going to go to my overlay. And I want to give it some CSS style so it's actually like full screen. So I'm going to drop in a little bit of CSS. I've already got the CSS save because I'm totally cheating here. And I'm going to boost this up a little bit and read it a bit easier. OK, so here I'm positioning the overlay so it's absolute. Top, left, right, and bottom are all zero. So it's actually going to stretch to fill the entire screen. I'm sending it to display flex and setting flex direction to column and align items and justify content to center, center. And that basically means that paper spinner child that I added there is just going to be vertically and horizontally centered right in the middle of the screen. And finally, I'll set the background to an opaque white so it hides whatever page content is behind it. So we can actually just verify that this is working. I can go back over to the blog that I was working on. I can probably go ahead and close the dev tools and refresh the page. So now we're just seeing that overlay and that spinner. It's blocking all the page content. So I at least know that that is working. But I only want this to display when we have a page that is kind of in a loading state. So what I'll do next is I'll go into my list page element. And remember, list page is the one that lists all of our individual blog posts. I'm going to give it a loading property. So down here in its properties, we have active for when the page gets swapped to by our route. But it could still be in a loading state then. So at a loading property, this is also going to be a Boolean. The value is going to default to false. And I'm going to set it to notify true because I'm going to need to have the outside world listen to this as well. So next, I'll go up to my IronAgeX element. Now this is the one that's sort of loading all of our blog post data for this page. And it actually has already inside of it, IronAgeX has a loading property. So here I can just bind my loading property to its loading property. So that's pretty nice. So now this page can kind of tell the outside world when it's loading. And really what it's doing is it's just sort of telling the outside world when IronAgeX is loading. So back in blog pages, which is sort of the common parent of all these guys, I will add a property or an attribute here. So I'll listen for this dude's loading property. And I'm going to call my attribute just so I can differentiate them a little bit. I'll call it like is loading, right? So I can do that here. Now down in my overlay, what I'm going to do is I'm going to bind the state of the overlay to that loading property. So we'll say, OK, we'll use the HTML hidden attribute. I'll use the dollar sign binding. So I can bind right to the attribute itself. And we'll say that this is one of those fun double negative things. So we'll say, when is loading is false, hidden should be true. Yes. OK, so when is loading is false, hide the overlay. When we are not loading, hide the overlay. OK, this is one of those things where you've got to think about it for a second. And then the active state of our spinner, we're actually going to do the reverse. We're going to say, OK, well, if it's loading, then we do want the spinner to be active. So that means now as we switch back and forth between the list page, we should see that overlay for just a second. And when all that content comes in from IronAgeX, it should hide itself. I'm going to go ahead and actually do the exact same thing for my post page. So I'll give it a loading property as well. It's Boolean. Defaults to false. And we want to notify true, so we can bind to it. And we will also bind it to the loading property of IronAgeX. And I can sort of duplicate that work that we did for list pages over in post page. At this point, you might be saying, these pages, sort of the signature of them is looking very, very similar in our markup. So it might be a good time to consider perhaps rolling some of this common behavior into behavior, I should say. So actually sharing that functionality between the elements instead of duplicating the code in both places. So that's something that we might do in a future episode just to kind of like tidy things up a bit. But for now, let's just verify that this works. So I'm going to switch back over to my browser. I will refresh the page, zoom out a little bit, because we're pretty zoomed in there. And what I can do is, because this content is going to load in really fast because I have it local, I'll go back to my network panel and I'll throttle the connection way down. So I'm going to set it to GPRS. And now when I click on film, I should see that loading state for just a second. Now you notice that my image still did that weird Swaperoo thing, but we're not seeing any stale text when we go and click on these items. One thing that does happen though when we switch between these is we can actually still scroll the page while that overlay is displayed. And that's kind of a bummer. We definitely don't want that. So I'm going to add one more little trick to blog pages. I'm going to add an observer for isLoading. So my observer is array. Let's get some more space down here. So I'll create an observer for, we'll say we're going to lock scroll whenever isLoading changes. And lock scroll will just be a method that I define where we say, all right, what is the state of isLoading? And if isLoading is true, then we're actually, we're going to cheat here, we'll reach outside of ourselves. We'll go to document.body and set the overflow style to hidden if isLoading is true. And what that's going to do is it's just going to like chop off the page and that way the user won't be able to scroll and see that content underneath there. Otherwise, if isLoading is false, then we'll set document.bodyStyleOverflow to visible, I think is the correct value. We'll double check. And then swap back over and bust out our dev tools so we can throw out all this thing again. So refresh the page. All right, so far so good. We'll go to our network panel, we'll set throttle lane to GPRS. And now we'll click on like the film section and you notice my scroll bar even like goes away. So I can tell I can't scroll or anything until that content actually has loaded in. Okay, cool. So we handled the issue of the text being stale and that loading in, but now we still have these images. And this is a really tricky problem because when our data loads, all it's loading is a path to a new image, but we still have to go make that HTTP request to fetch that content. And that could take a super long time to load, but I don't want my user to be waiting when they could be reading the text of the article while they still wait on that image to load. So we could kind of do a little trade-off there. We would give them the text of the article, but maybe we serve like a downgraded image. So something loads faster and then we wait and kind of upgrade that image as the nicer version loads in. So let me do that. And this is kind of a cool trick that I discovered recently by looking at a project the Polymer team did called Shop, which you can find over at shop.polymer-project.org. And if you go to the site, you'll notice that when we first boot up the page, it kind of does this like fade-in effect on this image. You see like a low res version, right? And then just kind of fades in. And what the Polymer team is actually doing is they're taking the original image and then they're downsizing it to 1%. So you get something that's like 200 bytes. And then in CSS scaling that back up to the full size of the image. And then we're loading the higher res version and we just crossfade them when the higher res version loads in. So this gives sort of a perceived performance improvement. The user can access our content a lot faster, but they're not waiting around on a super big image. So we can do that with our site. What I'm gonna do is over in Finder, I will find the blog that I've been working on here. Blog, vlog, okay images. And I've already gone ahead and down sampled these images, but I'll walk you through the process of doing it. So we'll take this photo of a lion that we've got. So we've got Photoshop here. We'll drop in this image of a lion. Now this is a really high res image. It's like 900 by 512, so pretty beefy. And I'm gonna go to the image panel property, whatever this thing is called, and set image size 2% and we'll set it to 1%. So that brings it down to nine by five pixels. And if we super zoom in, you can see this thing is just like, just a bunch of random squares now, but it roughly approximates our final image. And then we can export that for web. And I usually use like a medium quality setting. And I'm just gonna give it a different name. So I'll call it like picture one low res or something. Now the next thing I'm gonna do is take that low res image and base 64 and code it into a string. So that way I can load that string along with all of the text content for my article. Now there's a number of ways that you can base 64 and code an image. You can do it from the command line, I believe with the base 64 command in Unix. Or there's a bunch of websites out there where you just look up base 64 image and you can upload an image and it'll give you back a big string of text. And that's one technique that I used in this case because I'm lazy. So I've already gone ahead, I've base 64 encoded all these images. I have all the strings for them. And I'll go over to the data that I'm loading in my application, open up the list page. And along with the title and the slug and the image and the alt tag and everything, I've got this image placeholder value now. And inside of there, I just have this humongous base 64 encoded string. Well, it's not that humongous. It's like 200 or 300 bytes or something, which is really actually quite tiny. And this is what I'm gonna actually load into my application. Now I can't just use a regular image tag to load this thing. I need to use a special element. And the Polymer team has just such an element. So if I go to the Polymer catalog, let's see, Polymer iron image is the name. So we can check this out on the Polymer element catalog. This thing is awesome. And what it'll let us do is load a placeholder while it waits on the higher res version to come down. So I'm gonna just grab, let's see, there's a snippet of code here that I want. Here we go. So I'm gonna grab the snippet of code and I can go back to my list page and find this image tag that I was using previously. And I'm just gonna replace it with an iron image. So let's see. So we'll set width to 900 pixels, height 512. You could also do this in CSS if you wanted to have like media query breakpoints to change the size of the image. I'm working quick and dirty here, so I'll just do that inline. For the placeholder, right? If you go back and you look at our data, we called that value image placeholder. So I'll grab that. We can use that in our binding, right? So image or item, because we're in a DOM repeat, item image placeholder. Size and cover, yep, that looks good. I totally wanna do that. Preload. There is a fade effect that iron image gives us. If we go and look at their docs, this is kind of a nice thing. So there's a fade attribute we can set on this guy. So I'll say preload fade. The source is gonna be item.image. And then we can add an alt attribute too, which is important for accessibility. So we'll say alt equals, I believe it is item.image underscore alt. Okay. So this is gonna go out. It's going to quickly display a placeholder and then fetch the higher res version and fade that up when it is loaded. I'm also gonna add the same chunk of code over to our, what is it, our post page. So our post page, we got an image here, right. Replace that with iron images. And here we called it post content. So I just need to update, you know, wherever it says item post content. Hide that old image. Okay, let's give it a shot. So I've turned off throttling. I'm going to refresh the page. And you'll actually even see, even though we're on a fast connection, we'll actually see some of that crossfade happening because it's able to load that placeholder super, super, super fast because it's so tiny. But this makes a huge difference if you're on a slower connection. So again, we'll go to the network. Let's turn throttling on now. So we'll set it to like regular 3G, okay. And now let's switch to a different page. So we'll go from art to film. Okay, cool. So we didn't see any stale images and we were able to get that kind of nice fade-in effect while we were waiting on these other images to load. I mean, if we go to a really slow connection like GPRS here, what you'll see is as I go and maybe click on one of these posts, we see the spinner for just a second. Then we see the page content though and then that image fades up. And this is really, really nice. Let's actually do like a super hard refresh to clear our cache. You can really see this in action. Okay, so let's say I hit this page for the very first time. I'm gonna switch it to GPRS. Now I'm like super, super, super slow phone. I'm gonna switch to the film section and my text loads in super quick, right? And these images, they're kind of like rolling in along after it. But I don't have to wait for those images to be able to actually start reading the page and interacting with the page content. So the final product is just super, super nice and it's very, very responsive and very friendly to folks who might be on slower cell connections. Okay, so that about covers it for today. We've built an amazing site that is super quick on mobile using some of the fancier new app routing and iron image trickery that the Polymer team has given us. Now if you haven't done so, please go check out some of the talks that the Polymer team recorded at IO. These are all up and available on the Chrome Developers YouTube channel. And if you have any questions for me, you can leave them in the comments down below or you can always hit me up on a social network of your choosing at hashtag ask polymer. As always, thank you so much for watching and I'll see you next time.