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

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: Respond to feedback. 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 response_time(base::TimeTicks()),
473 before_first_contentful_paint(false),
472 was_cached(false), 474 was_cached(false),
473 has_validators(false), 475 has_validators(false),
474 always_revalidate(false), 476 always_revalidate(false),
475 is_no_store(false), 477 is_no_store(false),
476 network_accessed(false) {} 478 network_accessed(false) {}
477 479
478 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( 480 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary(
479 const URLRequestSummary& other) = default; 481 const URLRequestSummary& other) = default;
480 482
481 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { 483 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() {
482 } 484 }
483 485
484 // static 486 // static
485 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( 487 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse(
486 const net::URLRequest& request, 488 const net::URLRequest& request,
487 URLRequestSummary* summary) { 489 URLRequestSummary* summary) {
488 const content::ResourceRequestInfo* request_info = 490 const content::ResourceRequestInfo* request_info =
489 content::ResourceRequestInfo::ForRequest(&request); 491 content::ResourceRequestInfo::ForRequest(&request);
490 if (!request_info) 492 if (!request_info)
491 return false; 493 return false;
492 494
495 summary->response_time = base::TimeTicks::Now();
493 summary->resource_url = request.original_url(); 496 summary->resource_url = request.original_url();
494 summary->request_url = request.url(); 497 summary->request_url = request.url();
495 content::ResourceType resource_type_from_request = 498 content::ResourceType resource_type_from_request =
496 request_info->GetResourceType(); 499 request_info->GetResourceType();
497 summary->priority = request.priority(); 500 summary->priority = request.priority();
498 request.GetMimeType(&summary->mime_type); 501 request.GetMimeType(&summary->mime_type);
499 summary->was_cached = request.was_cached(); 502 summary->was_cached = request.was_cached();
500 summary->resource_type = 503 summary->resource_type =
501 GetResourceType(resource_type_from_request, summary->mime_type); 504 GetResourceType(resource_type_from_request, summary->mime_type);
502 505
503 scoped_refptr<net::HttpResponseHeaders> headers = 506 scoped_refptr<net::HttpResponseHeaders> headers =
504 request.response_info().headers; 507 request.response_info().headers;
505 if (headers.get()) { 508 if (headers.get()) {
506 summary->has_validators = headers->HasValidators(); 509 summary->has_validators = headers->HasValidators();
507 // RFC 2616, section 14.9. 510 // RFC 2616, section 14.9.
508 summary->always_revalidate = 511 summary->always_revalidate =
509 headers->HasHeaderValue("cache-control", "no-cache") || 512 headers->HasHeaderValue("cache-control", "no-cache") ||
510 headers->HasHeaderValue("pragma", "no-cache") || 513 headers->HasHeaderValue("pragma", "no-cache") ||
511 headers->HasHeaderValue("vary", "*"); 514 headers->HasHeaderValue("vary", "*");
512 summary->is_no_store = IsNoStore(request); 515 summary->is_no_store = IsNoStore(request);
513 } 516 }
514 summary->network_accessed = request.response_info().network_accessed; 517 summary->network_accessed = request.response_info().network_accessed;
515 return true; 518 return true;
516 } 519 }
517 520
518 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( 521 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary(
519 const GURL& i_main_frame_url) 522 const GURL& i_main_frame_url)
520 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {} 523 : main_frame_url(i_main_frame_url),
524 initial_url(i_main_frame_url),
525 first_contentful_paint(base::TimeTicks::Max()) {}
521 526
522 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( 527 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary(
523 const PageRequestSummary& other) = default; 528 const PageRequestSummary& other) = default;
524 529
525 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {} 530 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {}
526 531
527 ResourcePrefetchPredictor::Prediction::Prediction() = default; 532 ResourcePrefetchPredictor::Prediction::Prediction() = default;
528 533
529 ResourcePrefetchPredictor::Prediction::Prediction( 534 ResourcePrefetchPredictor::Prediction::Prediction(
530 const ResourcePrefetchPredictor::Prediction& other) = default; 535 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. 643 // corresponding to the navigation has not been created yet.
639 if (!navigation_id.main_frame_url.is_empty()) 644 if (!navigation_id.main_frame_url.is_empty())
640 OnNavigationComplete(navigation_id); 645 OnNavigationComplete(navigation_id);
641 break; 646 break;
642 default: 647 default:
643 NOTREACHED() << "Unexpected initialization_state_: " 648 NOTREACHED() << "Unexpected initialization_state_: "
644 << initialization_state_; 649 << initialization_state_;
645 } 650 }
646 } 651 }
647 652
653 void ResourcePrefetchPredictor::RecordFirstContentfulPaint(
654 const NavigationID& navigation_id,
655 const base::TimeTicks& first_contentful_paint) {
656 DCHECK_CURRENTLY_ON(BrowserThread::UI);
657 if (initialization_state_ != INITIALIZED)
658 return;
659
660 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
661 if (nav_it != inflight_navigations_.end())
662 nav_it->second->first_contentful_paint = first_contentful_paint;
663 }
664
648 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url, 665 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url,
649 PrefetchOrigin origin) { 666 PrefetchOrigin origin) {
650 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", 667 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url",
651 url.spec()); 668 url.spec());
652 // Save prefetch start time to report prefetching duration. 669 // Save prefetch start time to report prefetching duration.
653 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() && 670 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() &&
654 IsUrlPrefetchable(url)) { 671 IsUrlPrefetchable(url)) {
655 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now())); 672 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now()));
656 } 673 }
657 674
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 854
838 NavigationMap::iterator nav_it = 855 NavigationMap::iterator nav_it =
839 inflight_navigations_.find(nav_id_without_timing_info); 856 inflight_navigations_.find(nav_id_without_timing_info);
840 if (nav_it == inflight_navigations_.end()) 857 if (nav_it == inflight_navigations_.end())
841 return; 858 return;
842 859
843 // Remove the navigation from the inflight navigations. 860 // Remove the navigation from the inflight navigations.
844 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); 861 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second);
845 inflight_navigations_.erase(nav_it); 862 inflight_navigations_.erase(nav_it);
846 863
864 // Set before_first_contentful paint for each resource.
Benoit L 2017/04/25 15:30:36 If I understand the code correctly, this will slig
trevordixon 2017/04/25 20:23:55 OK, documented above where response_time is record
865 for (auto& request_summary : summary->subresource_requests) {
866 request_summary.before_first_contentful_paint =
867 request_summary.response_time < summary->first_contentful_paint;
868 }
869
847 const GURL& initial_url = summary->initial_url; 870 const GURL& initial_url = summary->initial_url;
848 ResourcePrefetchPredictor::Prediction prediction; 871 ResourcePrefetchPredictor::Prediction prediction;
849 bool has_data = GetPrefetchData(initial_url, &prediction); 872 bool has_data = GetPrefetchData(initial_url, &prediction);
850 if (has_data) 873 if (has_data)
851 ReportPredictionAccuracy(prediction, *summary); 874 ReportPredictionAccuracy(prediction, *summary);
852 875
853 auto it = prefetcher_stats_.find(initial_url); 876 auto it = prefetcher_stats_.find(initial_url);
854 if (it != prefetcher_stats_.end()) { 877 if (it != prefetcher_stats_.end()) {
855 const std::vector<URLRequestSummary>& summaries = 878 const std::vector<URLRequestSummary>& summaries =
856 summary->subresource_requests; 879 summary->subresource_requests;
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 continue; 1359 continue;
1337 1360
1338 ResourceData* resource_to_add = data.add_resources(); 1361 ResourceData* resource_to_add = data.add_resources();
1339 resource_to_add->set_resource_url(summary.resource_url.spec()); 1362 resource_to_add->set_resource_url(summary.resource_url.spec());
1340 resource_to_add->set_resource_type( 1363 resource_to_add->set_resource_type(
1341 static_cast<ResourceData::ResourceType>(summary.resource_type)); 1364 static_cast<ResourceData::ResourceType>(summary.resource_type));
1342 resource_to_add->set_number_of_hits(1); 1365 resource_to_add->set_number_of_hits(1);
1343 resource_to_add->set_average_position(i + 1); 1366 resource_to_add->set_average_position(i + 1);
1344 resource_to_add->set_priority( 1367 resource_to_add->set_priority(
1345 static_cast<ResourceData::Priority>(summary.priority)); 1368 static_cast<ResourceData::Priority>(summary.priority));
1369 resource_to_add->set_before_first_contentful_paint(
1370 summary.before_first_contentful_paint);
1346 resource_to_add->set_has_validators(summary.has_validators); 1371 resource_to_add->set_has_validators(summary.has_validators);
1347 resource_to_add->set_always_revalidate(summary.always_revalidate); 1372 resource_to_add->set_always_revalidate(summary.always_revalidate);
1348 1373
1349 resources_seen.insert(summary.resource_url); 1374 resources_seen.insert(summary.resource_url);
1350 } 1375 }
1351 } else { 1376 } else {
1352 PrefetchData& data = cache_entry->second; 1377 PrefetchData& data = cache_entry->second;
1353 data.set_last_visit_time(base::Time::Now().ToInternalValue()); 1378 data.set_last_visit_time(base::Time::Now().ToInternalValue());
1354 1379
1355 // Build indices over the data. 1380 // Build indices over the data.
(...skipping 29 matching lines...) Expand all
1385 1410
1386 // Update the resource type since it could have changed. 1411 // Update the resource type since it could have changed.
1387 if (new_summary.resource_type != content::RESOURCE_TYPE_LAST_TYPE) { 1412 if (new_summary.resource_type != content::RESOURCE_TYPE_LAST_TYPE) {
1388 old_resource->set_resource_type( 1413 old_resource->set_resource_type(
1389 static_cast<ResourceData::ResourceType>( 1414 static_cast<ResourceData::ResourceType>(
1390 new_summary.resource_type)); 1415 new_summary.resource_type));
1391 } 1416 }
1392 1417
1393 old_resource->set_priority( 1418 old_resource->set_priority(
1394 static_cast<ResourceData::Priority>(new_summary.priority)); 1419 static_cast<ResourceData::Priority>(new_summary.priority));
1420 old_resource->set_before_first_contentful_paint(
1421 new_summary.before_first_contentful_paint);
1395 1422
1396 int position = new_index[resource_url] + 1; 1423 int position = new_index[resource_url] + 1;
1397 int total = 1424 int total =
1398 old_resource->number_of_hits() + old_resource->number_of_misses(); 1425 old_resource->number_of_hits() + old_resource->number_of_misses();
1399 old_resource->set_average_position( 1426 old_resource->set_average_position(
1400 ((old_resource->average_position() * total) + position) / 1427 ((old_resource->average_position() * total) + position) /
1401 (total + 1)); 1428 (total + 1));
1402 old_resource->set_number_of_hits(old_resource->number_of_hits() + 1); 1429 old_resource->set_number_of_hits(old_resource->number_of_hits() + 1);
1403 old_resource->set_consecutive_misses(0); 1430 old_resource->set_consecutive_misses(0);
1404 } 1431 }
1405 } 1432 }
1406 1433
1407 // Add the new ones that we have not seen before. 1434 // Add the new ones that we have not seen before.
1408 for (int i = 0; i < new_resources_size; ++i) { 1435 for (int i = 0; i < new_resources_size; ++i) {
1409 const URLRequestSummary& summary = new_resources[i]; 1436 const URLRequestSummary& summary = new_resources[i];
1410 if (old_index.find(summary.resource_url) != old_index.end()) 1437 if (old_index.find(summary.resource_url) != old_index.end())
1411 continue; 1438 continue;
1412 1439
1413 // Only need to add new stuff. 1440 // Only need to add new stuff.
1414 ResourceData* resource_to_add = data.add_resources(); 1441 ResourceData* resource_to_add = data.add_resources();
1415 resource_to_add->set_resource_url(summary.resource_url.spec()); 1442 resource_to_add->set_resource_url(summary.resource_url.spec());
1416 resource_to_add->set_resource_type( 1443 resource_to_add->set_resource_type(
1417 static_cast<ResourceData::ResourceType>(summary.resource_type)); 1444 static_cast<ResourceData::ResourceType>(summary.resource_type));
1418 resource_to_add->set_number_of_hits(1); 1445 resource_to_add->set_number_of_hits(1);
1419 resource_to_add->set_average_position(i + 1); 1446 resource_to_add->set_average_position(i + 1);
1420 resource_to_add->set_priority( 1447 resource_to_add->set_priority(
1421 static_cast<ResourceData::Priority>(summary.priority)); 1448 static_cast<ResourceData::Priority>(summary.priority));
1449 resource_to_add->set_before_first_contentful_paint(
1450 summary.before_first_contentful_paint);
1422 resource_to_add->set_has_validators(new_resources[i].has_validators); 1451 resource_to_add->set_has_validators(new_resources[i].has_validators);
1423 resource_to_add->set_always_revalidate( 1452 resource_to_add->set_always_revalidate(
1424 new_resources[i].always_revalidate); 1453 new_resources[i].always_revalidate);
1425 1454
1426 // To ensure we dont add the same url twice. 1455 // To ensure we dont add the same url twice.
1427 old_index[summary.resource_url] = 0; 1456 old_index[summary.resource_url] = 0;
1428 } 1457 }
1429 } 1458 }
1430 1459
1431 PrefetchData& data = cache_entry->second; 1460 PrefetchData& data = cache_entry->second;
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1800 TestObserver::~TestObserver() { 1829 TestObserver::~TestObserver() {
1801 predictor_->SetObserverForTesting(nullptr); 1830 predictor_->SetObserverForTesting(nullptr);
1802 } 1831 }
1803 1832
1804 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1833 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1805 : predictor_(predictor) { 1834 : predictor_(predictor) {
1806 predictor_->SetObserverForTesting(this); 1835 predictor_->SetObserverForTesting(this);
1807 } 1836 }
1808 1837
1809 } // namespace predictors 1838 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698