Getting the Most Out of Safari Integrated Developer Tools 

Session 507 WWDC 2010

Safari contains an extraordinary set of integrated developer tools. See how to use these tools to debug JavaScript, profile performance, inspect and edit CSS, view locally stored data, and test pieces of code on the fly. Discover new features that streamline your development, and learn techniques for optimizing page load time on mobile devices such as iPhone and iPad.

Joseph Pecoraro: I’m Joe Pecoraro.

I’m a Safari Engineer a Safari iPhone OS Engineer, I’m a WebKit Engineer, and I’m an expert on the tools that we’re going to be talking about today.

I’m an expert for a couple of reasons.

I’ve been working in these tools for a while, a lot longer than actually I have been here at Apple, because they’re part of a WebKit Open Source Project.

And the second reason, I, like many of you, am a web developer.

The tools I mean, the features that I’ve added and improved on in these tools are ones that, I, as a web developer, wanted and needed, so they’re ones that you probably wanted and needed as well.

So let’s get started.

Getting the most out of Safari’s Developer Tools is a great title, because it’s easy to get distracted by a cool feature of the tools that doesn’t really relate to your day-to-day work.

And that’s not really getting the most out of the tools.

So we took a step back, and we said, “What do we know about you guys?”

You guys build great web applications using standards open web technologies like HTML, CSS, and JavaScript.

And by building applications using these features, you automatically get a wide range of support on all kinds of platforms and devices.

So, not just desktop computers and laptops, but also mobile devices like the iPhone and already on more than two million devices like the iPad.

And the great part about building using these technologies for these types of devices, is they all have a really great browser, Safari, running all those technologies including and actually, Safari is leading the field in HTML support, CSS support, and HTML5, and CSS3.

So when you’re working with Safari, you need tools that work with the latest feature, the latest tools.

And that’s exactly what we’re talking about today.

The tools built into Safari that are going to improve your work flow.

So we’re going to look at three different pieces today.

There’s so much that we can cover with these tools that we just have to limit ourselves.

So the first section is going to be exploring and developing web content.

This is how you can learn from the web itself.

And that’s an absolutely vital thing you need as a web developer.

Next, we’re going to look into advanced JavaScript debugging.

What turns a webpage into a web application is JavaScript.

It’s what makes the user feel like they’re using a desktop application.

And for that reason, it is important that we look at JavaScript, that’s typically complex to debug, we’re going to show you how to make it simple.

And finally, we’re going to tie this back to you and your users by looking at improving page load times, and how you can make your websites optimize really well across all kind of devices.

So the first section, explore and develop web content.

This is my favorite part of about the developer tools, because it deals with two things that I do every single day, and it’s two things that I know you guys do as well.

The first is browse the web.

Last week, I came across this webpage, and I thought it was really cool.

It’s giving a nice graphical display of different browsers in which HTML and CSS features they support.

So when I came across this, the first thing that I thought was, “How did the do that?”

right? It looks really cool, how did they do it?

Well, as developers, the answer is there for you.

The source code is open.

It’s in the HTML, it’s in the CSS, it’s in the JavaScript.

But if you want to find out how a particular portion of the page works, it could be a lot of work, right?

You have to manually dig through all the files to find out what affects a portion of the page, and that’s not very efficient.

So we’re going to show you how you can use the tools to inspect a portion of the page that you’re interested in, and have the browser compile all the relevant information for that section of the page, including information that wouldn’t be available to you in those source files, such as, the browser’s user agent styles, and the second part of this section, developing web content, is exactly that, you guessed it, offering web applications.

So when we see developers offering a web application, they tend to break the page down into chunks.

It’s a tried and tested developing technique that seems to work very, very well.

So let’s focus in on one of these chunks.

So there’s a bunch, there’s browser colors, there’s the sun rays, there’s JavaScript interactivity.

Well, one that we find is pretty useful is developing just one chunk, like a list of elements.

And we see developers working on this.

They get the mark up and the content pretty easily, right?

It’s just a list of elements.

The difficulty we find for developers is styling that list, positioning it on the page correctly, laying it out in the text formatting.

