Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor.cc

Issue 2755093002: predictors: Mark before_first_contentful_paint for resources fetched before fcp. (Closed)
Patch Set: Bump kDatabaseVersion Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 first_occurrence(0) {} 462 first_occurrence(0) {}
463 463
464 ResourcePrefetchPredictor::OriginRequestSummary::OriginRequestSummary( 464 ResourcePrefetchPredictor::OriginRequestSummary::OriginRequestSummary(
465 const OriginRequestSummary& other) = default; 465 const OriginRequestSummary& other) = default;
466 466
467 ResourcePrefetchPredictor::OriginRequestSummary::~OriginRequestSummary() {} 467 ResourcePrefetchPredictor::OriginRequestSummary::~OriginRequestSummary() {}
468 468
469 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() 469 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
470 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), 470 : resource_type(content::RESOURCE_TYPE_LAST_TYPE),
471 priority(net::IDLE), 471 priority(net::IDLE),
472 before_first_contentful_paint(false),
472 was_cached(false), 473 was_cached(false),
473 has_validators(false), 474 has_validators(false),
474 always_revalidate(false), 475 always_revalidate(false),
475 is_no_store(false), 476 is_no_store(false),
476 network_accessed(false) {} 477 network_accessed(false) {}
477 478
478 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( 479 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary(
479 const URLRequestSummary& other) = default; 480 const URLRequestSummary& other) = default;
480 481
481 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { 482 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() {
482 } 483 }
483 484
484 // static 485 // static
485 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( 486 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse(
486 const net::URLRequest& request, 487 const net::URLRequest& request,
487 URLRequestSummary* summary) { 488 URLRequestSummary* summary) {
488 const content::ResourceRequestInfo* request_info = 489 const content::ResourceRequestInfo* request_info =
489 content::ResourceRequestInfo::ForRequest(&request); 490 content::ResourceRequestInfo::ForRequest(&request);
490 if (!request_info) 491 if (!request_info)
491 return false; 492 return false;
492 493
494 // This method is called when the response is started, so this field reflects
495 // the time at which the response began, not when it finished, as would
496 // arguably be ideal. This means if firstContentfulPaint happens after the
497 // response has started, but before it's finished, we will erroneously mark
498 // the resource as having been loaded before firstContentfulPaint. This is
499 // a rare and insignificant enough occurrence that we opt to record the time
500 // here for the sake of simplicity.
501 summary->response_time = base::TimeTicks::Now();
493 summary->resource_url = request.original_url(); 502 summary->resource_url = request.original_url();
494 summary->request_url = request.url(); 503 summary->request_url = request.url();
495 content::ResourceType resource_type_from_request = 504 content::ResourceType resource_type_from_request =
496 request_info->GetResourceType(); 505 request_info->GetResourceType();
497 summary->priority = request.priority(); 506 summary->priority = request.priority();
498 request.GetMimeType(&summary->mime_type); 507 request.GetMimeType(&summary->mime_type);
499 summary->was_cached = request.was_cached(); 508 summary->was_cached = request.was_cached();
500 summary->resource_type = 509 summary->resource_type =
501 GetResourceType(resource_type_from_request, summary->mime_type); 510 GetResourceType(resource_type_from_request, summary->mime_type);
502 511
503 scoped_refptr<net::HttpResponseHeaders> headers = 512 scoped_refptr<net::HttpResponseHeaders> headers =
504 request.response_info().headers; 513 request.response_info().headers;
505 if (headers.get()) { 514 if (headers.get()) {
506 summary->has_validators = headers->HasValidators(); 515 summary->has_validators = headers->HasValidators();
507 // RFC 2616, section 14.9. 516 // RFC 2616, section 14.9.
508 summary->always_revalidate = 517 summary->always_revalidate =
509 headers->HasHeaderValue("cache-control", "no-cache") || 518 headers->HasHeaderValue("cache-control", "no-cache") ||
510 headers->HasHeaderValue("pragma", "no-cache") || 519 headers->HasHeaderValue("pragma", "no-cache") ||
511 headers->HasHeaderValue("vary", "*"); 520 headers->HasHeaderValue("vary", "*");
512 summary->is_no_store = IsNoStore(request); 521 summary->is_no_store = IsNoStore(request);
513 } 522 }
514 summary->network_accessed = request.response_info().network_accessed; 523 summary->network_accessed = request.response_info().network_accessed;
515 return true; 524 return true;
516 } 525 }
517 526
518 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( 527 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary(
519 const GURL& i_main_frame_url) 528 const GURL& i_main_frame_url)
520 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {} 529 : main_frame_url(i_main_frame_url),
530 initial_url(i_main_frame_url),
531 first_contentful_paint(base::TimeTicks::Max()) {}
521 532
522 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( 533 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary(
523 const PageRequestSummary& other) = default; 534 const PageRequestSummary& other) = default;
524 535
525 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {} 536 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {}
526 537
527 ResourcePrefetchPredictor::Prediction::Prediction() = default; 538 ResourcePrefetchPredictor::Prediction::Prediction() = default;
528 539
529 ResourcePrefetchPredictor::Prediction::Prediction( 540 ResourcePrefetchPredictor::Prediction::Prediction(
530 const ResourcePrefetchPredictor::Prediction& other) = default; 541 const ResourcePrefetchPredictor::Prediction& other) = default;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 // corresponding to the navigation has not been created yet. 649 // corresponding to the navigation has not been created yet.
639 if (!navigation_id.main_frame_url.is_empty()) 650 if (!navigation_id.main_frame_url.is_empty())
640 OnNavigationComplete(navigation_id); 651 OnNavigationComplete(navigation_id);
641 break; 652 break;
642 default: 653 default:
643 NOTREACHED() << "Unexpected initialization_state_: " 654 NOTREACHED() << "Unexpected initialization_state_: "
644 << initialization_state_; 655 << initialization_state_;
645 } 656 }
646 } 657 }
647 658
659 void ResourcePrefetchPredictor::RecordFirstContentfulPaint(
660 const NavigationID& navigation_id,
661 const base::TimeTicks& first_contentful_paint) {
662 DCHECK_CURRENTLY_ON(BrowserThread::UI);
663 if (initialization_state_ != INITIALIZED)
664 return;
665
666 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
667 if (nav_it != inflight_navigations_.end())
668 nav_it->second->first_contentful_paint = first_contentful_paint;
669 }
670
648 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url, 671 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url,
649 PrefetchOrigin origin) { 672 PrefetchOrigin origin) {
650 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", 673 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url",
651 url.spec()); 674 url.spec());
652 // Save prefetch start time to report prefetching duration. 675 // Save prefetch start time to report prefetching duration.
653 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() && 676 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() &&
654 IsUrlPrefetchable(url)) { 677 IsUrlPrefetchable(url)) {
655 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now())); 678 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now()));
656 } 679 }
657 680
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 860
838 NavigationMap::iterator nav_it = 861 NavigationMap::iterator nav_it =
839 inflight_navigations_.find(nav_id_without_timing_info); 862 inflight_navigations_.find(nav_id_without_timing_info);
840 if (nav_it == inflight_navigations_.end()) 863 if (nav_it == inflight_navigations_.end())
841 return; 864 return;
842 865
843 // Remove the navigation from the inflight navigations. 866 // Remove the navigation from the inflight navigations.
844 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); 867 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second);
845 inflight_navigations_.erase(nav_it); 868 inflight_navigations_.erase(nav_it);
846 869
870 // Set before_first_contentful paint for each resource.
871 for (auto& request_summary : summary->subresource_requests) {
872 request_summary.before_first_contentful_paint =
873 request_summary.response_time < summary->first_contentful_paint;
874 }
875
847 const GURL& initial_url = summary->initial_url; 876 const GURL& initial_url = summary->initial_url;
848 ResourcePrefetchPredictor::Prediction prediction; 877 ResourcePrefetchPredictor::Prediction prediction;
849 bool has_data = GetPrefetchData(initial_url, &prediction); 878 bool has_data = GetPrefetchData(initial_url, &prediction);
850 if (has_data) 879 if (has_data)
851 ReportPredictionAccuracy(prediction, *summary); 880 ReportPredictionAccuracy(prediction, *summary);
852 881
853 auto it = prefetcher_stats_.find(initial_url); 882 auto it = prefetcher_stats_.find(initial_url);
854 if (it != prefetcher_stats_.end()) { 883 if (it != prefetcher_stats_.end()) {
855 const std::vector<URLRequestSummary>& summaries = 884 const std::vector<URLRequestSummary>& summaries =
856 summary->subresource_requests; 885 summary->subresource_requests;
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 continue; 1381 continue;
1353 1382
1354 ResourceData* resource_to_add = data.add_resources(); 1383 ResourceData* resource_to_add = data.add_resources();
1355 resource_to_add->set_resource_url(summary.resource_url.spec()); 1384 resource_to_add->set_resource_url(summary.resource_url.spec());
1356 resource_to_add->set_resource_type( 1385 resource_to_add->set_resource_type(
1357 static_cast<ResourceData::ResourceType>(summary.resource_type)); 1386 static_cast<ResourceData::ResourceType>(summary.resource_type));
1358 resource_to_add->set_number_of_hits(1); 1387 resource_to_add->set_number_of_hits(1);
1359 resource_to_add->set_average_position(i + 1); 1388 resource_to_add->set_average_position(i + 1);
1360 resource_to_add->set_priority( 1389 resource_to_add->set_priority(
1361 static_cast<ResourceData::Priority>(summary.priority)); 1390 static_cast<ResourceData::Priority>(summary.priority));
1391 resource_to_add->set_before_first_contentful_paint(
1392 summary.before_first_contentful_paint);
1362 resource_to_add->set_has_validators(summary.has_validators); 1393 resource_to_add->set_has_validators(summary.has_validators);
1363 resource_to_add->set_always_revalidate(summary.always_revalidate); 1394 resource_to_add->set_always_revalidate(summary.always_revalidate);
1364 1395
1365 resources_seen.insert(summary.resource_url); 1396 resources_seen.insert(summary.resource_url);
1366 } 1397 }
1367 } else { 1398 } else {
1368 PrefetchData& data = cache_entry->second; 1399 PrefetchData& data = cache_entry->second;
1369 data.set_last_visit_time(base::Time::Now().ToInternalValue()); 1400 data.set_last_visit_time(base::Time::Now().ToInternalValue());
1370 1401
1371 // Build indices over the data. 1402 // Build indices over the data.
(...skipping 29 matching lines...) Expand all
1401 1432
1402 // Update the resource type since it could have changed. 1433 // Update the resource type since it could have changed.
1403 if (new_summary.resource_type != content::RESOURCE_TYPE_LAST_TYPE) { 1434 if (new_summary.resource_type != content::RESOURCE_TYPE_LAST_TYPE) {
1404 old_resource->set_resource_type( 1435 old_resource->set_resource_type(
1405 static_cast<ResourceData::ResourceType>( 1436 static_cast<ResourceData::ResourceType>(
1406 new_summary.resource_type)); 1437 new_summary.resource_type));
1407 } 1438 }
1408 1439
1409 old_resource->set_priority( 1440 old_resource->set_priority(
1410 static_cast<ResourceData::Priority>(new_summary.priority)); 1441 static_cast<ResourceData::Priority>(new_summary.priority));
1442 old_resource->set_before_first_contentful_paint(
1443 new_summary.before_first_contentful_paint);
1411 1444
1412 int position = new_index[resource_url] + 1; 1445 int position = new_index[resource_url] + 1;
1413 int total = 1446 int total =
1414 old_resource->number_of_hits() + old_resource->number_of_misses(); 1447 old_resource->number_of_hits() + old_resource->number_of_misses();
1415 old_resource->set_average_position( 1448 old_resource->set_average_position(
1416 ((old_resource->average_position() * total) + position) / 1449 ((old_resource->average_position() * total) + position) /
1417 (total + 1)); 1450 (total + 1));
1418 old_resource->set_number_of_hits(old_resource->number_of_hits() + 1); 1451 old_resource->set_number_of_hits(old_resource->number_of_hits() + 1);
1419 old_resource->set_consecutive_misses(0); 1452 old_resource->set_consecutive_misses(0);
1420 } 1453 }
1421 } 1454 }
1422 1455
1423 // Add the new ones that we have not seen before. 1456 // Add the new ones that we have not seen before.
1424 for (int i = 0; i < new_resources_size; ++i) { 1457 for (int i = 0; i < new_resources_size; ++i) {
1425 const URLRequestSummary& summary = new_resources[i]; 1458 const URLRequestSummary& summary = new_resources[i];
1426 if (old_index.find(summary.resource_url) != old_index.end()) 1459 if (old_index.find(summary.resource_url) != old_index.end())
1427 continue; 1460 continue;
1428 1461
1429 // Only need to add new stuff. 1462 // Only need to add new stuff.
1430 ResourceData* resource_to_add = data.add_resources(); 1463 ResourceData* resource_to_add = data.add_resources();
1431 resource_to_add->set_resource_url(summary.resource_url.spec()); 1464 resource_to_add->set_resource_url(summary.resource_url.spec());
1432 resource_to_add->set_resource_type( 1465 resource_to_add->set_resource_type(
1433 static_cast<ResourceData::ResourceType>(summary.resource_type)); 1466 static_cast<ResourceData::ResourceType>(summary.resource_type));
1434 resource_to_add->set_number_of_hits(1); 1467 resource_to_add->set_number_of_hits(1);
1435 resource_to_add->set_average_position(i + 1); 1468 resource_to_add->set_average_position(i + 1);
1436 resource_to_add->set_priority( 1469 resource_to_add->set_priority(
1437 static_cast<ResourceData::Priority>(summary.priority)); 1470 static_cast<ResourceData::Priority>(summary.priority));
1471 resource_to_add->set_before_first_contentful_paint(
1472 summary.before_first_contentful_paint);
1438 resource_to_add->set_has_validators(new_resources[i].has_validators); 1473 resource_to_add->set_has_validators(new_resources[i].has_validators);
1439 resource_to_add->set_always_revalidate( 1474 resource_to_add->set_always_revalidate(
1440 new_resources[i].always_revalidate); 1475 new_resources[i].always_revalidate);
1441 1476
1442 // To ensure we dont add the same url twice. 1477 // To ensure we dont add the same url twice.
1443 old_index[summary.resource_url] = 0; 1478 old_index[summary.resource_url] = 0;
1444 } 1479 }
1445 } 1480 }
1446 1481
1447 PrefetchData& data = cache_entry->second; 1482 PrefetchData& data = cache_entry->second;
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 TestObserver::~TestObserver() { 1851 TestObserver::~TestObserver() {
1817 predictor_->SetObserverForTesting(nullptr); 1852 predictor_->SetObserverForTesting(nullptr);
1818 } 1853 }
1819 1854
1820 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1855 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1821 : predictor_(predictor) { 1856 : predictor_(predictor) {
1822 predictor_->SetObserverForTesting(this); 1857 predictor_->SetObserverForTesting(this);
1823 } 1858 }
1824 1859
1825 } // namespace predictors 1860 } // namespace predictors
OLDNEW
« no previous file with comments | « chrome/browser/predictors/resource_prefetch_predictor.h ('k') | chrome/browser/predictors/resource_prefetch_predictor.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698