My name is James Robinson.
I'm an engineer on Google Chrome and I work
primarily on performance.
So WebKit is an open source project and a software library
that handles many of the functions of a web browser.
So it handles, for example, processing HTML, producing a
DOM, and providing many of the APIs that web developers use.
In itself, it is not a browser, but it's a key component of a
browser, and it's used in Google Chrome, Safari, Mobile
Safari, and many other browsers, including most of
the mobile web browsers.
So, WebKit can be thought of as a rendering engine.
And this means that it handles a specific set of tasks.
So one of the tasks it deals with is taking raw HTML and CSS
from the web and parsing them into a format that can then be
dealt with programmatically.
It also deals with issuing resource loads for all the
resources within a page that are needed, and it communicates
with a JavaScript engine to ensure that the script on
the page runs properly.
There's a few major things that the WebKit library
does not provide itself.
For example, it doesn't provide a networking library or a
graphics library, but it does handle the majority of
the tasks needed to develop a browser.
WebKit as an open source library is really a
global community.
There are contributors all over the world and they work from
many different countries.
So it's not unusual to have check-ins happening at 3:00 or
4:00 in the morning our time, because that might be the
middle of the afternoon somewhere else.
So you really get to work with a diverse group of people
from different backgrounds.
It's quite exciting.
WebKit is a very important part of Chrome's speed.
It's integral to displaying web pages and interacting
with web apps.
A large portion of the amount of time spent loading a page,
or displaying a page, or responding to a user action is
spent inside WebKit since it deals directly with a DOM and
the interactions between DOM and JavaScript.
So we closely monitor the performance of WebKit and
the performance of WebKit within Chrome to make sure
that things stay fast.
So the WebKit project, which existed well before Google got
involved, has always been monitoring its performance and
ensuring that as new features get added and code gets changed
around, that things don't get slower.
One of the main ways that this happens is with what are
called page load time tests.
And what they do is they load a sequence of pages in the
browser and then time how long it took for each page to
load up and display.
And these tests have proven very useful in making sure
that as new things get added, things don't get slower.
We also have a number of automated tests that are
designed to specifically target certain things.
So, we have a number of tests that deal with interactions
between the JavaScript and the DOM because it's very
important in any sort of dynamic web page.
And we use this to attempt to detect regressions and ensure
that when we do check-in optimizations, that they
really speed things up.
And then the worst form of regression testing is actually
users, but it's useful for Chrome since we have
the Dev channel.
So as we push new, maybe slightly untested builds out to
users, they will go out, try it on many web pages, and then
report back things that got slower.
And through that, it means we can pretty quickly detect that
we've broken something and go on and fix it.
And ideally, we'll add in automated tests to ensure that
we don't make that certain action slower any more.
One of the things that we've been working on with WebKit is
with interactions between WebKit and the other
libraries we have.
So one of the main ones is between WebKit and V8, which
is the JavaScript engine we use in Google Chrome.
Web applications will frequently run some JavaScript
code, which then calls into native code.
For example, they'll try to update some parts of the DOM or
change some styles around, and ensuring that those transitions
are very quick is an important part of our speed.
So a lot of work has gone into making sure that you can
quickly jump from the JavaScript engine to
the native code.
There's also work that has been done to ensure that you don't
end up losing too much time transferring certain
data types.
Some of the work that we're looking at now has to
do with scaling issues.
So when WebKit was initially written, the web happened
to be somewhat simpler.
Pages would be smaller, they'd have fewer images,
they'd have fewer texts.
But as the web develops and developers start pushing it in
different directions, things tend to get larger and
more complicated.
So, a web page nowadays might have a DOM that's maybe 10
times as large as the DOM would have been a few years ago.
And a lot of the pieces of code that worked fine when things
were a little bit simpler are now starting to have
some scaling issues.
So, one of the things we're working on is trying to
identify those issues where the initial code just doesn't quite
scale well and figure out ways to handle them a little
bit more gracefully.
One of the other things we're working on to improve
performance is to add new APIs that developers can use to make
richer web pages that are still very fast.
One example would be Workers, which let developers use
multi-threading techniques, and they allow a web page to do
more processing without blocking up the UI.
Another one is persistent storage APIs, which let web
applications store data on the client side without having to
constantly resync everything with the server.
And another one that's really exciting is new 3D APIs.
So this lets web developers build really exciting
interesting UIs without having to do tons and tons of 3D
processing in JavaScript.
And a lot of the work for APIs like this happens
in the WebKit layer.
A lot of these new features are in HTML5.
I believe Workers are in the HTML5 specification.
And there's a number of new APIs that aren't in the
particular specification called HTML5 but are in the general
category of new APIs.
So one of the interesting things about developing a new
API for the web is that once you do develop a new API for
the web, it tends to get used all over the web.
And so one of the challenges when developing these new APIs
is ensuring that you develop them in such a way that they'll
be interoperable across browsers and that you don't
make any mistakes that you live to regret later.
So when developing these new APIs, there's constant
communication with other browser vendors and with
application authors to see what sort of APIs they want and how
they can be implemented in a way that's efficient, both
for the implementer and for the applications.
One of the areas in WebKit that ends up often being a real
performance hotspot has to do with dealing with strings.
A lot of the resources that you download from the web are in
string form, all of your HTML, all of your CSS, all
of your JavaScript.
And in general, a large part of your data comes down as strings
from the web and then is handled internally in
JavaScript as a string.
And typically, these strings will be in different encodings
in different stages of the process.
So when downloading from the web, it's fairly common to
receive UTF-8 encoded strings.
But within WebKit, the HTML tokenizer and CSS parser and so
forth expect UTF-16 strings, whereas within the JavaScript
engine, strings might be represented as ASCII
or UTF-8 or UTF-16.
depending on the context.
So one of the performance optimizations that we've had to
make in several places has been ensuring that we do not
re-encode strings when we don't have to, and when we do
re-encode strings, we try to optimize for the common cases.
So one example has been a string that's in a general
encoding like UTF-8 or UTF-16 will often actually be
mostly ASCII, especially if it's JavaScript or CSS.
And so if we know that that's the common case, we can
optimize for that case and end up encoding the string
very quickly, if it actually is ASCII.
In some cases, we save whether or not the string in a general
format really is ASCII or not, because then we can do a very
quick string formatting pass.
And this has turned out to be a pretty big win on some pages.
Another area that ends up being a performance hotspot has
to do with repainting.
So WebKit will internally keep a representation of all of the
elements on the page, where they go, and then in what
order they should be painted.
And then when something changes on the page, say, an element
moves or some text is deleted, then some of the elements on
the page move and then they have to be repainted so that
the user can see the update.
So we're careful to only repaint the region of the
screen that's needed, ensuring that we don't
issue too many repaints.
So one of the cases that causes problems was if we issued
repaints for many regions of the screen that were
overlapping, then that would actually be slower than issuing
one repaint for the entire region.
So we have some logic to coalesce adjacent
paint rectangles.
Another issue has been with generating repaint rectangles
that are larger than the region of the screen
that actually changed.
So we've had to introduce a few checks to make sure that we
only issue a repaint for the smallest possible area that
could have actually changed.
And we have to be careful when doing these that we don't end
up underpainting, which means that we failed to repaint a
region of the screen that has changed.
But when we get this correct, it is actually a big
performance improvement.