And we’re going to run through how we see developers typically working on a feature like this.

It’s how I use to do it, it’s how many of you might be doing it right now, and we’re going to try and show you how you can reduce that workflow, improve it using the tools built in the browser.

So to build this list, you start out in your editor.

You write the markup for the list, that’s pretty easy.

You then load it into your browser, and you see, “OK, the content looks right.

Now it’s time to style.”

So you go back to your editor, you tweak some CSS, and you go back and you refresh your browser.

Not quite perfect yet.

So you go back and this tweak and refresh cycle continues and it repeats, and you can come back to the browser, and it wouldn’t even look like anything’s changed.

These context switches are costly.

They are a waste of development time sometimes.

And the problem is these refreshes.

So we want to cut out some of those refreshes, allowing you to do the work in the browser, get the right CSS values, get the right positioning, and take those back in one go to your editor.

And the tools built into Safari right now that allow you to do that are the Web Inspector.

And the best way I can show this to you is by going into a demo.

So we’re just going to see some pictures of it right now, and I can prep you for the demo.

We are going to be looking at a Safari 5 extension, which if you were at the sessions earlier, if you’ve heard about it this week, they’re just web content, they’re just HTML, CSS, JavaScript.

Inspecting an extension is exactly like inspecting a page.

And the second point is we’re going to try and focus on new features from Safari 4 to Safari 5.

So for those of you that are new to the Web Inspector, we are going to cover the basics.

We’re going to get you up to speed and comfortable with the Web Inspector itself.

But for advanced developers, we are going to cover some of those features that maybe you didn’t know about before.

And here, we are running Safari 5.

It’s running the Twitter flow extension from earlier which consists of an Extension bar, a Toolbar item, and when you click the Toolbar item, it brings up this full page experience.

And some of you are probably wondering right now, “Hey, that’s a pretty cool effect.

How do they do that?”

And to answer that question, just right-click on what interests you and choose inspect element, and that’s going to bring up the Web Inspector.

So here it is, docked to the bottom of the screen.

If this is your first time seeing it, you’ll see there’s a lot going on, there’s a lot of different panels giving you different ways to view information about the inspected page.

For this part of the demo, we’re just going to be focusing on the Elements panel.

The Elements panel consists of two major components.

On the left we have this DOM tree, on the right, we have contextual information for that selected element.

And something really cool to note about this DOM tree, is it’s not what you see in your editor, in your HTML editor when you try to let’s say, write the page.

It’s actually a live representation of what’s on the page right now.

And you can see that as the elements are adding and being added and removed from the DOM.

This is a great advance to working in the inspector in the browser compared to your editor because you’re going to have access to DOM elements that were probably generated through JavaScript, which you won’t be able to find in your editor.

So something neat about this DOM hierarchy is as you hover over the elements, they actually highlight on the page.

So some that move might not work perfectly, but here, if we hover over the header and we go in on the input element, you will see “Hey, this is the exact element that we wanted.”

As you’re exploring pages, you’re going to be able to pick the exact ones that you’re interested in.

If you’re developing pages, you’ll also get width information and margins and paddings that are useful to you as a developer.

So let’s select the input element and look at what kind of style information we can see.

So I’m going to zoom in the sidebar, pan, get that right, OK.

So we’ve got the input element selected.

What styles are affecting it?

Well, if we expand the computed style section, this is that list of all the styles that are finally affecting this element.

But in most cases, that’s not what you’re interested in.

You don’t want to know just what the styles are, but also where did they come from, in what order are they being applied, and that’s what the rest of the style section is actually showing you.

So the by this information is actually coming from the browser’s engine, WebKit.

So while CSS cascading rules and specificity are quite complex, it’s difficult to do manually.

And here, the tool is showing you exactly what the browser is applying.

So we see the margin top is defined in three different places.

We’ve got 5 pixels, 50 pixels, and 100 pixels, and we see the order of top to bottom of how they are applied, and we see the 5 pixels is over ruling the other two.

The 5 pixel rule was actually defined in this external file, tweetflow.css, specifically on line 24.

