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/renderer/page_load_histograms.cc

Issue 1230513002: Record first layout time UMA metric in PageLoadHistograms. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update comment. Created 5 years, 5 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
« no previous file with comments | « chrome/renderer/page_load_histograms.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/renderer/page_load_histograms.h" 5 #include "chrome/renderer/page_load_histograms.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h"
9 #include "base/command_line.h" 10 #include "base/command_line.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/metrics/field_trial.h" 12 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
15 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
18 #include "base/time/time.h" 19 #include "base/time/time.h"
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 break; 821 break;
821 default: 822 default:
822 break; 823 break;
823 } 824 }
824 } 825 }
825 } 826 }
826 827
827 } // namespace 828 } // namespace
828 829
829 PageLoadHistograms::PageLoadHistograms(content::RenderView* render_view) 830 PageLoadHistograms::PageLoadHistograms(content::RenderView* render_view)
830 : content::RenderViewObserver(render_view) { 831 : content::RenderViewObserver(render_view),
832 dumped_first_layout_histograms_(false),
833 weak_factory_(this) {
831 } 834 }
832 835
833 void PageLoadHistograms::Dump(WebFrame* frame) { 836 PageLoadHistograms::~PageLoadHistograms() {
837 }
838
839 bool PageLoadHistograms::ShouldDump(WebFrame* frame) {
834 // We only dump histograms for main frames. 840 // We only dump histograms for main frames.
835 // In the future, it may be interesting to tag subframes and dump them too. 841 // In the future, it may be interesting to tag subframes and dump them too.
836 if (!frame || frame->parent()) 842 if (!frame || frame->parent())
837 return; 843 return false;
838 844
839 // If the main frame lives in a different process, don't do anything. 845 // If the main frame lives in a different process, don't do anything.
840 // Histogram data will be recorded by the real main frame. 846 // Histogram data will be recorded by the real main frame.
841 if (frame->isWebRemoteFrame()) 847 if (frame->isWebRemoteFrame())
842 return; 848 return false;
843 849
844 // Only dump for supported schemes. 850 // Only dump for supported schemes.
845 URLPattern::SchemeMasks scheme_type = 851 URLPattern::SchemeMasks scheme_type =
846 GetSupportedSchemeType(frame->document().url()); 852 GetSupportedSchemeType(frame->document().url());
847 if (scheme_type == 0) 853 if (scheme_type == 0)
848 return; 854 return false;
849 855
850 // Ignore multipart requests. 856 // Ignore multipart requests.
851 if (frame->dataSource()->response().isMultipartPayload()) 857 if (frame->dataSource()->response().isMultipartPayload())
858 return false;
859
860 return true;
861 }
862
863 void PageLoadHistograms::Dump(WebFrame* frame) {
864 if (!ShouldDump(frame))
852 return; 865 return;
853 866
867 URLPattern::SchemeMasks scheme_type =
868 GetSupportedSchemeType(frame->document().url());
869
854 DocumentState* document_state = 870 DocumentState* document_state =
855 DocumentState::FromDataSource(frame->dataSource()); 871 DocumentState::FromDataSource(frame->dataSource());
856 872
857 bool data_reduction_proxy_was_used = false; 873 bool data_reduction_proxy_was_used = false;
858 data_reduction_proxy::LoFiStatus lofi_status = 874 data_reduction_proxy::LoFiStatus lofi_status =
859 data_reduction_proxy::LOFI_STATUS_TEMPORARILY_OFF; 875 data_reduction_proxy::LOFI_STATUS_TEMPORARILY_OFF;
860 if (!document_state->proxy_server().IsEmpty()) { 876 if (!document_state->proxy_server().IsEmpty()) {
861 Send(new DataReductionProxyViewHostMsg_DataReductionProxyStatus( 877 Send(new DataReductionProxyViewHostMsg_DataReductionProxyStatus(
862 document_state->proxy_server(), &data_reduction_proxy_was_used, 878 document_state->proxy_server(), &data_reduction_proxy_was_used,
863 &lofi_status)); 879 &lofi_status));
864 } 880 }
865 881
866 bool came_from_websearch = 882 bool came_from_websearch =
867 IsFromGoogleSearchResult(frame->document().url(), 883 IsFromGoogleSearchResult(frame->document().url(),
868 GURL(frame->document().referrer())); 884 GURL(frame->document().referrer()));
869 int websearch_chrome_joint_experiment_id = kNoExperiment; 885 int websearch_chrome_joint_experiment_id = kNoExperiment;
870 bool is_preview = false; 886 bool is_preview = false;
871 if (came_from_websearch) { 887 if (came_from_websearch) {
872 websearch_chrome_joint_experiment_id = 888 websearch_chrome_joint_experiment_id =
873 GetQueryStringBasedExperiment(GURL(frame->document().referrer())); 889 GetQueryStringBasedExperiment(GURL(frame->document().referrer()));
874 is_preview = ViaHeaderContains(frame, "1.1 Google Instant Proxy Preview"); 890 is_preview = ViaHeaderContains(frame, "1.1 Google Instant Proxy Preview");
875 } 891 }
876 892
893 MaybeDumpFirstLayoutHistograms();
894
877 // Metrics based on the timing information recorded for the Navigation Timing 895 // Metrics based on the timing information recorded for the Navigation Timing
878 // API - http://www.w3.org/TR/navigation-timing/. 896 // API - http://www.w3.org/TR/navigation-timing/.
879 DumpHistograms(frame->performance(), document_state, 897 DumpHistograms(frame->performance(), document_state,
880 data_reduction_proxy_was_used, lofi_status, 898 data_reduction_proxy_was_used, lofi_status,
881 came_from_websearch, websearch_chrome_joint_experiment_id, 899 came_from_websearch, websearch_chrome_joint_experiment_id,
882 is_preview, scheme_type); 900 is_preview, scheme_type);
883 901
884 // Old metrics based on the timing information stored in DocumentState. These 902 // Old metrics based on the timing information stored in DocumentState. These
885 // are deprecated and should go away. 903 // are deprecated and should go away.
886 DumpDeprecatedHistograms(frame->performance(), document_state, 904 DumpDeprecatedHistograms(frame->performance(), document_state,
(...skipping 11 matching lines...) Expand all
898 // the histograms we generated. Without this call, pages that don't have an 916 // the histograms we generated. Without this call, pages that don't have an
899 // on-close-handler might generate data that is lost when the renderer is 917 // on-close-handler might generate data that is lost when the renderer is
900 // shutdown abruptly (perchance because the user closed the tab). 918 // shutdown abruptly (perchance because the user closed the tab).
901 // TODO(jar) BUG=33233: This needs to be moved to a PostDelayedTask, and it 919 // TODO(jar) BUG=33233: This needs to be moved to a PostDelayedTask, and it
902 // should post when the onload is complete, so that it doesn't interfere with 920 // should post when the onload is complete, so that it doesn't interfere with
903 // the next load. 921 // the next load.
904 content::RenderThread::Get()->UpdateHistograms( 922 content::RenderThread::Get()->UpdateHistograms(
905 content::kHistogramSynchronizerReservedSequenceNumber); 923 content::kHistogramSynchronizerReservedSequenceNumber);
906 } 924 }
907 925
926 void PageLoadHistograms::MaybeDumpFirstLayoutHistograms() {
927 if (dumped_first_layout_histograms_)
928 return;
929
930 const WebPerformance& performance =
931 render_view()->GetWebView()->mainFrame()->performance();
932 Time first_layout = Time::FromDoubleT(performance.firstLayout());
933 if (first_layout.is_null())
934 return;
935
936 Time navigation_start = Time::FromDoubleT(performance.navigationStart());
937 if (!navigation_start.is_null())
938 PLT_HISTOGRAM("PLT.PT_NavigationStartToFirstLayout",
939 first_layout - navigation_start);
940
941 Time response_start = Time::FromDoubleT(performance.responseStart());
942 if (!response_start.is_null())
943 PLT_HISTOGRAM("PLT.PT_ResponseStartToFirstLayout",
944 first_layout - response_start);
945
946 dumped_first_layout_histograms_ = true;
947 }
948
908 void PageLoadHistograms::FrameWillClose(WebFrame* frame) { 949 void PageLoadHistograms::FrameWillClose(WebFrame* frame) {
909 Dump(frame); 950 Dump(frame);
910 } 951 }
911 952
912 void PageLoadHistograms::ClosePage() { 953 void PageLoadHistograms::ClosePage() {
913 // TODO(davemoore) This code should be removed once willClose() gets 954 // TODO(davemoore) This code should be removed once willClose() gets
914 // called when a page is destroyed. page_load_histograms_.Dump() is safe 955 // called when a page is destroyed. page_load_histograms_.Dump() is safe
915 // to call multiple times for the same frame, but it will simplify things. 956 // to call multiple times for the same frame, but it will simplify things.
916 Dump(render_view()->GetWebView()->mainFrame()); 957 Dump(render_view()->GetWebView()->mainFrame());
917 } 958 }
918 959
960 void PageLoadHistograms::DidUpdateLayout() {
Pat Meenan 2015/07/09 19:29:27 Just a sanity check, but do you know what the over
Bryan McQuade 2015/07/09 19:35:04 Should just be a function call, which is already b
961 // Normally, PageLoadHistograms dumps all histograms in the FrameWillClose or
962 // ClosePage callbacks, which happen as a page is being torn down. However,
963 // renderers that are killed by fast shutdown (for example, renderers closed
964 // due to the user closing a tab) don't get a chance to run these callbacks
965 // (see crbug.com/382542 for details).
966 //
967 // Longer term, we need to migrate histogram recording to happen earlier in
968 // the page load life cycle, so histograms aren't lost when tabs are
969 // closed. As a first step, we use the RenderViewObserver::DidUpdateLayout
970 // callback to log first layout histograms earlier in the page load life
971 // cycle.
972
973 WebFrame* frame = render_view()->GetWebView()->mainFrame();
974 if (dumped_first_layout_histograms_ || !ShouldDump(frame))
Pat Meenan 2015/07/09 19:29:27 Maybe fast exit the dumped_first_layout_histograms
Bryan McQuade 2015/07/09 19:35:04 Good idea, done.
975 return;
976
977 // The canonical source for the 'first layout time' is the
978 // blink::WebPerformance object, so we need to read the first layout timestamp
979 // from that object, rather than taking our own timestamp in this
980 // callback. This DidUpdateLayout callback gets invoked in the midst of the
981 // layout process. The logic that records the first layout time in the
982 // blink::WebPerformance object may run later in the layout process, after
983 // DidUpdateLayout gets invoked. Thus, we schedule a callback to run
984 // MaybeDumpFirstLayoutHistograms asynchronously, after the layout process is
985 // complete.
986 content::RenderThread::Get()->GetTaskRunner()->PostTask(
987 FROM_HERE,
988 base::Bind(&PageLoadHistograms::MaybeDumpFirstLayoutHistograms,
989 weak_factory_.GetWeakPtr()));
990 }
991
919 void PageLoadHistograms::LogPageLoadTime(const DocumentState* document_state, 992 void PageLoadHistograms::LogPageLoadTime(const DocumentState* document_state,
920 const WebDataSource* ds) const { 993 const WebDataSource* ds) const {
921 // Because this function gets called on every page load, 994 // Because this function gets called on every page load,
922 // take extra care to optimize it away if logging is turned off. 995 // take extra care to optimize it away if logging is turned off.
923 if (logging::LOG_INFO < logging::GetMinLogLevel()) 996 if (logging::LOG_INFO < logging::GetMinLogLevel())
924 return; 997 return;
925 998
926 DCHECK(document_state); 999 DCHECK(document_state);
927 DCHECK(ds); 1000 DCHECK(ds);
928 GURL url(ds->request().url()); 1001 GURL url(ds->request().url());
929 Time start = document_state->start_load_time(); 1002 Time start = document_state->start_load_time();
930 Time finish = document_state->finish_load_time(); 1003 Time finish = document_state->finish_load_time();
931 // TODO(mbelshe): should we log more stats? 1004 // TODO(mbelshe): should we log more stats?
932 VLOG(1) << "PLT: " << (finish - start).InMilliseconds() << "ms " 1005 VLOG(1) << "PLT: " << (finish - start).InMilliseconds() << "ms "
933 << url.spec(); 1006 << url.spec();
934 } 1007 }
OLDNEW
« no previous file with comments | « chrome/renderer/page_load_histograms.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698