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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 void ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(bool state) { | 410 void ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(bool state) { |
411 g_allow_port_in_urls = state; | 411 g_allow_port_in_urls = state; |
412 } | 412 } |
413 | 413 |
414 //////////////////////////////////////////////////////////////////////////////// | 414 //////////////////////////////////////////////////////////////////////////////// |
415 // ResourcePrefetchPredictor nested types. | 415 // ResourcePrefetchPredictor nested types. |
416 | 416 |
417 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() | 417 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() |
418 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), | 418 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), |
419 priority(net::IDLE), | 419 priority(net::IDLE), |
420 response_time(base::TimeTicks()), | |
421 before_first_contentful_paint(false), | |
420 was_cached(false), | 422 was_cached(false), |
421 has_validators(false), | 423 has_validators(false), |
422 always_revalidate(false) {} | 424 always_revalidate(false) {} |
423 | 425 |
424 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( | 426 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( |
425 const URLRequestSummary& other) | 427 const URLRequestSummary& other) |
426 : navigation_id(other.navigation_id), | 428 : navigation_id(other.navigation_id), |
427 resource_url(other.resource_url), | 429 resource_url(other.resource_url), |
428 resource_type(other.resource_type), | 430 resource_type(other.resource_type), |
429 priority(other.priority), | 431 priority(other.priority), |
432 response_time(other.response_time), | |
433 before_first_contentful_paint(other.before_first_contentful_paint), | |
430 mime_type(other.mime_type), | 434 mime_type(other.mime_type), |
431 was_cached(other.was_cached), | 435 was_cached(other.was_cached), |
432 redirect_url(other.redirect_url), | 436 redirect_url(other.redirect_url), |
433 has_validators(other.has_validators), | 437 has_validators(other.has_validators), |
434 always_revalidate(other.always_revalidate) {} | 438 always_revalidate(other.always_revalidate) {} |
435 | 439 |
436 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { | 440 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { |
437 } | 441 } |
438 | 442 |
439 // static | 443 // static |
440 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( | 444 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( |
441 const net::URLRequest& request, | 445 const net::URLRequest& request, |
442 URLRequestSummary* summary) { | 446 URLRequestSummary* summary) { |
443 const content::ResourceRequestInfo* request_info = | 447 const content::ResourceRequestInfo* request_info = |
444 content::ResourceRequestInfo::ForRequest(&request); | 448 content::ResourceRequestInfo::ForRequest(&request); |
445 if (!request_info) | 449 if (!request_info) |
446 return false; | 450 return false; |
447 | 451 |
452 summary->response_time = base::TimeTicks::Now(); | |
448 summary->resource_url = request.original_url(); | 453 summary->resource_url = request.original_url(); |
449 content::ResourceType resource_type_from_request = | 454 content::ResourceType resource_type_from_request = |
450 request_info->GetResourceType(); | 455 request_info->GetResourceType(); |
451 summary->priority = request.priority(); | 456 summary->priority = request.priority(); |
452 request.GetMimeType(&summary->mime_type); | 457 request.GetMimeType(&summary->mime_type); |
453 summary->was_cached = request.was_cached(); | 458 summary->was_cached = request.was_cached(); |
454 summary->resource_type = | 459 summary->resource_type = |
455 GetResourceType(resource_type_from_request, summary->mime_type); | 460 GetResourceType(resource_type_from_request, summary->mime_type); |
456 | 461 |
457 scoped_refptr<net::HttpResponseHeaders> headers = | 462 scoped_refptr<net::HttpResponseHeaders> headers = |
458 request.response_info().headers; | 463 request.response_info().headers; |
459 if (headers.get()) { | 464 if (headers.get()) { |
460 summary->has_validators = headers->HasValidators(); | 465 summary->has_validators = headers->HasValidators(); |
461 // RFC 2616, section 14.9. | 466 // RFC 2616, section 14.9. |
462 summary->always_revalidate = | 467 summary->always_revalidate = |
463 headers->HasHeaderValue("cache-control", "no-cache") || | 468 headers->HasHeaderValue("cache-control", "no-cache") || |
464 headers->HasHeaderValue("pragma", "no-cache") || | 469 headers->HasHeaderValue("pragma", "no-cache") || |
465 headers->HasHeaderValue("vary", "*"); | 470 headers->HasHeaderValue("vary", "*"); |
466 } | 471 } |
467 return true; | 472 return true; |
468 } | 473 } |
469 | 474 |
470 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( | 475 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( |
471 const GURL& i_main_frame_url) | 476 const GURL& i_main_frame_url) |
472 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {} | 477 : main_frame_url(i_main_frame_url), |
478 initial_url(i_main_frame_url), | |
479 first_contentful_paint(base::TimeTicks::Max()) {} | |
473 | 480 |
474 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( | 481 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( |
475 const PageRequestSummary& other) = default; | 482 const PageRequestSummary& other) = default; |
476 | 483 |
477 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {} | 484 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {} |
478 | 485 |
479 ResourcePrefetchPredictor::Prediction::Prediction() = default; | 486 ResourcePrefetchPredictor::Prediction::Prediction() = default; |
480 | 487 |
481 ResourcePrefetchPredictor::Prediction::Prediction( | 488 ResourcePrefetchPredictor::Prediction::Prediction( |
482 const ResourcePrefetchPredictor::Prediction& other) = default; | 489 const ResourcePrefetchPredictor::Prediction& other) = default; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
584 // corresponding to the navigation has not been created yet. | 591 // corresponding to the navigation has not been created yet. |
585 if (!navigation_id.main_frame_url.is_empty()) | 592 if (!navigation_id.main_frame_url.is_empty()) |
586 OnNavigationComplete(navigation_id); | 593 OnNavigationComplete(navigation_id); |
587 break; | 594 break; |
588 default: | 595 default: |
589 NOTREACHED() << "Unexpected initialization_state_: " | 596 NOTREACHED() << "Unexpected initialization_state_: " |
590 << initialization_state_; | 597 << initialization_state_; |
591 } | 598 } |
592 } | 599 } |
593 | 600 |
601 void ResourcePrefetchPredictor::RecordFirstContentfulPaint( | |
602 const NavigationID& navigation_id, | |
603 const base::TimeTicks& first_contentful_paint) { | |
604 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id); | |
605 if (nav_it != inflight_navigations_.end()) { | |
606 nav_it->second->first_contentful_paint = first_contentful_paint; | |
607 } | |
608 } | |
609 | |
594 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url, | 610 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url, |
595 PrefetchOrigin origin) { | 611 PrefetchOrigin origin) { |
596 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", | 612 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", |
597 url.spec()); | 613 url.spec()); |
598 // Save prefetch start time to report prefetching duration. | 614 // Save prefetch start time to report prefetching duration. |
599 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() && | 615 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() && |
600 IsUrlPrefetchable(url)) { | 616 IsUrlPrefetchable(url)) { |
601 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now())); | 617 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now())); |
602 } | 618 } |
603 | 619 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
763 | 779 |
764 NavigationMap::iterator nav_it = | 780 NavigationMap::iterator nav_it = |
765 inflight_navigations_.find(nav_id_without_timing_info); | 781 inflight_navigations_.find(nav_id_without_timing_info); |
766 if (nav_it == inflight_navigations_.end()) | 782 if (nav_it == inflight_navigations_.end()) |
767 return; | 783 return; |
768 | 784 |
769 // Remove the navigation from the inflight navigations. | 785 // Remove the navigation from the inflight navigations. |
770 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); | 786 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); |
771 inflight_navigations_.erase(nav_it); | 787 inflight_navigations_.erase(nav_it); |
772 | 788 |
789 // Set before_first_contentful paint for each resource. | |
790 for (auto& request_summary : summary->subresource_requests) { | |
791 request_summary.before_first_contentful_paint = | |
792 request_summary.response_time < summary->first_contentful_paint; | |
793 } | |
794 | |
773 const GURL& initial_url = summary->initial_url; | 795 const GURL& initial_url = summary->initial_url; |
774 ResourcePrefetchPredictor::Prediction prediction; | 796 ResourcePrefetchPredictor::Prediction prediction; |
775 bool has_data = GetPrefetchData(initial_url, &prediction); | 797 bool has_data = GetPrefetchData(initial_url, &prediction); |
776 if (has_data) | 798 if (has_data) |
777 ReportPredictionAccuracy(prediction, *summary); | 799 ReportPredictionAccuracy(prediction, *summary); |
778 | 800 |
779 auto it = prefetcher_stats_.find(initial_url); | 801 auto it = prefetcher_stats_.find(initial_url); |
780 if (it != prefetcher_stats_.end()) { | 802 if (it != prefetcher_stats_.end()) { |
781 const std::vector<URLRequestSummary>& summaries = | 803 const std::vector<URLRequestSummary>& summaries = |
782 summary->subresource_requests; | 804 summary->subresource_requests; |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1179 continue; | 1201 continue; |
1180 | 1202 |
1181 ResourceData* resource_to_add = data.add_resources(); | 1203 ResourceData* resource_to_add = data.add_resources(); |
1182 resource_to_add->set_resource_url(summary.resource_url.spec()); | 1204 resource_to_add->set_resource_url(summary.resource_url.spec()); |
1183 resource_to_add->set_resource_type( | 1205 resource_to_add->set_resource_type( |
1184 static_cast<ResourceData::ResourceType>(summary.resource_type)); | 1206 static_cast<ResourceData::ResourceType>(summary.resource_type)); |
1185 resource_to_add->set_number_of_hits(1); | 1207 resource_to_add->set_number_of_hits(1); |
1186 resource_to_add->set_average_position(i + 1); | 1208 resource_to_add->set_average_position(i + 1); |
1187 resource_to_add->set_priority( | 1209 resource_to_add->set_priority( |
1188 static_cast<ResourceData::Priority>(summary.priority)); | 1210 static_cast<ResourceData::Priority>(summary.priority)); |
1211 resource_to_add->set_before_first_contentful_paint( | |
alexilin
2017/04/21 13:49:05
It has been lost :(
trevordixon
2017/04/25 12:46:09
Oh no, I did a bad merge. Restored.
| |
1212 summary.before_first_contentful_paint); | |
1189 resource_to_add->set_has_validators(summary.has_validators); | 1213 resource_to_add->set_has_validators(summary.has_validators); |
1190 resource_to_add->set_always_revalidate(summary.always_revalidate); | 1214 resource_to_add->set_always_revalidate(summary.always_revalidate); |
1191 | 1215 |
1192 resources_seen.insert(summary.resource_url); | 1216 resources_seen.insert(summary.resource_url); |
1193 } | 1217 } |
1194 } else { | 1218 } else { |
1195 PrefetchData& data = cache_entry->second; | 1219 PrefetchData& data = cache_entry->second; |
1196 data.set_last_visit_time(base::Time::Now().ToInternalValue()); | 1220 data.set_last_visit_time(base::Time::Now().ToInternalValue()); |
1197 | 1221 |
1198 // Build indices over the data. | 1222 // Build indices over the data. |
(...skipping 29 matching lines...) Expand all Loading... | |
1228 | 1252 |
1229 // Update the resource type since it could have changed. | 1253 // Update the resource type since it could have changed. |
1230 if (new_summary.resource_type != content::RESOURCE_TYPE_LAST_TYPE) { | 1254 if (new_summary.resource_type != content::RESOURCE_TYPE_LAST_TYPE) { |
1231 old_resource->set_resource_type( | 1255 old_resource->set_resource_type( |
1232 static_cast<ResourceData::ResourceType>( | 1256 static_cast<ResourceData::ResourceType>( |
1233 new_summary.resource_type)); | 1257 new_summary.resource_type)); |
1234 } | 1258 } |
1235 | 1259 |
1236 old_resource->set_priority( | 1260 old_resource->set_priority( |
1237 static_cast<ResourceData::Priority>(new_summary.priority)); | 1261 static_cast<ResourceData::Priority>(new_summary.priority)); |
1262 old_resource->set_before_first_contentful_paint( | |
alexilin
2017/04/21 13:49:05
Ditto.
trevordixon
2017/04/25 12:46:09
Fixed.
| |
1263 new_summary.before_first_contentful_paint); | |
1238 | 1264 |
1239 int position = new_index[resource_url] + 1; | 1265 int position = new_index[resource_url] + 1; |
1240 int total = | 1266 int total = |
1241 old_resource->number_of_hits() + old_resource->number_of_misses(); | 1267 old_resource->number_of_hits() + old_resource->number_of_misses(); |
1242 old_resource->set_average_position( | 1268 old_resource->set_average_position( |
1243 ((old_resource->average_position() * total) + position) / | 1269 ((old_resource->average_position() * total) + position) / |
1244 (total + 1)); | 1270 (total + 1)); |
1245 old_resource->set_number_of_hits(old_resource->number_of_hits() + 1); | 1271 old_resource->set_number_of_hits(old_resource->number_of_hits() + 1); |
1246 old_resource->set_consecutive_misses(0); | 1272 old_resource->set_consecutive_misses(0); |
1247 } | 1273 } |
1248 } | 1274 } |
1249 | 1275 |
1250 // Add the new ones that we have not seen before. | 1276 // Add the new ones that we have not seen before. |
1251 for (int i = 0; i < new_resources_size; ++i) { | 1277 for (int i = 0; i < new_resources_size; ++i) { |
1252 const URLRequestSummary& summary = new_resources[i]; | 1278 const URLRequestSummary& summary = new_resources[i]; |
1253 if (old_index.find(summary.resource_url) != old_index.end()) | 1279 if (old_index.find(summary.resource_url) != old_index.end()) |
1254 continue; | 1280 continue; |
1255 | 1281 |
1256 // Only need to add new stuff. | 1282 // Only need to add new stuff. |
1257 ResourceData* resource_to_add = data.add_resources(); | 1283 ResourceData* resource_to_add = data.add_resources(); |
1258 resource_to_add->set_resource_url(summary.resource_url.spec()); | 1284 resource_to_add->set_resource_url(summary.resource_url.spec()); |
1259 resource_to_add->set_resource_type( | 1285 resource_to_add->set_resource_type( |
1260 static_cast<ResourceData::ResourceType>(summary.resource_type)); | 1286 static_cast<ResourceData::ResourceType>(summary.resource_type)); |
1261 resource_to_add->set_number_of_hits(1); | 1287 resource_to_add->set_number_of_hits(1); |
1262 resource_to_add->set_average_position(i + 1); | 1288 resource_to_add->set_average_position(i + 1); |
1263 resource_to_add->set_priority( | 1289 resource_to_add->set_priority( |
1264 static_cast<ResourceData::Priority>(summary.priority)); | 1290 static_cast<ResourceData::Priority>(summary.priority)); |
1291 resource_to_add->set_before_first_contentful_paint( | |
1292 summary.before_first_contentful_paint); | |
1265 resource_to_add->set_has_validators(new_resources[i].has_validators); | 1293 resource_to_add->set_has_validators(new_resources[i].has_validators); |
1266 resource_to_add->set_always_revalidate( | 1294 resource_to_add->set_always_revalidate( |
1267 new_resources[i].always_revalidate); | 1295 new_resources[i].always_revalidate); |
1268 | 1296 |
1269 // To ensure we dont add the same url twice. | 1297 // To ensure we dont add the same url twice. |
1270 old_index[summary.resource_url] = 0; | 1298 old_index[summary.resource_url] = 0; |
1271 } | 1299 } |
1272 } | 1300 } |
1273 | 1301 |
1274 PrefetchData& data = cache_entry->second; | 1302 PrefetchData& data = cache_entry->second; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1493 TestObserver::~TestObserver() { | 1521 TestObserver::~TestObserver() { |
1494 predictor_->SetObserverForTesting(nullptr); | 1522 predictor_->SetObserverForTesting(nullptr); |
1495 } | 1523 } |
1496 | 1524 |
1497 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) | 1525 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) |
1498 : predictor_(predictor) { | 1526 : predictor_(predictor) { |
1499 predictor_->SetObserverForTesting(this); | 1527 predictor_->SetObserverForTesting(this); |
1500 } | 1528 } |
1501 | 1529 |
1502 } // namespace predictors | 1530 } // namespace predictors |
OLD | NEW |