And that’s actually a link that would take you to the resource in another panel in the Inspector and highlight the line where the selector is.

It’s a that is a feature that has really been asked for from designers.

And we see, as we go down, the margin top of 50 pixels is defining the inline style sheet.

And if you think about the cascading rules, inline style sheets are normally more specific than external style sheets.

So here, because we have got a stronger selector, it is actually overruling a more general selector.

And if you are just again manually looking at the files, it would be difficult information to deal with.

You’d probably think that the 50 pixels might be applying.

So if you scroll down more, we see here our user agent styles.

That’s information about Safari’s default styles itself, that is information you would not get from the source code files.

And we scroll down farther and we see here’s something new in Safari 5.

We have got inherit information.

In this case, from the search elements, black containers of header and body.

And also, even cooler, we have got pseudo element styles.

And here is again, if you are exploring the web or even offering your own page, you might not have known about pseudo elements like the placeholder element, and even less seem to know that you can style those elements.

But by using the Inspector, you can see, OK, here is the selector I would need to style a placeholder text style and input element.

And here is what the default user agent style is.

So maybe you do want to do this on your own page and change it a little bit.

So you want to make the color just a little bit darker.

Well, what does dark grey represent in color values?

Well, you can actually flip through the different color representations by hovering the color swatch and just clicking through.

So Hex, RGB, HSL, and back around into the nickname.

Use the tools to work for you and get you exactly what you want.

So let’s take a look at the other sections.

Down here, we had metrics and properties and event listeners.

The metrics section shows you box model layout information, such as the positioning, margin, border, padding, all exactly as you would expect it, and you can actually go in and edit it like a lot of values in the Inspector.

We are going to skip over properties and focus on event listeners because those are new again, to Safari 5.

So we have got the search element selected, and we see that there is a search event with listeners, and there are two listeners registered on for this search event.

The first is registered on the input element itself, and it runs the change party function.

And that bubbles up to the body running the flat for event function.

And take a moment, body.happy is just showing you the most accurate selector for the body element at the time that this was expanded and this information was gone.

And what is really cool to note about this, event listeners section, is it’s information that you cannot actually get through JavaScript on the page.

And because it is coming from the engine itself, you get the exact capturing on target and a bubbling event listener phase that the events are going to go through.

So we can expand these and see a little bit more information about the listeners themselves.

When you actually input a search term and hit Enter, what is going to happen on this page?

Well first, it is going to run this change query event listener, and it is going to dispatch a message because this is an extension up to the global page to cause a Twitter search for more terms.

Sending a bubble up to flash for event, and that is going to change the background color to this slight grey color.

Well, let’s follow this even further.

We go to the body and we should just click on the element and jump directly to it in DOM tree, and we will see up here at the top that the background color has a WebKit transition, and it has got a transition that’s going to last for half of a second.

And down to bottom, because we already had that event listener section open, we see there is a WebKit transition end function with a listener, and an anonymous function has registered, and it is going to bring the background color back down to black.

So let’s play around with this a little.

We have seen the JavaScript to change the background color, and we’ve seen that there is a WebKit transition on it, so let’s actually run some JavaScript.

I am going to open up the console, the JavaScript console, built into the Inspector, and actually just going to slide up from the bottom.

This allows you to run JavaScript directly on the page, and it is also it’s really, really neat.

I find myself in here a lot.

So let’s start typing,, and you see it is giving us this nice autocompletion, and I find this autocompletion is the best it can possibly be, much better than editors.

And that is because again, it is getting information right from the page.

It knows the objects that you have got, it has the actual object, and it can enumerate all the properties, anything that you have customly added or removed.

So we could type, but that is kind of long, right?

We have already got the body element selected here in the DOM tree.

We can just do special variable $0, and this is part of the command line API that a lot of web developer tools use.

It is similar to the console API, like console.log, etcetera.

$0 represents the current selected element, $1 is the last, all the way up to $4.

So let’s go to the Dedicated Console panel, to remove some of the distraction, and see what happens when we actually change the background color on the body.

So we saw the JavaScript to do that.

I am going to do something obvious.

I am going to make it just white.

