I created a relatively large spreadsheet on this page: http://spreadsheets.google.com/ccc?key=pKH_GaQ9XjP781vNySuYzcA&hl=en If you edit one of the top elements, like interest rate, it takes Chrome/Safari about 6s to finish updating. Firefox completes the update in about 2s. The Wireshark trace shows that all of the new data is back from the server in about 1.5s. The rest of the time Chrome/Safari is busy updating the view.
An example callstack: 0.0% 96.0% WebCore WebCore::XMLHttpRequest::didFinishLoading(WebCore::SubresourceLoader*) 0.0% 96.0% WebCore WebCore::XMLHttpRequest::callReadyStateChangeListener() 0.0% 96.0% WebCore WebCore::XMLHttpRequest::dispatchReadyStateChangeEvent() 0.0% 96.0% WebCore WebCore::JSAbstractEventListener::handleEvent(WebCore::Event*, bool) 0.0% 96.0% JavaScriptCore KJS::JSFunction::call(KJS::ExecState*, KJS::JSValue*, KJS::ArgList const&) 0.0% 96.0% JavaScriptCore KJS::Machine::execute(KJS::FunctionBodyNode*, KJS::ExecState*, KJS::JSFunction*, KJS::JSObject*, KJS::ArgList const&, KJS::ScopeChainNode*, KJS::JSValue**) 0.0% 96.0% JavaScriptCore KJS::Machine::privateExecute(KJS::Machine::ExecutionFlag, KJS::ExecState*, KJS::RegisterFile*, KJS::Register*, KJS::ScopeChainNode*, KJS::CodeBlock*, KJS::JSValue**) 0.0% 96.0% JavaScriptCore KJS::functionProtoFuncApply(KJS::ExecState*, KJS::JSObject*, KJS::JSValue*, KJS::ArgList const&) 0.0% 96.0% JavaScriptCore KJS::JSFunction::call(KJS::ExecState*, KJS::JSValue*, KJS::ArgList const&) 0.0% 96.0% JavaScriptCore KJS::Machine::execute(KJS::FunctionBodyNode*, KJS::ExecState*, KJS::JSFunction*, KJS::JSObject*, KJS::ArgList const&, KJS::ScopeChainNode*, KJS::JSValue**) 0.0% 96.0% JavaScriptCore KJS::Machine::privateExecute(KJS::Machine::ExecutionFlag, KJS::ExecState*, KJS::RegisterFile*, KJS::Register*, KJS::ScopeChainNode*, KJS::CodeBlock*, KJS::JSValue**) 0.0% 96.0% JavaScriptCore KJS::functionProtoFuncCall(KJS::ExecState*, KJS::JSObject*, KJS::JSValue*, KJS::ArgList const&) 0.0% 96.0% JavaScriptCore KJS::JSFunction::call(KJS::ExecState*, KJS::JSValue*, KJS::ArgList const&) 0.0% 96.0% JavaScriptCore KJS::Machine::execute(KJS::FunctionBodyNode*, KJS::ExecState*, KJS::JSFunction*, KJS::JSObject*, KJS::ArgList const&, KJS::ScopeChainNode*, KJS::JSValue**) 0.0% 96.0% JavaScriptCore KJS::Machine::privateExecute(KJS::Machine::ExecutionFlag, KJS::ExecState*, KJS::RegisterFile*, KJS::Register*, KJS::ScopeChainNode*, KJS::CodeBlock*, KJS::JSValue**) 0.0% 96.0% JavaScriptCore KJS::functionProtoFuncCall(KJS::ExecState*, KJS::JSObject*, KJS::JSValue*, KJS::ArgList const&) 0.0% 96.0% JavaScriptCore KJS::JSFunction::call(KJS::ExecState*, KJS::JSValue*, KJS::ArgList const&) 0.0% 96.0% JavaScriptCore KJS::Machine::execute(KJS::FunctionBodyNode*, KJS::ExecState*, KJS::JSFunction*, KJS::JSObject*, KJS::ArgList const&, KJS::ScopeChainNode*, KJS::JSValue**) 0.3% 96.0% JavaScriptCore KJS::Machine::privateExecute(KJS::Machine::ExecutionFlag, KJS::ExecState*, KJS::RegisterFile*, KJS::Register*, KJS::ScopeChainNode*, KJS::CodeBlock*, KJS::JSValue**) 0.0% 93.9% WebCore WebCore::JSElement::getValueProperty(KJS::ExecState*, int) const 0.0% 93.9% WebCore WebCore::Element::offsetHeight() 0.0% 93.9% WebCore WebCore::Document::updateLayoutIgnorePendingStylesheets() 0.0% 93.8% WebCore WebCore::Document::updateLayout() 0.0% 93.3% WebCore WebCore::FrameView::layout(bool) 0.0% 89.5% WebCore WebCore::RenderLayer::updateLayerPositions(bool, bool) 0.1% 89.5% WebCore WebCore::RenderLayer::updateLayerPositions(bool, bool) 0.7% 89.2% WebCore WebCore::RenderLayer::updateLayerPositions(bool, bool) 0.7% 38.6% WebCore WebCore::RenderObject::repaintAfterLayoutIfNeeded(WebCore::IntRect const&, WebCore::IntRect const&) 1.5% 24.6% WebCore WebCore::RenderTableCell::absoluteClippedOverflowRect() 0.5% 9.5% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.5% 8.9% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.5% 8.1% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.7% 7.3% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.5% 5.8% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.5% 5.1% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.8% 4.2% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.5% 2.9% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.3% 1.9% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.5% 1.2% WebCore WebCore::RenderBox::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.1% 0.3% WebCore WebCore::RenderView::computeAbsoluteRepaintRect(WebCore::IntRect&, bool) 0.2% 0.2% WebCore WebCore::RenderView::printing() const
All our time seems to be in table layout code
I tried this with the latest Development version of Chrome, and Chrome refreshes the page 1 or 2s now, so apparently someone addressed the underlying issue, or google changed the spreadhsheet application to not hit this case.