Chromium Code Reviews| Index: third_party/WebKit/Source/core/loader/ProgressTracker.cpp |
| diff --git a/third_party/WebKit/Source/core/loader/ProgressTracker.cpp b/third_party/WebKit/Source/core/loader/ProgressTracker.cpp |
| index 7b88633f67640380684c012534cec9830f740026..96ffb4d79a56e0ca2e148c3f98328773bb0e4ef5 100644 |
| --- a/third_party/WebKit/Source/core/loader/ProgressTracker.cpp |
| +++ b/third_party/WebKit/Source/core/loader/ProgressTracker.cpp |
| @@ -25,6 +25,7 @@ |
| #include "core/loader/ProgressTracker.h" |
| +#include "core/fetch/Resource.h" |
| #include "core/fetch/ResourceFetcher.h" |
| #include "core/frame/FrameView.h" |
| #include "core/frame/LocalFrame.h" |
| @@ -46,11 +47,7 @@ namespace blink { |
| // soon as a load starts. |
| static const double initialProgressValue = 0.1; |
| -// Similarly, always leave space at the end. This helps show the user that we're not done |
| -// until we're done. |
| -static const double finalProgressValue = 0.9; // 1.0 - initialProgressValue |
| - |
| -static const int progressItemDefaultEstimatedLength = 1024 * 1024; |
| +static const int progressItemDefaultEstimatedLength = 128 * 1024; |
| struct ProgressItem { |
| WTF_MAKE_NONCOPYABLE(ProgressItem); USING_FAST_MALLOC(ProgressItem); |
| @@ -70,15 +67,14 @@ RawPtr<ProgressTracker> ProgressTracker::create(LocalFrame* frame) |
| ProgressTracker::ProgressTracker(LocalFrame* frame) |
| : m_frame(frame) |
| - , m_mainResourceIdentifier(0) |
| - , m_totalPageAndResourceBytesToLoad(0) |
| - , m_totalBytesReceived(0) |
| , m_lastNotifiedProgressValue(0) |
| , m_lastNotifiedProgressTime(0) |
| , m_progressNotificationInterval(0.02) |
| , m_progressNotificationTimeInterval(0.1) |
| + , m_finishedParsing(false) |
| , m_finalProgressChangedSent(false) |
| , m_progressValue(0) |
| + , m_bytesLoadedSoFar(0) |
| { |
| } |
| @@ -106,13 +102,14 @@ double ProgressTracker::estimatedProgress() const |
| void ProgressTracker::reset() |
| { |
| m_progressItems.clear(); |
| - |
| - m_totalPageAndResourceBytesToLoad = 0; |
| - m_totalBytesReceived = 0; |
| m_progressValue = 0; |
| m_lastNotifiedProgressValue = 0; |
| m_lastNotifiedProgressTime = 0; |
| m_finalProgressChangedSent = false; |
| + m_finishedParsing = false; |
| + m_bytesLoadedSoFar = 0; |
| + m_progressUpdate.clear(); |
| + m_bytesSoFarUpdate.clear(); |
| } |
| void ProgressTracker::progressStarted() |
| @@ -138,128 +135,103 @@ void ProgressTracker::progressCompleted() |
| void ProgressTracker::finishedParsing() |
| { |
| - if (m_frame->settings()->mainResourceOnlyProgress()) |
| - sendFinalProgress(); |
| + m_finishedParsing = true; |
| + maybeSendProgress(); |
| } |
| void ProgressTracker::sendFinalProgress() |
| { |
| if (!m_finalProgressChangedSent) { |
| + m_finalProgressChangedSent = true; |
| m_progressValue = 1; |
| m_frame->loader().client()->progressEstimateChanged(m_progressValue); |
| } |
| } |
| -void ProgressTracker::incrementProgress(unsigned long identifier, const ResourceResponse& response) |
| +static bool isParserBlockingOrImage(Resource::Type type) |
| +{ |
| + return type == Resource::MainResource || type == Resource::Image || type == Resource::CSSStyleSheet || type == Resource::Script || type == Resource::XSLStyleSheet; |
|
paulirish
2016/04/07 21:42:30
Mentioned this offline already,
but I think you'l
|
| +} |
| + |
| +void ProgressTracker::willSendRequest(const Resource* resource) |
| { |
| if (!m_frame->isLoading()) |
| return; |
| + if (m_finishedParsing || !isParserBlockingOrImage(resource->getType())) |
| + return; |
| + ASSERT(!m_progressItems.get(resource->identifier())); |
| + m_progressItems.set(resource->identifier(), adoptPtr(new ProgressItem(progressItemDefaultEstimatedLength))); |
| +} |
| - if (m_frame->loader().provisionalDocumentLoader() && m_frame->loader().provisionalDocumentLoader()->mainResourceIdentifier() == identifier) |
| - m_mainResourceIdentifier = identifier; |
| +void ProgressTracker::incrementProgress(unsigned long identifier, const ResourceResponse& response) |
| +{ |
| + ProgressItem* item = m_progressItems.get(identifier); |
| + if (!item) |
| + return; |
| long long estimatedLength = response.expectedContentLength(); |
| if (estimatedLength < 0) |
| estimatedLength = progressItemDefaultEstimatedLength; |
| - |
| - m_totalPageAndResourceBytesToLoad += estimatedLength; |
| - |
| - if (ProgressItem* item = m_progressItems.get(identifier)) { |
| - item->bytesReceived = 0; |
| - item->estimatedLength = estimatedLength; |
| - } else { |
| - m_progressItems.set(identifier, adoptPtr(new ProgressItem(estimatedLength))); |
| - } |
| + item->bytesReceived = 0; |
| + item->estimatedLength = estimatedLength; |
| } |
| -void ProgressTracker::incrementProgressForMainResourceOnly(unsigned long identifier, int length) |
| +void ProgressTracker::incrementProgress(unsigned long identifier, int length) |
| { |
| - if (identifier != m_mainResourceIdentifier) |
| - return; |
| - |
| ProgressItem* item = m_progressItems.get(identifier); |
| + |
| + // FIXME: Can this ever happen? |
| if (!item) |
| return; |
| - |
| item->bytesReceived += length; |
| + m_bytesLoadedSoFar += length; |
| if (item->bytesReceived > item->estimatedLength) |
| - item->estimatedLength *= 2; |
| - double newProgress = initialProgressValue + 0.1; // +0.1 for committing |
| - if (m_frame->view()->didFirstLayout()) |
| - newProgress += 0.2; |
| - // 0.4 possible so far, allow 0.5 from bytes loaded, for a max of 0.9. |
| - newProgress += ((double) item->bytesReceived / (double) item->estimatedLength) / 2; |
| - |
| - if (newProgress < m_progressValue) |
| - return; |
| - |
| - m_progressValue = newProgress; |
| - double now = currentTime(); |
| - double notifiedProgressTimeDelta = now - m_lastNotifiedProgressTime; |
| - |
| - double notificationProgressDelta = m_progressValue - m_lastNotifiedProgressValue; |
| - if (notificationProgressDelta < m_progressNotificationInterval && notifiedProgressTimeDelta < m_progressNotificationTimeInterval) |
| - return; |
| - m_frame->loader().client()->progressEstimateChanged(m_progressValue); |
| - m_lastNotifiedProgressValue = m_progressValue; |
| - m_lastNotifiedProgressTime = now; |
| + item->estimatedLength = item->bytesReceived * 2; |
| + maybeSendProgress(); |
| } |
| -void ProgressTracker::incrementProgress(unsigned long identifier, int length) |
| +void ProgressTracker::maybeSendProgress() |
| { |
| - if (m_frame->settings()->mainResourceOnlyProgress()) { |
| - incrementProgressForMainResourceOnly(identifier, length); |
| - return; |
| + m_progressValue = initialProgressValue + 0.1; // +0.1 for committing |
| + if (m_finishedParsing) |
| + m_progressValue += 0.2; |
| + |
| + long long bytesReceived = 0; |
| + long long estimatedBytesForPendingRequests = 0; |
| + for (const auto& progressItem : m_progressItems) { |
| + bytesReceived += progressItem.value->bytesReceived; |
| + estimatedBytesForPendingRequests += progressItem.value->estimatedLength; |
| } |
| + ASSERT(estimatedBytesForPendingRequests >= 0); |
| + ASSERT(estimatedBytesForPendingRequests >= bytesReceived); |
| - ProgressItem* item = m_progressItems.get(identifier); |
| - |
| - // FIXME: Can this ever happen? |
| - if (!item) |
| + if (m_finishedParsing && estimatedBytesForPendingRequests == bytesReceived) { |
| + sendFinalProgress(); |
| return; |
| - |
| - unsigned bytesReceived = length; |
| - double increment, percentOfRemainingBytes; |
| - long long remainingBytes, estimatedBytesForPendingRequests; |
| - |
| - item->bytesReceived += bytesReceived; |
| - if (item->bytesReceived > item->estimatedLength) { |
| - m_totalPageAndResourceBytesToLoad += ((item->bytesReceived * 2) - item->estimatedLength); |
| - item->estimatedLength = item->bytesReceived * 2; |
| } |
| - int numPendingOrLoadingRequests = m_frame->document()->fetcher()->requestCount(); |
| - estimatedBytesForPendingRequests = progressItemDefaultEstimatedLength * numPendingOrLoadingRequests; |
| - remainingBytes = ((m_totalPageAndResourceBytesToLoad + estimatedBytesForPendingRequests) - m_totalBytesReceived); |
| - if (remainingBytes > 0) // Prevent divide by 0. |
| - percentOfRemainingBytes = (double)bytesReceived / (double)remainingBytes; |
| - else |
| - percentOfRemainingBytes = 1.0; |
| - |
| - // For documents that use WebCore's layout system, treat first layout as the half-way point. |
| - bool useClampedMaxProgress = !m_frame->view()->didFirstLayout(); |
| - double maxProgressValue = useClampedMaxProgress ? 0.5 : finalProgressValue; |
| - increment = (maxProgressValue - m_progressValue) * percentOfRemainingBytes; |
| - m_progressValue += increment; |
| - m_progressValue = min(m_progressValue, maxProgressValue); |
| - ASSERT(m_progressValue >= initialProgressValue); |
| + double percentOfBytesReceived = !estimatedBytesForPendingRequests ? 1.0 : |
| + (double)bytesReceived / (double)estimatedBytesForPendingRequests; |
| + m_progressValue += percentOfBytesReceived / 2; |
| - m_totalBytesReceived += bytesReceived; |
| + ASSERT(m_progressValue >= initialProgressValue); |
| + // Always leave space at the end. This helps show the user that we're not |
| + // done until we're done. |
| + ASSERT(m_progressValue <= 0.9); |
| + if (m_progressValue < m_lastNotifiedProgressValue) |
| + return; |
| double now = currentTime(); |
| double notifiedProgressTimeDelta = now - m_lastNotifiedProgressTime; |
| double notificationProgressDelta = m_progressValue - m_lastNotifiedProgressValue; |
| if (notificationProgressDelta >= m_progressNotificationInterval || notifiedProgressTimeDelta >= m_progressNotificationTimeInterval) { |
| - if (!m_finalProgressChangedSent) { |
| - if (m_progressValue == 1) |
| - m_finalProgressChangedSent = true; |
| - |
| - m_frame->loader().client()->progressEstimateChanged(m_progressValue); |
| - |
| - m_lastNotifiedProgressValue = m_progressValue; |
| - m_lastNotifiedProgressTime = now; |
| - } |
| + ASSERT(!m_finalProgressChangedSent); |
| + m_frame->loader().client()->progressEstimateChanged(m_progressValue); |
| + m_lastNotifiedProgressValue = m_progressValue; |
| + m_lastNotifiedProgressTime = now; |
| + m_progressUpdate.append(m_progressValue); |
| + m_bytesSoFarUpdate.append(m_bytesLoadedSoFar); |
| } |
| } |
| @@ -271,11 +243,8 @@ void ProgressTracker::completeProgress(unsigned long identifier) |
| if (!item) |
| return; |
| - // Adjust the total expected bytes to account for any overage/underage. |
| - long long delta = item->bytesReceived - item->estimatedLength; |
| - m_totalPageAndResourceBytesToLoad += delta; |
| - |
| - m_progressItems.remove(identifier); |
| + item->estimatedLength = item->bytesReceived; |
| + maybeSendProgress(); |
| } |
| } // namespace blink |