And when I hit Enter, the background color of this page should flash to white for half a second, and come back down to black.

And of course, I forgot the equal sign.

There we go.

That is a little bit too strong.

We saw the 333.

But let’s try and say, we are offering this page and we want to come up with our own style to work better.

let’s try 456, a nice teal color that I know.

And OK that is cool, that could be what we actually want, and we can then take this value back to our editor.

And one thing to know is how much faster it is working with the JavaScript console to just poke the page than doing the traditional update file, refresh the page cycle.

We have to update a JavaScript file, reload up the extension, put in a search term, hit Enter, and we’d only have been able to see that individual style and not compare it to anything really quick.

Here, because we are just poking at the page, we can do a lot really fast, really compare different styles.

So there is one last thing I wanted to look at.

So I am going to come back to the Elements panel and remove the console, and you have got this DOM tree and this style sidebar, you can actually edit those directly.

So if you find something you are interested in, just start double-clicking it, just start editing it.

You can tab through, you can edit tag names, attributes, you can even add an attribute, if you don’t make the display none, and remove the input element on the page.

And you know, if you are really ambitious and you want to actually add HTML to the page, you can choose Edit as HTML, and get this free form editor.

Enter will give you new lines, Command Enter will commit your change.

Also, you can do the same thing to styles.

let’s try and do something a little bit cooler.

We have seen that there is a color around the edge of some of these Tweets.

And we have seen that the body’s class has been changing, sad, happy, and normal, based on the text in the Tweet itself.

So we can style something on the page, say, add a selector to the page and start styling.

let’s do that with this text up here at the top.

It is static, it is not going to change throughout the demo.

So I am going to zoom in a bit more on the sidebar, and let’s increase this text size so you can see it.

So we have got the font size down here, I will just double-click it, and because this is in numerical value, I can just use the up and down arrows to increase the size immediately right in front of you.

[ Applause ]

So I just tab through.

I’ll make a WebKit transition on the color for about three seconds, and zoom out a bit, I can actually add a new style rule.

So this is allowing me to add a selector to the page and start styling the elements.

So I am going to say when the body is sad, let’s make the color red.

And it is grayed out right now because it is not currently affecting the element when I created it.

And we see right now the body is happy, I can make the color green.

Of course, I just missed it, but here is red, the sad, and you see that transition happening.

This is really a great tool for designers.

When they are starting with a blank canvas and they want to just create a whole bunch of styles to customize the page just perfectly.

They do not have to do a lot of back and forth editing.

They can just quickly apply styles and see how it affects the page.

So with that I will go back to the slides and do a recap.

So what we just looked at was learning from the web, exploring, and being able to just inspect portions of the page, view the DOM elements, view the CSS styles, and view any other contextual information like event listeners.

Basically answering the question, “How did they do that?”

We also looked at how you can interact with the page and just directly edit the DOM tree, the styles, use the JavaScript console to poke at the page itself and really save some development time.

So with that, I’m going to pass things over to Brian, my coworker, to talk about JavaScript.

[ Applause ]

Brian Weinstein: Hi, guys.

I’m Brian Weinstein.

I worked on the Web Inspector and extensions for Safari 5, and I would like to now talk to you guys debugging JavaScript.

So let’s get a little bit of the show of hands here right before lunch, who has written some JavaScript, proofread it, loaded it up in the browser, and then saw that nothing has happened?

And I don’t believe the rest of you.

[ Laughter ]

All right.

So there are two kinds of errors that you’ll see relatively commonly when you’re writing a lot of JavaScript.

You’ll see parse errors and runtime errors.

I’m going to start talking about parse errors.

Parse errors are what happens when the interpreter does not know what to do to with your code.

I have few examples of these that we can run through.

You might have mismatched quotes where this would just confuse this would just confused the interpreter.

You might have missing commas in an object decoration.

This could happen really easily if you’re adding a new property to an object.

Or you might have unbalanced tokens, like when you want to log something to the console and you forget your closing parentheses around your console around your console.log.

I’m going to run through a few run a few screenshots here with the Web Inspector to show you how easy it is to find and fix these errors.

