Lazy loading data with app-route -- Polycasts #47
Skills:
Frontend Performance90%
Key Takeaways
Implementing lazy loading data with app-route
Full Transcript
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 a Prout so we're gonna picking up where we left off the last time this time they will be using a Prout to continue working on our blog and what we're gonna 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 2 to grok what I'm talking about here let's switch over to the laptop and you'll see that I've got the the blog as we left it last time showing here and I'm going to just go over to the 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 you the network tab I will go over to right over here which is 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 when these posts and I go back to the art section and you just see how there was kind of like a like a moment where we saw a flash of the old film section when we switch 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 they're seeing is kind of the the relevant page and something that's really fresh and up-to-date so to do that we're gonna switch over to our code editor and this is where we we left the project last time and I've already gone ahead and renamed and 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 a pro out 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 selector menu in the previous episode as passing category data as this two-way binding like this and while this you know is is cool and it this this 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 / films / list and I say okay cool well I'll update it too / films / 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're just looking at the site but if you hit the back button they 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 you know 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 is nice one way loop and that solves that but now the next thing we want to do is we want to tackle that funky weird flash of unstyled 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 gonna 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 you know what to do so we don't display kind like stale or outdated text and my thinking here is I'm probably gonna display like an overlay over the screen with like a little spinner so that way you know the user doesn't see like a weird swapper rule with our headings they just see a spinner page and then when that contents 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 gonna go ahead and drop in a div I'm gonna call this overlay and inside of here I will drop in a paper spinner and I'll just leave it with this this active attribute and I need to go up to the top and make sure that I have imported paper spinner okay 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 fullscreen so 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 gonna boost this up a little bit so you can read it a bit easier okay so here I'm positioning the overlay so it's absolute top left right and bottom are all 0 so it's actually gonna stretch to fill the entire screen I'm saying it to you 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 now 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 alright 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 the the page gets swapped to by our route but it could still be in a loading state then so we'll add a loading property this is also gonna be a boolean the values going to default to false and I'm gonna start notify true because I'm gonna need to have the outside world listen to this as well so next I'll go up to my iron Ajax 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 iron Ajax has a loading property so here I can just bind my loading property to its loading property right 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 iron-ajax is loading so back in blog pages which is sort of a common parent of all these guys I will add a property or an attribute here so I'll listen for the steeds loading property and I'm gonna 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 gonna do is I'm gonna bind the state of the overlay to that loading property so we'll say okay we'll use the HTML hidden attribute I use a 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 okay so when is loading is false hide the overlay when we are not loading hide the overlay okay this is one of those like things where you got to think about it for a second and then the active state of our spinner we're actually gonna do the reverse we're gonna say okay well if it's loading then we do want the spinner to be active okay so that means now as we switch back and forth between the list page we should see that that overlay for just a second and when all that content comes in from iron-ajax it should hide itself I'm gonna go ahead and then and actually do the exact same thing for my post page so I'll give it a loading property as well all right it's boolean defaults to false and we want to notify true so I can bind to it and we will also bind it to the loading property of iron Ajax and I can sort of duplicate that work that we did for list pages over in post page at this point you know you might be saying these pages the 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 episodes to kind of like tidy things up a bit but for now let's just verify that this works so I'm gonna switch back over to my browser I will refresh the page zoom out a little bit we're pretty zoomed in there and what I can do is because this contents gonna 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 gonna 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 swap a roo 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 gonna add one more little trick to blog pages I'm gonna add an observer for is loading so my observers array got some more space down here so I'll create an observer for we'll say we're gonna lock scroll whenever is loading changes and lock scroll will just be a method that I define where we say all right what is the state of is loading and if is loading is true then we're actually we're gonna cheat here we'll reach outside of ourselves we'll go to document about body and set the overflow style to hidden if it's loading is true and what that's going to do is that's just gonna like chop off the page and that way the user won't be able to scroll and see that content underneath there otherwise if is loading is false then we'll set document body style overflow to you mm well I think is the correct value let's swap back over and bust out our dev tools so we can throttle this thing again so refresh the page all right so far so good we'll go to our network panel we'll set throttle linkage GPRS and now we'll click on like the film section 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 too low but I don't want my user to you know 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 the article but maybe we serve like a like a downgraded image so something lives 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 poorer team did called shop which you can find over at shop.com are - project.org 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 little 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 one percent 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 then so this gives sort of a perceived performance improvement these are 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 and downsampled 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 got Photoshop here well drop in this image of a lion now this is a really high res image it's like 900 by 512 so so pretty beefy and I'm gonna go to the image panel property whatever this thing is called and set image size to percent and we'll set it to one percent so that brings it down to 9 by 5 pixels and if we eat super zoom in you can see this thing it's just like just a bunch of random squares now but it roughly approximates our final image and then they can export that for web and I usually use like a like a medium quality setting and I'm just going to 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 base64 encode 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 base64 encode an image you can do it from the command line I believe with the base64 command in UNIX or there's there's a bunch of websites out there where you just look up base64 image and you can upload an image and I'll give you back a big string of text and that's that's one technique that I used in this case because I'm lazy so I've already gone ahead a base64 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 humungous base64 encoded string let's not vacuum I guess it's like 200 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 a special element and the pollen 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 I'll let us do is load a placeholder while it waits on the high-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 I'm just going to 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 50 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 it in line for the placeholder right if you if you go back and you look at our data we called that value image placeholder so I'll grab that I can use that in our binding all right image or item because we're Nodame repeat item image placeholder sizing cover yep that looks good I totally want to do that preload there is a fade effect that iron image gives us if we go and look at their docks this is kind of a nice thing so there's a fade attribute we can set on this guy so I'll set a 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 it fault equals I believe it is item dot 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 place 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 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 cuz it's so tiny but this makes a huge difference if you're on a slower connection so again I'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 go from art to film okay cool so we didn't see any stale images and we 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 our like a super hard refresh to clear our cache so 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 and now I'm like super super super slow phone I 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 at the Balmer team recorded at i/o 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
Original Description
Lazy loading data and managing flash of unstyled content (FOUC) can be pretty tricky in a single page app. In today's episode I'm going to tackle both of these topics. We'll add a loading screen to our app that uses a spinner to indicate we're waiting on our text content, then we'll use a technique popularized by Medium where we base64 encode a low res version of our images (so we can display them quickly) and then transition to the higher res version once it's had time to download.
Demo source:
https://goo.gl/iEQs0J
Shop demo:
https://goo.gl/oX9QEc
app-route docs:
https://goo.gl/6KzFYk
Polymer Talks from Google I/O:
https://goo.gl/T2K7XI
Polymer Slack:
http://goo.gl/9UI2Uu
Subscribe to the Chrome Developers channel at http://goo.gl/LLLNvf
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Chrome for Developers · Chrome for Developers · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Polymer Performance Patterns (The Polymer Summit 2015)
Chrome for Developers
Polymer Power Tools (The Polymer Summit 2015)
Chrome for Developers
Chrome Dev Summit 2014 – Chrome Case Studies
Chrome for Developers
Web Directions Code 2015 round up
Chrome for Developers
Maintainable Code - HTTP203
Chrome for Developers
iron-ajax… wat?! -- Polycasts #26
Chrome for Developers
The Guardian - Supercharged
Chrome for Developers
ES2015 (next version of JavaScript), Totally Tooling Tips (S2 Ep1)
Chrome for Developers
#AskPolymer: Rob answers all the questions ever -- Polycasts #27
Chrome for Developers
The Future of JavaScript - HTTP203
Chrome for Developers
Data Binding 101 -- Polycasts #28
Chrome for Developers
The Guardian part 2 - Supercharged
Chrome for Developers
The Future of Web Audio: with Chris Wilson and Chris Lowis
Chrome for Developers
Chrome 46: New motion-path animations, client hints and service worker improvements
Chrome for Developers
Sublime Snippets, Totally Tooling Tips (S2 Ep2)
Chrome for Developers
#AskPolymer: How do you make the show? -- Polycasts #29
Chrome for Developers
Critical Path CSS, Totally Tooling Tips (S2 Mini Tip #1)
Chrome for Developers
Binding to Objects -- Polycasts #30
Chrome for Developers
Player FM - Supercharged
Chrome for Developers
Where’s the Designer? #AskPolymer -- Polycasts #31
Chrome for Developers
Jake Beats Wikipedia - HTTP203
Chrome for Developers
Supercharged Observers! -- Polycasts #32
Chrome for Developers
Jai's Web blog - Supercharged
Chrome for Developers
Windows Command-line Tooling, Totally Tooling Tips (S2, Ep4)
Chrome for Developers
What about internationalization? #AskPolymer -- Polycasts #33
Chrome for Developers
Developing for Billions (Chrome Dev Summit 2015)
Chrome for Developers
Google+ Performance Improvement Comparison
Chrome for Developers
Deploying HTTPS: The Green Lock and Beyond (Chrome Dev Summit 2015)
Chrome for Developers
Progressive Web Apps (Chrome Dev Summit 2015)
Chrome for Developers
Instant Loading with Service Workers (Chrome Dev Summit 2015)
Chrome for Developers
Increase Engagement with Web Push Notifications (Chrome Dev Summit 2015)
Chrome for Developers
Engaging with the Real World: Web Bluetooth and Physical Web (Chrome Dev Summit 2015)
Chrome for Developers
Asking for Permission: respectful, opinionated UI (Chrome Dev Summit 2015)
Chrome for Developers
Polymer - State of the Union (Chrome Dev Summit 2015)
Chrome for Developers
Building Progressive Web Apps with Polymer (Chrome Dev Summit 2015)
Chrome for Developers
Introduction to RAIL (Chrome Dev Summit 2015)
Chrome for Developers
DevTools in 2015: Authoring to the max (Chrome Dev Summit 2015)
Chrome for Developers
RAIL in the real world (Chrome Dev Summit 2015)
Chrome for Developers
#ChromeDevSummit talks are up - W00T! -- Polycast #34
Chrome for Developers
V8 Performance from the Driver's Seat (Chrome Dev Summit 2015)
Chrome for Developers
Quantify and improve real-world RAIL (Chrome Dev Summit 2015)
Chrome for Developers
Owning your performance: RAIL (Chrome Dev Summit 2015)
Chrome for Developers
HTTP/2 101 (Chrome Dev Summit 2015)
Chrome for Developers
Leadership Panel (Chrome Dev Summit 2015)
Chrome for Developers
Build Processes, Totally Tooling Tips (S2, Ep 5)
Chrome for Developers
Accessibility (Chrome Dev Summit 2015)
Chrome for Developers
Binding to Arrays -- Polycasts #35
Chrome for Developers
HTTP2 - HTTP203
Chrome for Developers
Chrome 47: Splash Screens, requestIdleCallback and better desktop notifications (New in Chrome)
Chrome for Developers
Call For Submissions - Supercharged
Chrome for Developers
Cross Device Testing, Totally Tooling Tips (S2 Ep6)
Chrome for Developers
Testing AJAX with Web Component Tester -- Polycasts #37
Chrome for Developers
Slack: Extended Xmas Special - Supercharged
Chrome for Developers
Browser testing with Travis & Sauce Labs -- Polycasts #38
Chrome for Developers
Optimize for production with Vulcanize -- Polycasts #39
Chrome for Developers
Highlights from Chrome Dev Summit 2015
Chrome for Developers
Chrome 48: Custom buttons in notifications, DevTools Security panel, and Presentation mode
Chrome for Developers
Crisper: Protecting your Polymer app with CSP -- Polycasts #40
Chrome for Developers
How do I use Sass with Polymer? #AskPolymer -- Polycasts #41
Chrome for Developers
Colors – DevTools Tonight #0 (Pilot)
Chrome for Developers
More on: Frontend Performance
View skill →
🎓
Tutor Explanation
DeepCamp AI