Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" | 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 const base::TimeTicks& first_contentful_paint) { | 661 const base::TimeTicks& first_contentful_paint) { |
| 662 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 662 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 663 if (initialization_state_ != INITIALIZED) | 663 if (initialization_state_ != INITIALIZED) |
| 664 return; | 664 return; |
| 665 | 665 |
| 666 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id); | 666 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id); |
| 667 if (nav_it != inflight_navigations_.end()) | 667 if (nav_it != inflight_navigations_.end()) |
| 668 nav_it->second->first_contentful_paint = first_contentful_paint; | 668 nav_it->second->first_contentful_paint = first_contentful_paint; |
| 669 } | 669 } |
| 670 | 670 |
| 671 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url, | |
|
alexilin
2017/05/23 11:01:39
Why moving code?
| |
| 672 HintOrigin origin) { | |
| 673 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", | |
| 674 url.spec()); | |
| 675 // Save prefetch start time to report prefetching duration. | |
| 676 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() && | |
| 677 IsUrlPrefetchable(url)) { | |
| 678 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now())); | |
| 679 } | |
| 680 | |
| 681 if (!prefetch_manager_.get()) // Prefetching not enabled. | |
| 682 return; | |
| 683 if (!config_.IsPrefetchingEnabledForOrigin(profile_, origin)) | |
| 684 return; | |
| 685 | |
| 686 ResourcePrefetchPredictor::Prediction prediction; | |
| 687 if (!GetPrefetchData(url, &prediction)) | |
| 688 return; | |
| 689 | |
| 690 BrowserThread::PostTask( | |
| 691 BrowserThread::IO, FROM_HERE, | |
| 692 base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch, | |
| 693 prefetch_manager_, url, prediction.subresource_urls)); | |
| 694 | |
| 695 if (observer_) | |
| 696 observer_->OnPrefetchingStarted(url); | |
| 697 } | |
| 698 | |
| 699 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) { | |
| 700 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url", | |
| 701 url.spec()); | |
| 702 auto it = inflight_prefetches_.find(url); | |
| 703 if (it != inflight_prefetches_.end()) { | |
| 704 UMA_HISTOGRAM_TIMES( | |
| 705 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, | |
| 706 base::TimeTicks::Now() - it->second); | |
| 707 inflight_prefetches_.erase(it); | |
| 708 } | |
| 709 if (!prefetch_manager_.get()) // Not enabled. | |
| 710 return; | |
| 711 | |
| 712 BrowserThread::PostTask( | |
| 713 BrowserThread::IO, FROM_HERE, | |
| 714 base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch, | |
| 715 prefetch_manager_, url)); | |
| 716 | |
| 717 if (observer_) | |
| 718 observer_->OnPrefetchingStopped(url); | |
| 719 } | |
| 720 | |
| 721 void ResourcePrefetchPredictor::OnPrefetchingFinished( | 671 void ResourcePrefetchPredictor::OnPrefetchingFinished( |
| 722 const GURL& main_frame_url, | 672 const GURL& main_frame_url, |
| 723 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) { | 673 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) { |
| 724 if (observer_) | 674 if (observer_) |
| 725 observer_->OnPrefetchingFinished(main_frame_url); | 675 observer_->OnPrefetchingFinished(main_frame_url); |
| 726 | 676 |
| 727 prefetcher_stats_.insert(std::make_pair(main_frame_url, std::move(stats))); | 677 prefetcher_stats_.insert(std::make_pair(main_frame_url, std::move(stats))); |
| 728 } | 678 } |
| 729 | 679 |
| 730 bool ResourcePrefetchPredictor::IsUrlPrefetchable(const GURL& main_frame_url) { | 680 bool ResourcePrefetchPredictor::IsUrlPrefetchable( |
| 681 const GURL& main_frame_url) const { | |
| 731 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 682 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 732 if (initialization_state_ != INITIALIZED) | 683 if (initialization_state_ != INITIALIZED) |
| 733 return false; | 684 return false; |
| 734 | 685 |
| 735 return GetPrefetchData(main_frame_url, nullptr); | 686 return GetPrefetchData(main_frame_url, nullptr); |
| 736 } | 687 } |
| 737 | 688 |
| 738 bool ResourcePrefetchPredictor::IsResourcePrefetchable( | 689 bool ResourcePrefetchPredictor::IsResourcePrefetchable( |
| 739 const ResourceData& resource) const { | 690 const ResourceData& resource) const { |
| 740 float confidence = static_cast<float>(resource.number_of_hits()) / | 691 float confidence = static_cast<float>(resource.number_of_hits()) / |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 754 prefetch_manager_ = NULL; | 705 prefetch_manager_ = NULL; |
| 755 } | 706 } |
| 756 history_service_observer_.RemoveAll(); | 707 history_service_observer_.RemoveAll(); |
| 757 } | 708 } |
| 758 | 709 |
| 759 void ResourcePrefetchPredictor::OnMainFrameRequest( | 710 void ResourcePrefetchPredictor::OnMainFrameRequest( |
| 760 const URLRequestSummary& request) { | 711 const URLRequestSummary& request) { |
| 761 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 712 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 762 DCHECK_EQ(INITIALIZED, initialization_state_); | 713 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 763 | 714 |
| 764 const GURL& main_frame_url = request.navigation_id.main_frame_url; | |
| 765 StartPrefetching(main_frame_url, HintOrigin::NAVIGATION); | |
| 766 | |
| 767 CleanupAbandonedNavigations(request.navigation_id); | 715 CleanupAbandonedNavigations(request.navigation_id); |
| 768 | 716 |
| 769 // New empty navigation entry. | 717 // New empty navigation entry. |
| 770 inflight_navigations_.insert( | 718 const GURL& main_frame_url = request.navigation_id.main_frame_url; |
| 771 std::make_pair(request.navigation_id, | 719 inflight_navigations_.emplace( |
| 772 base::MakeUnique<PageRequestSummary>(main_frame_url))); | 720 request.navigation_id, |
| 721 base::MakeUnique<PageRequestSummary>(main_frame_url)); | |
| 773 } | 722 } |
| 774 | 723 |
| 775 void ResourcePrefetchPredictor::OnMainFrameResponse( | 724 void ResourcePrefetchPredictor::OnMainFrameResponse( |
| 776 const URLRequestSummary& response) { | 725 const URLRequestSummary& response) { |
| 777 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 726 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 778 DCHECK_EQ(INITIALIZED, initialization_state_); | 727 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 779 | 728 |
| 780 NavigationMap::iterator nav_it = | 729 auto nav_it = inflight_navigations_.find(response.navigation_id); |
| 781 inflight_navigations_.find(response.navigation_id); | |
| 782 if (nav_it != inflight_navigations_.end()) { | 730 if (nav_it != inflight_navigations_.end()) { |
| 783 // To match an URL in StartPrefetching(). | 731 // To match a URL in StartPrefetching(). |
| 784 StopPrefetching(nav_it->second->initial_url); | 732 StopPrefetching(nav_it->second->initial_url); |
|
alexilin
2017/05/23 11:01:39
Shouldn't we move StopPrefetching outside of Resou
Benoit L
2017/05/29 16:45:14
The unfortunate part is that without navigation tr
alexilin
2017/05/30 11:55:27
Answered in other comment.
TL;DR
Expose navigation
| |
| 785 } else { | 733 } else { |
| 786 StopPrefetching(response.navigation_id.main_frame_url); | 734 StopPrefetching(response.navigation_id.main_frame_url); |
| 787 } | 735 } |
| 788 } | 736 } |
| 789 | 737 |
| 790 void ResourcePrefetchPredictor::OnMainFrameRedirect( | 738 void ResourcePrefetchPredictor::OnMainFrameRedirect( |
| 791 const URLRequestSummary& response) { | 739 const URLRequestSummary& response) { |
| 792 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 740 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 793 DCHECK_EQ(INITIALIZED, initialization_state_); | 741 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 794 | 742 |
| (...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1838 if (!history_service) | 1786 if (!history_service) |
| 1839 return; | 1787 return; |
| 1840 DCHECK(!history_service_observer_.IsObserving(history_service)); | 1788 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 1841 history_service_observer_.Add(history_service); | 1789 history_service_observer_.Add(history_service); |
| 1842 if (history_service->BackendLoaded()) { | 1790 if (history_service->BackendLoaded()) { |
| 1843 // HistoryService is already loaded. Continue with Initialization. | 1791 // HistoryService is already loaded. Continue with Initialization. |
| 1844 OnHistoryAndCacheLoaded(); | 1792 OnHistoryAndCacheLoaded(); |
| 1845 } | 1793 } |
| 1846 } | 1794 } |
| 1847 | 1795 |
| 1796 bool ResourcePrefetchPredictor::CanPrefetchUrlForOrigin( | |
| 1797 const GURL& url, | |
| 1798 HintOrigin origin) const { | |
| 1799 return prefetch_manager_.get() && // Prefetching not enabled. | |
| 1800 config_.IsPrefetchingEnabledForOrigin(profile_, origin) && | |
|
alexilin
2017/05/23 11:01:38
I think the second condition is always true if the
Benoit L
2017/05/29 16:45:14
Nope, the first one is true if prefetching is enab
alexilin
2017/05/30 11:55:27
Yup, you're right.
The following paragraph is jus
| |
| 1801 IsUrlPrefetchable(url); | |
|
alexilin
2017/05/23 11:01:39
TODO:
Look at the cost of IsUrlPrefetchable() meth
| |
| 1802 } | |
| 1803 | |
| 1804 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url, | |
| 1805 HintOrigin origin) { | |
| 1806 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", | |
| 1807 url.spec()); | |
| 1808 DCHECK(CanPrefetchUrlForOrigin(url, origin)); | |
| 1809 | |
| 1810 // Save prefetch start time to report prefetching duration. | |
| 1811 if (inflight_prefetches_.find(url) == inflight_prefetches_.end()) | |
| 1812 inflight_prefetches_.emplace(url, base::TimeTicks::Now()); | |
| 1813 | |
| 1814 ResourcePrefetchPredictor::Prediction prediction; | |
| 1815 bool has_data = GetPrefetchData(url, &prediction); | |
| 1816 DCHECK(has_data); | |
| 1817 | |
| 1818 BrowserThread::PostTask( | |
| 1819 BrowserThread::IO, FROM_HERE, | |
| 1820 base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch, | |
| 1821 prefetch_manager_, url, prediction.subresource_urls)); | |
| 1822 | |
| 1823 if (observer_) | |
| 1824 observer_->OnPrefetchingStarted(url); | |
| 1825 } | |
| 1826 | |
| 1827 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) { | |
| 1828 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url", | |
| 1829 url.spec()); | |
| 1830 auto it = inflight_prefetches_.find(url); | |
| 1831 if (it != inflight_prefetches_.end()) { | |
| 1832 UMA_HISTOGRAM_TIMES( | |
| 1833 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, | |
| 1834 base::TimeTicks::Now() - it->second); | |
| 1835 inflight_prefetches_.erase(it); | |
| 1836 } | |
| 1837 if (!prefetch_manager_.get()) // Not enabled. | |
| 1838 return; | |
| 1839 | |
| 1840 BrowserThread::PostTask( | |
| 1841 BrowserThread::IO, FROM_HERE, | |
| 1842 base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch, | |
| 1843 prefetch_manager_, url)); | |
| 1844 | |
| 1845 if (observer_) | |
| 1846 observer_->OnPrefetchingStopped(url); | |
| 1847 } | |
| 1848 | |
| 1848 //////////////////////////////////////////////////////////////////////////////// | 1849 //////////////////////////////////////////////////////////////////////////////// |
| 1849 // TestObserver. | 1850 // TestObserver. |
| 1850 | 1851 |
| 1851 TestObserver::~TestObserver() { | 1852 TestObserver::~TestObserver() { |
| 1852 predictor_->SetObserverForTesting(nullptr); | 1853 predictor_->SetObserverForTesting(nullptr); |
| 1853 } | 1854 } |
| 1854 | 1855 |
| 1855 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) | 1856 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) |
| 1856 : predictor_(predictor) { | 1857 : predictor_(predictor) { |
| 1857 predictor_->SetObserverForTesting(this); | 1858 predictor_->SetObserverForTesting(this); |
| 1858 } | 1859 } |
| 1859 | 1860 |
| 1860 } // namespace predictors | 1861 } // namespace predictors |
| OLD | NEW |