So you load a page that has you load a page that has a parse error on the site.

When you look at right above me at the in the bottom your bottom right hand corner of the Inspector, you’ll see that there’s a little badge saying that there’s one error on the page.

You can click that and it will open the console, and it will show you the error, and if we get a little bit of a closer look at that, you’ll it will give you a line number on the file and tell you that, “Yeah, it really was a parse error.”

So you can click on the line you can click on the filename, and it will take you directly to that file, and to that line, and it will actually show you with a little nice yellow highlight, that there was a parse error right there, it takes you to the actual line, and when we take a closer look at that, you can see that we’re missing a comma between mouseover and globalWindow.pauseTweets.

It’s something that would be very easy to miss when you’re writing code, but we make it very easy to find and fix this error.

The ones that are a little more tricky to find and diagnose are runtime errors.

This is when the interpreter correctly understands the code, but something during execution throws an exception.

So let’s take a look at a few ways this can happen.

You might have you might try and you might try to be referencing an undefined or null property by calling that will give you an exception.

You might have some you might throw an explicit exception if you’re defining an API and someone calls it with an incorrect number of arguments, or you might find an error like this where this will actually throw a DOM exception because you are not allow to append children to the document.

You either would probably want to append the child to the document.body or document.head.

So now, I’m going to take as through a demo of how to find and fix these JavaScript errors when your and we’re actually be using an extension, which as was mentioned before, is all HTML, CSS, and JavaScript.

So let’s go over to the demo machine.

And that worked, step one.

All right.

So right after I’d seen this demo after I’d seen the demos by Tim and Adam about extensions, I decided, “Oh, All right.

I bet before our presentation, I can add a Next button to the I can add a Next button to the bar.”

And I added a Next button, but I didn’t get far enough as to make it working.

When you click the Next button, you’ll see that nothing is happening.

So let’s take a look at the Inspector and see if we can see what is going on.

So we inspect the element, and this is the window version of the Inspector.

It’s not doc into the page because it wouldn’t really make much sense to dock it into the bar.

And I got a little click-happy, so we can see that there are seven errors on the page, and let’s take a look at those, and to take we’ll zoom in a bit.

And our error is that Safari.globalpage is not an object.

So this happened on 1ine 54 of bar.JS.

So let’s take a look of that.

And it’s where we call it’s the Next button’s click handler, and that is being called when and we call Safari.globalpage.content.window.immediatelyShowNextTweet.

So let’s go into the Scripts panel, and we’re going to turn on a pretty cool feature that lets you break on exception.

So what this will do is this will pause this will pause the execution of the JavaScript in the debugger right before an exception is thrown.

So seven times that I believe I clicked the button seven times.

So it’s pretty much a one-to-one correspondence between when I click the button and when it threw an exception.

So let’s see what happens.

We click the Next button, and it’s broken for us in the debugger, and it has and we are now stopped on our line that has been breaking.

So let’s take a look at some of the variable state.

New to Safari 5, we have this variable state popover that shows you the value of any variables when the execution is paused.

So our error is telling us Safari.globalpage is undefined.

So let’s put our mouse over Safari.globalpage, and look at that.

It is undefined.

So this is probably where our issue was coming from.

Now, I’m pretty sure that I’m able to use Safari like that.

So let’s take a closer look at the Safari object, and we see all of its properties.

And this is just really cool and makes it really easy to debug JavaScript on the fly.

And as was mentioned in the earlier presentations, you see there’s a Safari.application, a Safari.extension, and a Safari.self.

We can open all of these and take a little bit closer look at it.

And so, we can see that there is no Safari.globalpage.

So us was getting the error is expected.

But if we look at the extension object, we can see that Safari extension has a global page.

And inside the global page, there is that content window.

And that content window has and that’s a DOM window.

So let’s try let’s go into the console and take a look at our code and try and write this try and write the function of this should be.

So let say Safari.extension.globalpage, and it’s autocompleting or us, which is a good sign.

It means we’re probably on the right track, .contentwindow.immediatelyShowNextTweet.

