I/O in Google Chrome

Wednesday, October 08, 2008

One of our early goals for Google Chrome was to make the browser as fast as we possibly could. But in addition to raw speed, we wanted it to be highly responsive. After all, it doesn't matter how fast pages can be loaded if the user interface is locked up!

To understand our holistic approach to performance in Google Chrome, it helps to know some background. Processing speed per dollar has rapidly increased over the last 40 years, but hard drives, which are based on moving parts, do not improve nearly as fast. As a result, a modern processor can execute millions of instructions in the same time that it takes to read just one byte off disk. We knew that building a fast, responsive browser for modern systems would require extra attention to disk I/O usage.

Developers are ideal testers for I/O performance since the load of compiling a very large application like Google Chrome will bog down even the most powerful system. This soon led us to a rule that the main thread of Google Chrome—the thread that runs the entire user interface—is not allowed to do any I/O. After fixing the obvious cases, we ran a program that thrashes the disk while we profiled common operations in Google Chrome to find latent I/O hotspots. We even ran a test where we removed the privileges of the main thread to read or write to disk, and made sure that nothing stopped working.

We moved the I/O onto a number of background threads which allow the user-interface to proceed asynchronously. We did this for large data sources like cookies, bookmarks, and the cache, and also for a myriad of smaller things. Writing a downloaded file to disk, or getting the icons for files in the download manager? The disk operations are being called from a special background thread. Indexing the contents of pages in history or saving a login password? All from background threads. Even the "Save As" dialog box is run from another thread because it can momentarily hang the application while it populates.

Startup poses a different type of problem. If all the subsystems simultaneously requested their data on startup, even if it was from different threads, the requests would quickly overwhelm the disk. As a result, we delay loading as much data as possible for as long as possible, so the most important work can get done first.

Our startup sequence works like this: First chrome.exe and chrome.dll are loaded. Then the preferences file is loaded (it may affect how things proceed). Then we immediately display the main window. The user now can interact with the UI and feels like Google Chrome has loaded, even though there has been remarkably little work done. Immediately after showing the window, we create the sub-process for rendering the first tab. Only once this process has loaded do subsystems like bookmarks proceed, since any I/O contention would slow down the display of that first tab (this is why you may see things like your bookmarks appear after a slight delay). The cache, cookies, and the Windows networking libraries are not loaded until even later when the first network request is issued.

We carefully monitor startup performance using an automated test that runs for almost every change to the code. This test was created very early in the project, when Google Chrome did almost nothing, and we have always followed a very simple rule: this test can never get any slower. Because it's much easier to address performance problems as they are created than fixing them later, we are quick to fix or revert any regressions. As a result, our very large application starts as fast today as the very lightweight application we started out with.

Our work on I/O performance sometimes complicates the code because so many operations have to be designed to be asynchronous: managing requests on different threads with data that comes in at different times is a lot of extra work. But we think it has been well worth it to help us achieve our goal of making Google Chrome not only the fastest, but the most responsive browser we could build.

17 comments:

kirill said...

I find that flash locks up chrome quite often... It's always a pain to watch youtube or any other video and opening more than one tab with flash almost guarantees to lock up browser for a minute or two.

loganb said...

Given that the Chrome is almost certainly going to load a page originating on the network in the opening tab, why do you consider it better for the user to feel the latency hit of loading the network stack after the browser window is open? If you load it during user actions, the browser (possibly entire system) will feel sluggish while components are loaded. Alternatively, loading resources ahead of time that will immediately get used upon startup will make the application feel more responsive albeit with a slightly longer load time. Is there some data that shows that users perceive one as faster than the other?

MK said...

I am eternally grateful to you guys for making startup speed a priority in Chrome. I really consider it one of Chrome's killer features over Firefox. Perhaps understandably, Mozilla has never put much emphasis on fast cold-starts, resulting in (what feels like) longer launch times with each new version.

The only big show-stopper left on my end is some mouse-scroll bugs, which I hear might've been fixed. Looking forward to the next release!

Ondrej Brablc said...

Try running Chrome in portable mode from a U3 enabled USB flash drive.

It is even slower than FF3. I guess you suffer from the same sqlite fsync problems as FF3 is just solving.

anonymous said...

Can you make it when you type in the address bar that you can tab through the selections?

Brett Wilson said...

kirill regarding plugin hangs: I'll talk about this in the next post (hopefully).

loganb regarding network starting: It looks like we load the WinHTTP dll earlier than the first network request, but I'm not sure why. There is still some stuff like the cache that isn't loaded until the first network request. I think we should consider loading some things more aggressively as soon as we're idle (which will be after the new tab page has shown completely) which would make it slightly faster when the first request comes in.

ondrej brablc regarding slowness on flash drives: We shouldn't be blocking the UI on sqlite fsyncs, but there could be other stuff going on. This sounds like an interesting test, I haven't tried it yet.

-Brett

sinm said...

No need for bookmarks, history, flash or even first tab rendering until i've got my omnibar for interaction with the web

RichB said...

> Even the "Save As" dialog box is run from another thread because it
> can momentarily hang the application while it populates.

Doesn't it need to be on the main STA thread for Copy/Paste (COM/OLE) to work?

Luc VN said...

Brett, Thanks for all this useful info !!!

Darky said...

I have to say you guys have surely delivered in raw speed, but have majorly failed in responsive-ness. The cold start time between clicking app launch to the UI showing up is indeed very fast, but it needs to wait a lot longer before the UI becomes responsive. Also the tabs often hang up each other, usually a loading tab in the background will hang up the currently viewing tab, prompting the browser to ask to close the currently viewing tab, not the loading tab, thus not getting to the problem correctly.

In terms of responsive-ness, currently it's Opera > Firefox >>> Chrome > IE8.

froobly said...

I find that a huge problem with the responsiveness in Chrome comes from the fact that each tab is its own process. When you close a tab, I/O generally hangs for a few seconds while it's waiting for the process to finish. Particularly, the close->change tab sequence is especially slow. In other browsers, when something locks up like this, you at least have a disk thrashing noise telling you there's a good reason for it. In Chrome, it just hangs there silently for several seconds, leaving you wondering if there's a deadlock.

"Pray For Me Brother" ...Rockzzz said...

Guys,
Please refer the link for the solution(Not all but most of them had the problem solved)

http://groups.google.com/group/google-chrome-help-troubleshooting/browse_thread/thread/2c1642dc143dab84/4bbf11e18cc42979?hl=en&

Samuel said...

How to automate Chrome to test web apps?

brainturl said...

Sorry bro not a solution, but you can reach chrome help to know more on chrome automation.

Frågarn said...

Can I change what command I want to use to change tab?
For e.g now it's Ctrl+tab but if I wanna change tab to left with 1 and right with 2 how can I change that?

Salvatore said...

I miss the Home button

Bay area shirts said...

I have been reading up on the under the hood I/O performance of Google Chrome and I came across some very interesting tidbits.
Hard Drive Recovery