Placeholder Image

Subtitles section Play video

  • >>Steve Souders: Okay. Is that my cue to go? Okay. We're having a current discussion about

  • letting people come in and sit up front, so I hope we can do that.

  • I'm really excited to see everyone that showed up, but I have a cold shower announcement

  • to make. I'm not giving anything away. So although that's not entirely true. I'm

  • giving away information and knowledge, but nothing that physically you can take home

  • and give to your kids if that's what they're expecting.

  • So I'm going to talk about HTML5 from a performance perspective, but first I'm going to start

  • off and give a little background on my work in working on Web performance and kind of

  • the motivation. I think probably a lot of people -- how many people here build Web sites?

  • Yeah, okay, great. So I think there's something in the DNA of

  • engineers in general, and especially programmers, to be efficient and optimize.

  • I think as developers we all like our code -- we feel proud if people -- if we can say

  • about our code that it's really fast and efficient. And so at the beginning I'm going to talk

  • about how we can try to work to instill that interest and buy-in for performance across

  • other parts of the organization outside of engineering.

  • So there will be a little preamble on that and then we'll dive into the HTML5 stuff.

  • I just want to mention the slides are up on my Web site, stevesouders.com. If you go there

  • there's a link to it. You can check that out. Okay. So let's get started -- oh, the other

  • thing I want to mention is really more than what I say and more than the words on the

  • slides, I really want people to pay attention to the photos in the background of the slides.

  • [ Laughter ] >>Steve Souders: Come on, we're going to -- loosen

  • up a little bit. Let's go. I mean, like the story of my life, like I

  • take slow things and make them fast, like is that very appropriate or what?

  • I need more feedback. [ Applause ]

  • >>Steve Souders: Yeah, okay, there we go. I worked at Yahoo for a long time, eight years.

  • I was going to be there one year and I was there eight years. And about four and a half

  • years ago I joined Google, which was really my goal when I first started on Web performance

  • because I knew the people at Google really cared about making things fast, and it's true.

  • So I've been there four and a half years. I do mostly open source stuff, so I did -- I

  • created YSlow, Cuzillion, Sprite Me, Hammerhead, Browserscope. Lindsey Simon now runs that

  • project, very successful project. Jdrop, which is a great concept, but not such a successful

  • project, but you should check it out. HTTP Archive, another one I don't have time to

  • talk about today, but check it out, HTTParchive.org. I wrote "High Performance Web sites," "Even

  • Faster Web sites." I taught at Stanford based on the books and

  • I run the velocity conference. Oh, I have to update. We just had it this week in fact.

  • I just finished that on Wednesday. So I've been doing this performance stuff

  • for quite a listening time now, seven years, I think, but when I started back in 2004 I

  • kind of felt like the lone voice in the woods. So really I'm sure there were people that

  • were working on it back then, but when I searched for information about making Web sites faster,

  • I really didn't find very much. There was a great blog post from David Hyatt that actually

  • really opened my eyes to where I should look for making Web sites faster.

  • I should mention that when I talk about performance, I mean that from the end user's perspective.

  • My goal when I started this in 2004 was to make the user experience fast.

  • Now, there's another aspect of performance which I think of more as efficiency or scalability

  • on back end servers. How can we handle 10X the current number of users with the same

  • hardware? Those kinds of efficiency optimizations are also performance, but when I say performance,

  • I really mean speed, speed of the user experience. So when I first started working on this there

  • really wasn't that much information out there and I would try to go -- I started documenting

  • things, writing books, blogging, trying to go to other teams and convince them to focus

  • on performance. And it's kind of like QA or writing unit tests.

  • Like try to sell unit tests -- time to build unit tests to someone from marketing or sales.

  • That's kind of hard to do, because it's hard to visually see the benefit of that.

  • So at the beginning it was kind of the same thing with talking about make the Web site

  • faster. Yeah, we need like a couple of people to work for at least six months. And you won't

  • see anything different on the site, it will just feel faster. And believe me, that's really

  • critical. And they're like no, really we want you to

  • add more flash. [Laughter].

  • >>Steve Souders: And so fast forward to 2010, future of Web apps. We have Fred Wilson. How

  • many people know Fred Wilson? Like one of the most prolific bloggers. He's

  • the number one VC out of New York City, out of Union Square, very techy guy. But really

  • his business is investment, funding startup companies.

  • Here he is speaking at a tech conference about his 10 golden principles of successful Web

  • apps. What's number one? Speed. He says, First and foremost we believe that speed is more

  • than a feature, speed is the most important feature.

  • And he goes on to talk about with their portfolio companies they track all of the company's

  • performance, speed, page load time for real users. And that in their experience the data

  • shows that when the speed drops off, the success of the business drops off.

  • And that's why they do this for all the portfolio companies that they work with.

  • And so I think that's to me like Web performance has arrived. We have a VC talking at a tech

  • conference about speed, like this was beautiful to me. I start almost every slide deck with

  • this slide. And actually, a partner of Fred's spoke at

  • the Velocity conference this week. And in addition -- if that's not enough to

  • have the number one VC out of New York City talking about performance, I'm going to run

  • through a bunch of case studies here that correlate performance speed to the success

  • of the business. So here's -- about two years ago Bing and

  • Google Search got up on stage at the same time and talked about experiments they had

  • run. Bing introduced intentionally a delay in serving search results. They took it up

  • to two seconds. At a two-second delay they saw all their goodness metrics drop off. Most

  • significantly revenue per user dropped off four percent.

  • And of course, these companies are doing this on a very small sample size.

  • So Google took this up to 400 milliseconds at the max. Didn't see that much dropoff in

  • searches per user, although at Google scale that's a fairly significant dropoff.

  • The thing that was really interesting about this study was after they removed the delay,

  • they kept that user group segmented and tracked their usage. And it took I think six weeks

  • for the usage, the searches per day, and other goodness metrics, to resume where they were

  • before the experiment started. So the user's awareness of what the experience

  • is like is something that gets ingrained and lives with them and it takes a long time to

  • build that and to recover from delays. So it's important to stay on top of keeping your

  • Web site fast. And Yahoo ran a similar study. And for full

  • page traffic, that means traffic where the onload event actually fires, a 400-millisecond

  • delay saw a five to nine percent dropoff in traffic.

  • Here Mozilla -- this is about a year old. Mozilla, when you want to upgrade to Firefox

  • and you're in Internet Explorer, you get the IE landing page, and they made that IE Firefox

  • landing page 2.2 seconds faster, and they saw a 15% lift in Firefox downloads. So for

  • them that's their business metric, being a nonprofit.

  • And this was a seminal study from Velocity a few years ago. Shopzilla did a tremendous

  • performance effort, taking their site from seven seconds to about three seconds, and

  • they saw conversion rate go up seven to 12 percent depending on the country.

  • This is very significant. They saw the unique users from search engine marketing more than

  • double. And this was the first study that showed another benefit in addition to the

  • business metrics is operating costs going down.

  • So here we have the number of servers needed to run the Web site after this optimization

  • dropped. And that kind of makes sense because like one of the optimizations is connecting

  • scripts together, so instead of making seven requests to my server, I'm only making one.

  • Turn on Gzip so the amount of time it takes for the response to get off the server box

  • is lowered and so the server can handle a higher QPS.

  • And then following that a good friend of mine, Bill Scott, when he was at Netflix, they had

  • -- they didn't have Gzip turned on for some reason. I can go into it after if people want

  • to ask. And he turned it on one day and the [Indiscernible]

  • said the Web site is down, all we're serving is the error page.

  • And he said why do you think that? And they said the traffic in our data server

  • has dropped in half. He said, Nope, we're serving everything, it's

  • just that we turned on Gzip. So this is probably six figures a month in a data center that

  • they saved. Pretty significant. Here's another example, Edmunds.com turned

  • on -- added an expires header so that their resources through their CDN could be cached

  • and they saw their CDN traffic drop by a third. So again, this is a six-figure maybe high

  • five-figure savings per month from CDN costs. And then not that recently anymore, this was

  • about a year and a half ago, Google announced that speed or latency was going to be taken

  • into consideration for page rank. And that was caveated, it's one of two hundred signals,

  • it only effects about one percent of search results, but still it's a consideration and

  • page rank is really important. All of these things about a year, year and

  • a half ago I saw coming together and so I coined a new catch phrase for this emerging

  • industry called WPO. It stands for Web Performance Optimization. And actually as I mentioned,

  • I keep mentioning, we just had Velocity this week, there were a number. Sequoia, Battery

  • Ventures, Excel, Union Square were all there. This industry is really growing up. There's

  • a number of startups in this Web performance space now.

  • And the elevator pitch is it drives traffic to your site. We see that with search engine

  • marketing, with page rank. It improves the user experience. You would think that making

  • Web sites faster the user would get in and out more quickly, and it's just the opposite.

  • All of these studies show that page views per session, session length all increase because

  • the users are having a better experience. It increases revenue. We saw stats on that

  • with conversions, downloads, and it reduces operating costs.

  • So this all sounds pretty good, right? Web PO is really taking off.

  • All right, that's the preamble. How many people here think fast Web sites are good?

  • All right. So hopefully if you're having trouble selling that -- if this is stuff that you

  • want to work on and you're having trouble selling that back home, you can take some

  • of these case studies and show people back home that this is a good investment. You'll

  • actually get a positive ROI. And maybe these will give a little guidance on what you can

  • track on the business side to actually correlate performance improvements with the goals of

  • the business. All right. So let's transition into the meat

  • of the topic. I don't want to debate about what HTML5 is. There's the spec. I also mean

  • CSS3. It's the new stuff. So I'm going to highlight a few things around

  • HTML5 and CSS3 that I think are really important to pay attention to from a performance perspective.

  • So the first is if you want to optimize something you need to be able to measure it. And right

  • now what we'd really like to measure is the user's perception of speed. Currently there's

  • no JavaScript handler for brain activity. So what we've been using as an industry -- as

  • a proxy for that is the window onload event. Now, the problem with that is, for example,

  • if I do a Google search and I click on a search result that takes me to Whole Foods, and I

  • want to measure -- from Whole Foods' perspective, they want to know how long it took for the

  • user to click that link to when Whole Foods was ready. And the problem is tracking the

  • start time. How do you track the time that the user started by clicking on that link?

  • Because that's the user's perception time. And what you can do is at the top of the Whole

  • Foods page you can put a script lock that takes a time measurement, but that totally

  • ignores the time it takes for the request to go up to the Whole Foods server, for it

  • to stitch together all of the content and send that back down to the browser.

  • So about two years ago Google and Microsoft formed this Web performance working group

  • as part of the W3C, and the first task was to create the Web timing spec, which is actually

  • three specs, navigation timing, user timing, resource timing.

  • How many people here use navigation timing to measure Web sites?

  • Good. It's not good that there were so few hands up. It's good because I'm going to talk

  • about it a little bit. So those of three and I'm going to talk about

  • each one in a little bit more detail. They're also working on a few other specs, page visibility

  • I'll touch on quickly. Script-base animations I'm not going to spend too much time on, but

  • people are doing a lot of animation with JavaScript and they're working on making that better.

  • And efficient script yielding, since the browsers are single threaded, if you have long running

  • JavaScript it can really degrade the user experience. So what can scripts do to mitigate

  • that. But let me talk about the timing specs. So

  • navigation timing actually is out. The spec is done and it's available today. If you look

  • at window.performance, there's this timing object. And you can do things like from the

  • timing object you can get the navigation start and the load event end, take the difference.

  • And the nice thing is that the Web timing spec gives us two main things. This is the

  • first one. This is the time at which the -- the epic time at which the user clicked on that

  • link on Google. So now the user can -- the Web site owner can get the full time from

  • when the click happened to when the onload event or whatever event you wanted to. And

  • in fact if you put a little time stamp at the top of the page you can break that into

  • what I call the back end time, the time from the click to when the first byte arrived and

  • the time from the first byte to when the full page loaded.

  • And there's a bunch of other timings in there. You can get DNS time and connection time.

  • There are a bunch of time values that you can get in there.

  • So this has been out -- the spec was finished probably about six months ago, maybe a little

  • longer. And I think IE 9 -- no, I think Chrome was

  • the first to implement it. But it's in IE 9 and up, Firefox 7 and up. They had some

  • bugs in the Firefox 7 in the early days, but those are all fixed now. It's on Android.

  • And I heard a month ago it's on Blackberry, but I haven't tested that.

  • And here's a good URL from Tony Gentilcore that kind of explains how you could use it

  • and some examples of getting different time values.

  • So one thing that's really cool is Google is taking -- for page rank is taking time

  • into consideration, but when they announce that -- I'm really proud of the work from

  • the make the Web faster team at Google, where it wasn't like okay, we're going to hold you

  • responsible for it, good luck. We also rolled out several tools.

  • In Webmaster tools you can go in there and you can see how your site compares its speed,

  • compares to the rest of the industry. And really the folks who were going to get

  • penalized from a page rank perspective are going to be in the lower 10%, maybe even lower

  • than that. So maybe you're not awesome, but if you're in the top 50% you probably don't

  • have too much to worry about there. So that's a little help, but the other thing that's

  • nice to get more granularity, if you use Google analytics, we added this time measurement

  • capability in Google Analytics. I think we call it site speed -- yeah, site speed.

  • Yeah, this screen dump is a little old. I think the UI is a little difference now. But

  • the nice thing is when we first launched it you had to add a little bit more to your Google

  • Analytics snippet, and then about three or four months ago we turned it on for everyone.

  • So even if you had no awareness of the site speed, time measurement capability, you've

  • been gathering data for about five months now, four or five months. So you could go

  • to Google Analytics and go and find this site speed tab and you could get charts, and it's

  • the usual Google Analytics slice and dice capabilities by browser, by geographic region,

  • by page, and you can see what your performance is.

  • This is my Web site, so I don't know what was going on there, but that was awhile ago.

  • See, now it's fast. Well, in November it was fast.

  • Thank you for that. I appreciate that. [ Laughter ]

  • >>Steve Souders: Oh, I think I probably -- now it's on by default. Oh, it's only in browsers

  • that support nav timing, so we really need mobile browsers to start supporting this more.

  • Oh, it's sampled. So by default it's a one percent sampling rate.

  • If you have a huge Web site, like one percent is probably fine. And the guys have done a

  • really smart thing. Like they don't start it at midnight and if you're a huge Web site

  • you've used your one percent by 12:15. They, like, dole it out throughout the day. But

  • if you're a smaller Web site, you can change it with some Google Analytics commands to

  • cover 100% of your Web site, but it's limited, I think, to 10,000 measurements a day. But

  • again, those will be sampled throughout the day, so you won't get biases based on peak

  • time and stuff like that. And then I'm just going to talk really quick

  • about the other two parts of the timing spec. There's resource timing. And this is -- there's

  • drafts of this available, but this hasn't been nailed down. I don't think there's any

  • browser that supports it yet because the draft is -- the spec is still being defined.

  • But this -- if you think about it, navigation timing is basically this same information,

  • but it's at the page level. It's really high. And what we're doing with resource timing

  • is we're bringing that down to every HTTP request in the page. So for every HTTP request

  • in the page you can get DNS lookup time, connection time, total time for that to come back. This

  • is going to be a great mechanism for if you're using a CDN to track how your CDN -- or maybe

  • you're testing out multiple CDN's, to see how their performance is going.

  • It does have to worry about security safeguards. So you could have some kind of hack where,

  • you know, on my Web site I have the logo from some nefarious Web site. And when you land

  • on my Web site I can actually see what the DNS time is. And if the DNS time is zero,

  • I know that you've been to this other Web site. So there are some security safeguards

  • with HTTP headers. Web sites can allow or not allow cross-domain tracking of resource

  • timing. And then there's also user timing, which is

  • really important for people building Web2O apps, AJAXy stuff. Something like Gmail that

  • is open for several hours, there's no concept of a page load time. There's only one of those

  • when you start it up. So this is, if you're doing HXE stuff like

  • compose, this will give you commands that you can use to say the user is about to do

  • a compose operation, let me -- let me mark a start time and then when the compose is

  • all done, you can mark an end time, you can give it a label, and so it lets you define

  • and track any timing episodes that you care about in the Web apps that you are building.

  • So it basically is like nav timing but it's much more flexible and lets you define the

  • start and stop times whenever you want in your code.

  • The other one that I mentioned that they are working on is page visibility. This one is

  • important from a performance perspective. Mostly from a -- from an altruistic perspective,

  • but it could also affect, you know, what you are doing on your Web site. And so basically

  • what the spec let's you do is detect when your page is visible. So like one thing I

  • do in the morning when I come in, since I can't stand to wait for Web sites to load,

  • is I have this script and I -- you know, I boot up my machine, I load the script, it

  • loads my 30 Web sites that I read every morning and then I go get breakfast and when I come

  • back, all of the pages are loaded and I can just go through all of the tabs. But only

  • the top tab is visible. And inevitably when I come back, if I left my sound on, my office

  • manager, you know, giving me a dirty look, because there's some hidden tab that's playing

  • video. And the sound -- or maybe multiple tabs that are playing video and the sound

  • is just annoying and it's like really? Like you started the video, even though like the

  • tab is not even visible? Like why did you do that?

  • And the page visibility API introduces a way to detect whether or not the tab of the window

  • is visible. And so this is also really important, like,

  • if you are tracking metrics, like page impressions. If the user opened the tab but they're never

  • going to go to it, but you counted it as an impression, that's a miscount. Same thing

  • with ads. Again, the example of video. You might be doing something like showing them,

  • you know, stock updates or the latest messages from friends or you might be rotating through

  • a carousel of photos and they're not looking at it. So not only are you kind of -- like

  • you might rotate through a carousel of photos that started with their favorite photo, but

  • by the time they opened the tab they are down to their 5757th favorite photo and you have

  • kind of ruined the experience for yourself. So you could use it there.

  • Um, the other thing that you can do is -- this API can be used for pre-fetching resources.

  • So the Web site owner can decide and -- the Web site owner can decide if they want to

  • pre-fetch resources maybe for the next page and also if the page should be prerendered.

  • This is something that Chrome does. So Chrome can actually prerender a page in the background.

  • But one of the problems with doing that is, again, if there are ad impression counts or

  • page impression counts that are firing, and the page is being rendered in the background,

  • and the user actually never sees it, that's a miscount. So the page visibility API gives

  • people controlling those metrics the ability to only fire the metrics when it makes sense.

  • And I think this is only in Chrome right now. But what it looks like is you can say WebKit

  • hidden is the property, you can look at to see whether or not the tab is hidden and this

  • is an event handler you can attach to to detect when the page does become visible.

  • So we had script defer in IE for years, but now with HTML5 the async and defer attributes

  • are officially supported across almost every browser out there. I'm not going to go into

  • it here but in fact I've talked for years and written extensively about the impact that

  • scripts have on the user experience. So I mentioned earlier how the UI thread,

  • you know, the UI is single threaded, the browser is single threaded, so if you have JavaScript,

  • for example, that takes three seconds to execute, the user is clicking in the browser and they

  • are trying to scroll the window and nothing is happening because the JavaScript is blocking

  • any of that interaction. And so -- so that also happens when the script is being downloaded.

  • So if you have a 500 k JavaScript payload and the user has a slow connection, again,

  • it can take seconds for that to download. While that's downloading, the UI could be

  • blocked. Unless you can do your script loading asynchronously. So if you just do scriptsource

  • equals main.js it's going to stop the HTML parser from parsing past that script tag and

  • it's also going to block rendering. No browser in the world will render anything below a

  • script tag until that script is downloaded and parsed and executed. But you can use the

  • async attribute which tells the browser to start the download but to go ahead and continue

  • parsing the HTML and rendering the DOM elements in the page. So it gives the user feedback.

  • It's a better user experience. The user can see the page rendering, especially because

  • a lot of times we put scripts in the heads of our pages, which means the entire body

  • is blocked from rendering until all of those scripts are downloaded, parsed and executed.

  • And so this tells the browser, download it in the background, continue parsing; and as

  • soon as the script arrives, parse and execute it.

  • So one -- two tricky things about this is you can't have any document.write in this

  • JavaScript code because parser is already past that point. You are going to get very

  • bad and varied results across browsers if you do document.write in an async script.

  • The other challenge with async is suppose that I have three scripts, A, B, C, C depends

  • on B, B depends on A. But A is probably like jQuery, so might be my biggest script. C might

  • be really tiny, so if I load all of these async, which is the one that's going to come

  • back first? C. If I loaded async, it's going to be parsed and executed as soon as it comes

  • back and it's going to get undefined symbol errors because B might not be back and A might

  • not be back. You can't just willy-nilly add an async attribute to all of your script tags.

  • But what you can do is you can use defer. If it's JavaScript that isn't critical for

  • rendering content to the page, and doesn't have document.write can add the defer attribute.

  • It's pretty similar. It says download it in the background, let the parser continue parsing

  • and rendering DOM elements. After the entire page is done, parse and execute these deferred

  • scripts and do it in the order that they were listed in the page. And so if you have those

  • interdependencies across scripts, defer is a good fallback.

  • But -- but this still doesn't give all of the control that I think is really needed

  • to build a good user experience for -- for Web apps, especially on mobile.

  • For example, one thing that I would like to do is I would like to download maybe a big

  • script, 100 k, 300 k, 500 k, but not parse and execute it. It might be a script for something

  • like popping up a div to compose a message or address book stuff that is only needed

  • if the user starts typing an email message. But if I download that, as soon as it hits

  • the browser, the parse and execute is going to happen and it's going to lock up the UI.

  • So I really want to get this JavaScript down to the device, get it in cache, but parse

  • and execute it, depending on what the user does.

  • The other thing that I would like to have is a control over when the download happens.

  • Right now the spec doesn't say when browser should download the script. But if I've said

  • defer, if I've said async, certainly if I've said defer, I would like you to do this download,

  • after everything more important is already done, because there's a limited number of

  • TCP connections that the browser will make, and if you download scripts or multiple scripts,

  • then things like the background image of the page, the logo at the top of the page, might

  • actually be pushed out because you are already using the six TCP connections that most browsers

  • allocate to a domain. So we don't have control over those in markup,

  • but there are techniques that you can use to get that behavior. So this is one that

  • Gmail wrote about quite a while ago. Gmail mobile team. And it's a hack. I think it's

  • a beautiful hack. So what they did was in the page, they have

  • -- you know, maybe 300 k of JavaScript. I'm just making these numbers up. I don't know

  • how much JavaScript Gmail has. It's probably more than that. But they have a lot of JavaScript

  • in here and they just wrap it in -- in comment delimiters. So what happens is this will get

  • downloaded to the browser, it will be cached, it's already resident. But it's not parsed

  • and executed. So -- so let's say this is compose a new message JavaScript. It pops up in div,

  • it formats everything, it does error detection and things like that. So we don't really need

  • this JavaScript to block the UI thread for parse and execution until the user actually

  • clicks on the compose button, which they may never do during this session. So what we do

  • is we download the code because we want it on the device. When they click compose, especially

  • on a phone, we don't want to wait to download 300 k of JavaScript, we don't want to make

  • the user wait. So what we do is we download it, you can even download it in the background.

  • It's not going to block the UI thread when it arrives. Now the user clicks compose, you

  • have all of the JavaScript on the client and now you just find the DOM element for the

  • script tag, remove the comment delimiters and eval the code. A lot of people say eval

  • is evil. Doug Crawford is here today, I saw him downstairs, he'll tell you that. Certainly

  • eval is evil from a security perspective. If you are eval'ing code that you didn't generate,

  • that can produce really bad things. You wouldn't want to do this with third party widgets and

  • ads, et cetera. So this is code that you control, that you generated. So from a security perspective,

  • it's okay and the actual performance of eval is less than 10% worse than just a script

  • block. So from a performance perspective, it's actually down like around one or two

  • percent. From a performance perspective, it's fine. So you control the code, performance-wise

  • it's good. So this is a -- this is a really nice hack.

  • And it's perfect for pre-fetching JavaScript that you might need but you are not sure.

  • It's possible that you will never need it. So don't block the UI thread, especially for

  • large amounts of JavaScript. You know, this -- might require a fair amount

  • of rewriting on your Web site. So I wrote something called ControlJS, that's open source,

  • you can get it off my Web site. Several big companies -- I was just at this conference,

  • and I found that -- including Wal-Mart, I found several big companies that were using

  • this that I was really surprised at because I don't do a lot of testing.

  • [ Laughter ] >>Steve Souders: I trust that they've done

  • that. And actually, who else -- Washington Post

  • is using it. And I asked them to contribute back the robustness changes they had to add.

  • And so the thing that I like about this technique is that it's all done in markup. So we can

  • just change -- instead of script source, having type text script, we would say text CJS, and

  • instead of a source we have a data control.js source, so this means that the browser will

  • basically just ignore this and you can also do it with inline scripts just by changing

  • the type. Then you load control.js. What it does is it crawls the DOM, and it

  • finds these script nodes and it does the right thing. It downloads it asynchronously, it

  • does it in the background. Again, you would only do this with scripts that aren't critical

  • for generating the initial user experience and scripts that do not have any document.write.

  • But I think it's a little easier to get on top of. You can even add this execute false,

  • which says downloaded but don't parse and execute it. And then later when the user,

  • for example, clicks on the compose button, you can say control.js execute script. So

  • that's kind of a nice alternative. The other thing I like about it, how many people here

  • have played with -- with JavaScript loader, script loaders, lab js or YUI lowered. Some

  • people -- the thing that I find ironic about all of the other alternatives out there is

  • their goal is to help you load JavaScript asynchronously. They do that with a helper

  • script, but you have to load their helper script synchronously.

  • [ Laughter ] >>Steve Souders: Anyone else think that's

  • weird? Like, you know, synchronous loaded scripts are bad. So you load our scripts synchronously

  • and we will help you avoid that problem. [ Laughter ]

  • >>Steve Souders: Like -- so from the beginning, one of the requirements of ControlJS was that

  • you could load it asynchronously. So you would use the Google Analytics, async loading pattern

  • and load the script anywhere you want in a page and everything will still work.

  • So JavaScript is a really, really big problem. I'm -- make sure that you look at how it's

  • impacting your Web site and if possible adopt some of these asynchronous loading techniques.

  • Okay. Shifting gears, I wanted to talk about app cache, which is good for offline apps

  • and also for longer caching. So again, the importance of the background

  • photo. You are in the desert. You typically don't have a good connection. So having the

  • offline apps is really important. [ Laughter ]

  • >>Steve Souders: There we go, the groan. So building offline apps is really cool. I think

  • Google docs just announced that this week or last week. It really helps with the user

  • experience when you have a bad connection, you are flying, whatever. But also people

  • are using it from a performance perspective for better caching.

  • So this is a study that I did five or six years ago with (saying name) when we were

  • at Yahoo, it's been a long time, but I've talked to people at other big Web companies

  • who have run the same experiment and they basically get the same results. So I encourage

  • you to run it on your Web site. Basically we put a hidden pixel in every page, we tracked

  • how often people made a request with or without an if-modified-since header. If they send

  • the if-modified-since request, it means they have it in the cache. If they don't, it means

  • they don't have it in the cache. So we can track how many people coming in, how many

  • page views are done with a full cache, a prime cache. Our resources are in their cache or

  • with an empty cache, our resources are not in their cache.

  • I talk about in my best practices setting a far futures expires header. Turns out even

  • if you do that, browsers aren't going to keep things around for that long or for whatever

  • reason, users are going to come in and they're not going to have everything in cache that

  • you might expect. So what we see here is that for page views,

  • if you look at it from the page views perspective, about 20% of page views on any given day are

  • done with a -- with an empty cache. Right? My resources are not in the cache.

  • You can see on the first day, when we put this pixel on the page, 100% of the pages

  • had an empty cache because this image had never been loaded before. After about two

  • weeks, we hit a steady state and we can see it's about 20%. We ran this on various properties

  • at Yahoo that had different user metrics. This was always about the same. This number

  • fluctuated a little bit more, but it was always between 40 and 60%. About half of your users

  • come in at least once a day with an empty cache. So why are these numbers different?

  • Typically, users are doing multiple page views in a session. So even if they have an empty

  • cache, they will come in and have an empty cache page view, which will show up here and

  • show up here. But then they might do three or four more page views, which are going to

  • be a prime cache, because when they did their empty cache page load stuff got put into the

  • cache. So that's why these numbers are different. But it still means people anchor on negative

  • experience. So if half of your users were coming in every day with an empty cache, and

  • you are not taking that into consideration, you are like, well, yeah, it's not 300 k image

  • or script but it will be in the cache, for about half of your users, it's not going to

  • be in the cache. So you can run this experiment yourself and you will get the same results.

  • So the cache, even if you are doing far future expires, the cache might not be doing what

  • you think. And -- and here's a great study from Guy Poe over at Blaze, now Akamai, where

  • he shows that mobile caches are very small. This is another reason why things you think

  • should be in the cache won't be. This was a study I did where I found that -- I like

  • building Web apps and putting them on the home screen and turned out in iOS if you do

  • that the cache isn't used optimally. So you can use app cache for caching.

  • So the way they use app cache at this manifest attribute, you give it a file name, which

  • is your app cache. Manifest is a good name I think we all intuitively recognize what

  • we are going to see here. Here's your manifest file. It has to start with this cache manifest

  • header. We will talk about the revision number in a second, but you'll want to add that.

  • It's got these various sections, a cache section says these are the things that I want you

  • to put into app cache. The network session says these are the things that you should

  • never put into app cache. The fallback section says if the user is online, then use this

  • URL. But if they are offline, read this one from app cache. So the browser, when the user

  • is online, will download this one, but will also download this one and save it into app

  • cache. At least right now, you have to make sure to give this a very specific content

  • type. Text/cache-manifest. So it looks pretty good. It turns out actually it's really, really,

  • really hard and complicated to work with. So here are some of the gotchas that you will

  • probably run into. I know I did. I didn't realize -- like, I never listed my

  • HTML document itself, .php, .HTML in the manifest file, so I just assumed it wouldn't be put

  • into app cache. But if your HTML document uses the manifest

  • attribute, then it's going to be saved to app cache. This was really confusing for me

  • because I had a log-in box on the front page. And if the user came in and their app cache

  • was empty and they weren't logged in, the logged-out version of the page would be saved;

  • every time they came back, that's what they would see even after logging in. So that's

  • a little confusing. If anything in the manifest list 404s, nothing is saved. You get about

  • five meg, which is pretty good. Yeah, so this is interesting, suppose you change one of

  • the resources listed in the manifest file, like an image, you would think that the next

  • time the user opens the app, they would see that new image. They don't. You actually have

  • to change something in the manifest file to make it different, and that's why the revision

  • number was in there on the previous slide. That's what I do is I have that automatically

  • updated whenever I update through source code, through my source code control system, it

  • will automatically update that revision number, so the manifest is always touched whenever

  • I update a resource, and this was really confusing to me. Even if you do, you know, rev the manifest

  • file, the user still won't see the change until the second time they open the app. So

  • I think this is really interesting, and it's a real gotcha', so I wanted to walk through

  • it in more detail, so let's suppose you go home today and you build mobile Web app that

  • uses app cache, or a desktop app that uses app cache, and it's got this awesome green

  • logo that the designer gave you, and you list that into your app cache manifest file, so

  • you push that tonight, tomorrow, the first user ever downloads your app, and the app

  • cache is obviously empty. They've never seen this before, and so the browser fetches the

  • manifest file and in there the logo is listed so the browser downloads that, puts it into

  • app cache, and renders the app to the user so the user sees the awesome green logo. So

  • now suppose tomorrow night you go, you know, I really think an orange logo would be better,

  • so you push to your server this new orange logo, and you remember to change the version

  • number in the manifest file. So the logo is new, the manifest file is new. And on -- today's

  • Friday, so you do that Saturday night, so on Sunday, the user -- same user loads the

  • app again, and the browser says, okay, well, this app has a manifest file associated with

  • it. Do I have any of those resources in my app cache?

  • Oh, I do. I need logo.jif, or i have logo.jif in my app cache; it's this pretty green logo.

  • Even though I've already pushed an orange logo to my server, the browser is ignoring

  • that. That's why it can work offline. It can say I have this stuff in app cache, let me

  • load as much as I can without using the network. And so it displays that app cache logo to

  • the user. But now what it does is it's -- once it's rendered the app with the old out-of-date

  • logo, it fetches the manifest file, it detects that it's changed and so then it checks all

  • other resources in the manifest file and it gets the new version of the logo which is

  • orange, it saves that to app cache, so if the user reloads the app, a second time, it

  • will -- the browser will look in app cache and now it has the orange logo, so it renders

  • the orange logo to the user, it fetches the manifest file which hasn't changed and so

  • it's done. So it's really taken these two loads -- after I update a resource it takes

  • two loads for the user to see the changes. Now, there is a work around to this, it's

  • not that hard, but not that easy. There's this update ready part. The implementation

  • is pretty easy. I can track this. But it's what do I want to do with the user experience?

  • So in the background, the browser detected that there was a new logo, and it fires this

  • update ready, but are you going to tell the user to like reload the app to see the changes?

  • I don't know, you have to decide for yourself. Maybe if it's just images it's not that important.

  • If it's like an important JavaScript security privacy fix, then, yeah, maybe you want to

  • tell them to reload it, or you want to reload it without even telling them, just reload

  • the app. Another way to do improved caching because we know the browser cache doesn't

  • work super awesome is local storage. Really simple API. Local storage is persistent across

  • sessions. If you only care about sessions, you can use session storage. It's about five

  • meg. One warning, browser developers really are worried about this getting too much use

  • because it does a synchronous read. Some browsers will actually read everything out of local

  • storage, the first time you go to that page during the session, and if you have a lot

  • of stuff in local storage, again, it's single-threaded so that can slow down the user experience.

  • So I built this bookmark that lets you look into what is stored in local storage, and

  • I discovered a couple of interesting things that Bing and Google search were doing, which

  • I hadn't thought of, and it's very cool to help with caching. So I think this is the

  • Google search -- Google mobile search implementation. The first time you do a search, the HTML document

  • will return all of these inline script and style blocks, a lot of JavaScript and CSS,

  • and when it's done, it iterates over those script tags and style tags that have IDs,

  • and it takes the content of the block, and writes it into local storage based on the

  • ID of that element. So now, after I've done this first search ever on my phone, I have

  • blocks of JavaScript and CSS in my local storage, so now let's say I do another -- oh, and the

  • other thing it does is it sets a cookie that says which blocks of JavaScript and CSS have

  • been written into this user's local storage. So now if I do another search, this cookie

  • goes up to the server, and the server says, oh, well, you're doing a search, I have to

  • give you this block and that block and this JavaScript and this CSS. Let me see what you

  • already have in local storage. It looks at the cookie and says, oh, you already have

  • this block, I don't have to send you that, I don't have to send you this CSS, and for

  • -- in the case of mobile search, it drops the download size from about 110K to just

  • 10K, because all that stuff is now in local storage. And then when the lightweight page

  • arrives, there's some JavaScript that will pull all of these things out of local storage

  • and write them into the page. So this is a really cool way to get more persistent cache.

  • Local storage is unaffected by other Web sites whereas the shared browser cache, if the user

  • visits a bunch of other Web sites that have large resources, your content might get pushed

  • out. So I did a quick survey using this is what this -- I'm a good JavaScript hacker.

  • I'm not a good UI designer. This is my awesome storage or bookmark list, and you can see

  • it lets you look at what's in the local storage and session storage, tells you how big it

  • is, how many items it is. So let's just do a quick run through the Alexa Top 10 and see

  • how local storage is being used. So here we have -- Google search is using it on both

  • mobile and desktop, so that's one. Bing is using it on mobile. Facebook is using it on

  • mobile. Yahoo is maybe using it a little bit, but not really. We're not going to count that.

  • YouTube, yeah, we'll count that. Quite a bit of content on mobile. Amazon, no. Twitter?

  • Yeah, okay, we'll count that. Five. LinkedIn, no, I would say. eBay, no. MSN, no. So about

  • five or six of the Alexa Top 10 are using local storage, so that's an indicator that,

  • you know, it's worth investigating. Why is it more -- maybe used more prevalently on

  • mobile? You know, the experience of not having something

  • in the cache in mobile is worse, because the network connection speed is so slow, also

  • the cache is smaller on mobile, so caching isn't awesome on desktop, but is much better

  • on mobile, so I think that's why these top properties started using local storage on

  • mobile, but I would expect to see this proliferate on desktop apps as well. So I want to talk

  • about font-face. Again, pay attention to the photos, not to what I say. So, you know, fonts,

  • using custom fonts can create a more compelling, beautiful experience, but people haven't really

  • paid attention to what it does, similar to how scripts and style sheets can block a page,

  • what custom font files do, and so I created this table that here's the blog post, that

  • shows how scripts and style sheets and fonts can affect, and, you know, "blank below in

  • red" means that everything using this font or below it are going to be affected. Flash

  • -- oh, delayed means -- blank is really bad. It means like everything in the page is blank.

  • Delayed means just the element that's using the font file is affected. Flash means once

  • the things -- things will render, but once the resource arrives it has to be redrawn,

  • and so it's kind of a jerky user experience, things have to be rerenderred and repainted.

  • So you can see the impact. Even the green "good" is not really a good experience. And

  • so you want to use fonts kind of carefully. And it's kind of ironic, it's kind of how

  • these async script loader libraries make you load their scripts synchronously. When I talk

  • to designers about why they're using custom fonts, even though we know it has this impact

  • on the user experience, they say, well, these are the most important design elements in

  • the page. I'm like, "so you want the most important parts of the page to take the longest

  • to render?" Like, that doesn't make sense to me. So despite

  • my warnings, custom fonts have taken off, like they've more than doubled in the last

  • year, this is a chart from the HTP archive. So they're taking off. The good thing is the

  • folks at Typekit and the Google fonts library have done a lot of good work to mitigate the

  • impact that custom fonts files have, but we can still go farther. In fact, I think Google

  • fonts library just announced custom fonts a few months ago. If you don't need -- like

  • if you're only using digits or other certain characters, like it's just a word that you

  • want to render in that font, you can actually create a smaller font. The font files are

  • typically like over 100K, so you can create one that is just the characters that you need.

  • The flash of unstyled text means you draw text and then you have to redraw it, and so

  • what I would propose is that browsers have like an impatient fallback, like if -- I don't

  • want to have this flash of my text, so I'm going to wait 250 milliseconds for the font

  • file. If it hasn't come back and we're drawing in a default font, and even if the font files

  • comes back later, I'm not going to redraw it. I'll cache that font for the next time

  • the user goes to the page, but I'm not going to do that, and again, I think this is a behavior

  • that the Google font library and Typekit loaders do automatically for you. Yeah. And also,

  • okay, I'm running short on time, so I'm going to go a little faster. Font should be given

  • a higher priority in caching. Browsers are still just starting to pay attention to that,

  • and even if a font is expired, I might want to render with it, and do a "if modified since

  • request", and then if I get back, "oh, not modified?"

  • It's okay, I've already rendered with a font. All I have to do is validate it. Oh, good,

  • I'm getting close to the end, so there's a lot more stuff I didn't talk about. We -- you

  • know, all of us spent a lot of time building rounded corners that downloaded a bunch of

  • images, so now you can do a lot of things that used to require HTP traffic, you can

  • do with CSS 3, so that's cool. You have to be a little careful, these incur, you know,

  • might incur a lot of CPU overhead or repaints. You can use SVG and canvas instead of downloading

  • images. Video tag could make starting up videos faster. Web sockets, if you have a very chatty

  • sort of app can be used. Web workers, if you have like a lot of computation that you want

  • to get out of the UI thread, you can use Web workers, oh, for some things that we used

  • to have to write a lot of JavaScript or HTML for, you can do with these new built-in controls.

  • Again, the photo, more, infinite number of digits. History API, we used to have to implement

  • this in JavaScript. Now we don't have to download all that JavaScript. Ping is a way to avoid

  • a redirect if you want to track something. Don't use set time-out for animation. Use

  • request animation frame. It will be faster. You can use the native JSON parser, and here

  • are some good resources to get more information about this other HTML5 stuff. So what are

  • the takeaways? Speed matters. Hopefully we all agree about

  • that. I saw you raise your hand before. So I'm going to hold you to that. Pay attention

  • to what's coming out of the Web performance working group out of the W3C. You can use

  • window.performance to track the timing on your pages, and even if you haven't done that

  • yet, if you're using Google Analytics, you can go and see the data there. It's already

  • been gathered for the last few months. JavaScript blocking the UI thread is really critical.

  • Try to get a lot of that stuff deferred or async, and caching is really important. I

  • think it's one of the most important things for a fast user experience. Browsers are improving

  • their cache. Mobile browsers have a lot of room to catch up on, so you can try some of

  • these other techniques. And be careful about using font-face. So before I close out, I

  • want to mention, if you like this kind of performance stuff, I'm sorry, but you should

  • have been at Velocity this week. We just finished that Wednesday. But if you missed that, you

  • could go to Web PERF days, the first ever, but -- well, actually, that was yesterday.

  • Okay, so you missed that one. [ Laughter ]

  • >>Steve Souders: Oh, okay, we've got Velocity Europe coming up in October, so you might

  • have to go a little farther, but -- and we'll be back next year in June for Velocity. I

  • also wanted to just mention this -- oh, I added this like five minutes before I came

  • on stage. How can I do this, like -- I don't know, I have to go through them all. So (indiscernible)

  • runs this performance calendar every year, and O'Reilly took the most recent performance

  • calendar and put it into a book, so this just came out this week, and you can get most of

  • this content on the blog for the performance calendar, but the -- they were updated, and

  • if you like books, you can get it in book form here. So that's it. Thank you very much.

  • [ Applause ] >>Steve Souders: So I've got about four minutes,

  • I would be happy to answer any questions and I think they want you to use the mic. Everyone

  • is heading out. >>> Would you care to expand upon font awesome?

  • And also to resolve some of the issues of pop-in, I found setting a fixed type for whatever

  • text I decide is very nice. >>Steve Souders: What's the first one? Expound

  • on... >>> Font awesome, using fonts instead of sprites?

  • >>Steve Souders: Oh, yeah, so you can create a custom font, you know, file, that has little

  • pictures, you know, kind of like wings -- what is it on windows? The wings font, wingdings,

  • yeah, so you can do that with a font, so if you have like really small images that you're

  • using now and you're downloading them as HTP requests instead of images, instead you can

  • download a font fall. It doesn't have to be huge. Maybe you have 10 of those or 20 of

  • those, and you can download those and use those to draw those little images, those little

  • sprites in the page for like maybe little buttons or things like that, and so, you know,

  • I think that's a great idea. You could also use sprites. Sprites are maybe a little harder

  • to do. You have to create the image and know all the CSS, but the one thing I would say,

  • if you're using any kind of font file, is try to figure out a way to do it that doesn't

  • block the page, like especially in IE. Custom font files block rendering of everything in

  • the page, so if you could do that lazily or something like that, that would be good, and

  • then the second one was... >>> Just a tip to deal with font snapping

  • in after they loaded, the ugly hack of just setting a fixed type for everything. So at

  • least it doesn't like reflow. >>Steve Souders: Yeah, yeah, you could do

  • that. Yes, another question. >>> Yeah, you said mobile browsers don't support

  • most of those features yet, custom, you know, desktop browsers either, so how would we test

  • them? >>Steve Souders: I guess I wasn't clear. Everything

  • I talked about is supported in mobile browsers, pretty much, and, in fact, you're going to

  • get -- I think that's another reason why we're seeing more HTML5 stuff on mobile and desktop,

  • because on desktop, there's still a lot more lingering IE6, IE7 legacy browsers out there,

  • so you're almost a little safer using the cutting edge stuff on mobile than you are

  • on desktop. The only thing I can think about is I thought there was something -- well,

  • the page visibility API is only in Chrome, but all the timing stuff, local storage fonts,

  • app cache, async and defer attributes, all of that is supported on mobile too.

  • >>> Thank you. >>Steve Souders: Yeah. Okay, let's go here.

  • >>> Let's see here. You were talking about visibility and document.webkit hidden and

  • how that relates with click tracking and stuff like that. One click unsubscribes and e-mails

  • and things like that, is that another way that we can avoid being automatically unsubscribed?

  • >>Steve Souders: Oh, oh, well, but how would you -- how would you -- what's the scenario

  • where you would render unsubscribed page without the user seeing it?

  • >>> Well, if they're following links and pre-loading in the background, you might follow --

  • >>Steve Souders: Oh, yeah, the pre-rendering I was talking about is the developer or user

  • has explicitly asked to open a page, but we can just know we can do it in the background.

  • But, so, yeah, if you're crawling a page, that could be something that you could do

  • is to make sure not to -- you know, you could instrument an unsubscribed link so that it

  • only worked if the page was visible. Yeah. >>> Thank you.

  • >>Steve Souders: Yeah. >>> What's your recommendation in terms of

  • moving the script tags physically to the bottom of the body tag versus using the defer script

  • tag that you described? >>Steve Souders: Yeah, I think both of those

  • work. One thing that we -- I only have a few seconds, so one thing we don't have time to

  • talk about is the importance of the onload event firing as quickly as possible, so in

  • both cases with defer and async and putting scripts at the bottom, you're going to block

  • the onload link, the onload event from firing, so really putting scripts at the bottom is

  • almost the same as doing defer. It really has more to do with kind of the size of your

  • team. A lot of times there's, you know, 20 or 200 people working on a property, and so

  • it's hard to get the message out to put scripts at the bottom or like someone's code is only

  • going to be executed at the top and be really hard to give them a foothold in the top and

  • give them also a foothold in the bottom and make sure that both of those are done in sync,

  • so if the only place like the logging or metrics team has a place to -- a foothold in the page

  • is at the top, they can get the same behavior using the defer attribute as just putting

  • the script tag at the bottom. Putting the script tag at the bottom is another lightweight

  • way to avoid that blocking of the UI thread. Okay. So I should wrap up. Thank you very

  • much. [ Applause ]

>>Steve Souders: Okay. Is that my cue to go? Okay. We're having a current discussion about

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it