So and this is actually this is really exciting, because what this is doing is we’re currently debugging a bar, but this is actually autocompleting functions for us on the global page, and that’s just really exciting and will make your life a lot easier to debug web applications, or to debug extensions.

So let’s run this function.

Look at that.

It is going to the next Tweet when we run this function.

All right.

Let’s [ Applause ]

Thank you.

All right.

So now, let’s open our bar file and where we call Safari.globalpagecontentwindowimmediatelyShowNextTweet, we just say Safari.extension.globalpage.


We go back we go to the extension builder, and we reload our extension.

And I know exactly what I did, and but now, we go back and the Next button works.

And it will keep cycling us through and it will keep cycling us through out Tweets as we go.

And now, it should go back to showing them every 10 seconds, but it’s not.

It is just cycling through them way too fast.

So let’s take a look at what is going on here.

So let’s open the extension builder, let’s was reload the global page just to clean up our state a little bit here, and we’ll go into the extension builder, and we and since global page, as was mentioned before, is just HTML, CSS, and JavaScript, we can inspect the global page.

And now, am going to get to show you something that it is exciting.

It is the Timeline panel.

So what this what the Timeline panel does, it was mentioned in the Safari State of the Union, it shows you where your web page is spending time.

It shows you when scripts are running, when network access is happening, and when resources are loading.

So let’s start the Timeline panel and we’ll start recording.

So let’s start the Timeline panel, and we’ll start recording.

We will click Next a few times, and let’s take a look at what is happening here.

[ Pause ]

All right.

So we now we saw our bug, and this is really interesting.

So what is happening is that we are installing timers each time the next button is clicked, and they are firing 10 seconds later.

But every time the Next button is clicked, we’re creating a new timer that we’re creating a new timer that is never cleared.

And each time the Next button is clicked, we should be clearing the timer.

So right now, we have like a lot of timers running.

And so, let’s take a look at our code where the timers are handled, let’s go to the global HTML page, and so, when immediately show next Tweet is called, we are clearing the we are clearing timers.rotate intervalID.

But when we are calling set interval, we are setting timers.rotate interval identifier.

That is probably what is going on, so let’s use the same variable in both places.

let’s close these files out, open the extension builder again, and reload our extension, and then we are able to click Next a few times, and they will not show up until and now, the timers have been are being cleared correctly, and they will only show up every 10 seconds, which is what we want.

[ Applause ]

All right.

Thank you, guys.

let’s go back to the slides.

And so, what we just discussed here is we showed how efficient the Web Inspector is at finding and fixing parse errors, and then we showed a little demo of debugging runtime errors, learning how to break on exceptions, and showed off some exciting new features of Safari 5, like the debugging state popover and the Timeline panel.

I am going to give it back to Joe to talk about how to improve page load times.

[ Applause ]

Joseph Pecoraro: So improving page load times is all about improving the page for you and your users.

Your users are the ones who are using your page a lot, so you want them to have the best experience possible.

And there’s a lot of different page load issues.

I have just picked out four here; large resources, a large number of resources, sequential dependencies, and non-responsive interfaces.

And the thing is, you probably know about a lot of these.

You probably know how to fix them as well.

So why is this part going to be useful to you?

It is going to be useful because the problems that developers have is not how to fix these, it is how to find them, how to detect and diagnose them on your own pages.

And that is what we are going to do.

We are going to show you how you can use the Web Inspector to find these problems and then fix them.

So we can really break these down into two different sections.

The top two are related to size or quantity.

And there is a view of the ones back there that will do just that.

So here is the Resources panel of the Web Inspector.

I’ve chosen the size graph, so we are viewing the resources based on their sizes.

If this is your first time viewing the Web Inspector’s Resources panel, you will see it is very visual.

There are a lot of colors, there is a lot of information going on.

These colors are actually representing different resource types.

So in the summery up at the top, you can see that this page consists of a lot of purple resources, which are images, and orange resources, which are scripts, which is kind of what we would expect.

This is the homepage.

And down below we see the resources sorted in size from largest to smallest.

And we see that the largest resource is in fact, that image, but we see this kind of two-tone color for the script beneath it.

