Transcript
>> 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, document.body.style, 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 document.body.style,
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 document.nonexistent.bar
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.
contentwindow.immediatelyShowNextTweet.
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 apple.com 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, apple.com.
The top resource, the largest latency,
came from metrics.apple.com.
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 apple.com.
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 apple.com, 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 webkit.org.
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.