So let’s zoom in on that.

As you hover over the resource in the Inspector, it is going to show you these numbers.

It is going to give you a detailed overview.

So on the left, in the bold potion, the 32 kilobytes represents the transfer size of the resource.

Extending out with the transparent portion up to 120 kilobytes is the total size, the real size of the resource.

And what this is showing you is that when it was transferred over the wire, this resource was compressed.

This is something that you want to see when you view your resources in the Web Inspector, because you definitely want the resource to be compressed.

Look just here how you can visually see how much smaller it was when it was compressed.

Likewise, when you have a large resource, you can minimize it.

So if you if this resource were not minimized, you could improve it on your own page and see the exact values before and after, because you got them right here.

So let’s zoom out and scroll down the view to see what I meant by a large number of requests.

So here, we have got seven scripts highlighted.

All seven are really small.

They are just less than 3 kilobytes in size.

This means that the page is doing seven separate requests for each of these individual resources.

And if you think about it, requests take up a large portion of the page load.

So when you can minimize a number of requests, you are minimizing your application’s dependency on latency, for instance.

So let’s say, five of these were static, you might be able to combine those into an individual resource, and request that, and therefore, reduce the page load a little bit.

This doesn’t have to be with just scripts.

It can be images as well.

If you see a lot of small images, typically icons, you may be able to combine those into a sprite, for instance, which is a great way to improve a page.

Now, size is typically pretty easy.

Where we find that developers struggle is time-related resources, because seeing the network overtime is difficult and it will likely change every time.

So these other two deal with time, and they really deal with the user experience.

When your user comes to the page, they want it to load quickly, they want it to feel like it is loading quickly, they want it to be interactive as early as possible so they can start using it.

And that is exactly what these two are.

So the largest time-related problem is latency.

Now although, you do not have control over latency, you can minimize its effects.

So you can actually view latency in the Inspector.

Here is again, the Resources panel.

We have chosen the time graph, and down at the bottom, I have chosen to sort by latency.

And just with size, this is sorting the elements, largest latency down to smallest.

So let’s zoom in on the top three.

Here again, when you hover with your mouse, you are going to get that number.

And again, there’s two-tones, but here, they have been flipped.

On the left, we see the transparent portion leading up to the bold portion.

And so, these values are representing the left-edge of the transparent portion, is when the browser requests the resources.

That request goes on until the bold portion, about 2.3 seconds later, that is when the browser starts receiving the data for that resource.

And the bold portion continues until the entire resource is downloaded and completed.

So what I found very interesting about this is that these three highest latency items were not actually coming directly from the page that I requested,

The top resource, the largest latency, came from

And the other two are a third party altogether.

And what that showed me is no matter how much you can optimize your own page, if you a dependency on third parties, they may be affecting your page load, they may be delaying events on your page because you have to wait for their resources.

And say you actually did own one of these servers, you could, you know, have diagnosed a server-side issue.

One of your servers is affecting the latency.

You may be able to switch a closer server, a better server, or a content delivery network that is going to make the latency just a little bit smaller.

Latency is a real big issue for mobile devices, not so much, desktop.

So what I’ve switch to is my favorite view of resources.

And to get to this point, I have turned off the large icons, I have clicked the icon down in the bottom, and I have switched to the small view, and that is going to allow me to fit a lot on the page at once.

I have also chosen to sort by response time.

And what this shows you is exactly what you wanted to see, the page as it loads, as resources are requested, and as they are downloaded.

And what I really love about this is you do not have to read any of the text to understand what is going on.

You just see a lot of colors and a lot of lines.

And speaking of lines, there are two new lines, these two vertical lines.

The blue line represents the DOMContentReady or the DOMContentLoaded Event, firing on the page.

And this will fire after the original document has been parsed, inline scripts have been run.

So the DOM is now interactive.

You can interact with it in JavaScript, you can register your listeners, you can start working with the page.

The red line, 5 seconds later at about the 10-second mark, is the unload event firing.

And this cannot fire until the original subresources have loaded.

So external style sheets, scripts, images, to name a few.

And you can see the huge discrepancy in this case because of the network speed and the large image.

And we’ve seen a trend of developers moving from unload to DOMContentReady, or inline scripts, for instance.

And that is a really, really good thing, because as your page loads, the page is going to be interactive far earlier than the unload event in some cases.

So say, you have your own JavaScript navigation menu, you want it to be interactive for the user so they can start using it as early as possible.

The last thing that I want to talk about was sequential dependencies.

And there is even one more.

If you just look at the colors of this, you will see orange resources up at the top, those are scripts loading, and purple resources down at the bottom.

Those are the images loading.

And there’s three images in particular that I find interesting.

These make up the main content on

This is the hero graphic in the center, this is the navigation menu at the top, and the promo image down the corner.

And what you can see here is because they are so low in this view, they are actually not even being requested until about 3 seconds later, and downloaded at about 4.

So when the images start loading, is something that the user is definitely going to be worried about, because that is their view of the page as it is loading.

And by using this view, you might be able to shuffle things around on your page, move scripts later down closer to the body of the body’s closing tag to delay their load, and potentially bring up these image loads so that they load a little bit sooner, and the user sees the page start filling in a little bit faster.

So back to sequential dependencies, there’s always one sequential dependency.

And we can look up at the top, this is the initial page request, right?

So I went to, started loading the index page, that is that blue line at the top, the request took 863 milliseconds until I got the resource.

And as soon as I got that data, the browser started parsing, and it said, “Hey, I need these scripts.”

And you can literally draw a line right down where this sequential dependency is.

And this is what I call a visual property of the Inspector, as you can just easily see this dependency right here.

And it doesn’t just have to be that initial request.

Here is another example.

I went to a mail client.

And if I zoom in, there were 5 different redirects just to get me the original page that I wanted.

There’s a total over 1 second.

As a user, I was just sitting there and the page was blank.

Sequential dependencies don’t have to start at page low like we just saw in the redirect.

It could be with external style sheets requiring images or something like that.

And they do affect the page load because they are compounding all of those latencies, all of those requests.

So when you can remove those sequential dependencies and replace them with, you know, parallel request, you are going to be able to improve your page loads.

So with that, we have looked at some time-related issues, and some size-related issues, all of the network, so that you can improve your page load times.

And let’s summarize everything we have gone through this talk so far.

First section, explore and develop web content was all about how you, as a developer, can learn from the web itself.

There are so many examples out there.

And if you come across something and you ever think the question, “How did they do that?”

you know exactly what to do.

Right-click on what interests you, you open up the Web Inspector, and you start exploring the page.

As a web developer, this is a really, really vital thing that you can do.

It helps you grow and it helps the web improve by everyone learning from each other.

We showed how you could reduce your development time by using the Web Inspector to just edit the page manually.

This reduces the back and forth contact switches, it reduces the number of wasted refreshes, you can even debug JavaScript in the inspector, which has traditionally been complex, but we just showed you it is really, really cool.

And last, we talked about improving your page load times, which is again, how you can optimize your page for all your users.

Not just your desktop users or the ones using laptops, but also mobile devices, like websites for the iPhone and the iPad.

So if you have any questions and you would want to ask them, not just now, but later you think of them, you can email them to Vicki Murley, the Safari Technologies Evangelist.

If you want documentation on the Web Inspector, you can actually go to the Developer Center for Apple.

And again, the tool that we showed you, the Web Inspector, is Open Source.

If you thought about some cool features that you want, if you want to improve it or just view its source code, you can check it out at

There’s developers working on it 24 hours a day, we’ve got a great team here in California, we’ve got some people in Russia, I mean, 24 hours a day, someone is available to you.

And if you want to ask any questions about it, there is the web the Apple Developer Forums as well, in any of these sessions, and any of the labs.

So related sessions, definitely, because we just showed you extensions.

If you want to check out those videos when they go up, because they were earlier today, you can check those out.

And later today tomorrow, there is a session on off line storage.

Although we did not show it to you, there is a great panel in the Web Inspector for viewing client size storage information.

So if you go to that session, that may interest you.

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US