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

Side by Side Diff: third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp

Issue 2289303004: WebFonts: measure network loading time (Closed)
Patch Set: review #27 Created 4 years, 3 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 "core/css/RemoteFontFaceSource.h" 5 #include "core/css/RemoteFontFaceSource.h"
6 6
7 #include "core/css/CSSCustomFontData.h" 7 #include "core/css/CSSCustomFontData.h"
8 #include "core/css/CSSFontFace.h" 8 #include "core/css/CSSFontFace.h"
9 #include "core/css/CSSFontSelector.h" 9 #include "core/css/CSSFontSelector.h"
10 #include "core/dom/Document.h" 10 #include "core/dom/Document.h"
(...skipping 22 matching lines...) Expand all
33 : WebEffectiveConnectionType::TypeSlow2G; 33 : WebEffectiveConnectionType::TypeSlow2G;
34 34
35 return WebEffectiveConnectionType::TypeOffline <= type && type <= thresholdT ype; 35 return WebEffectiveConnectionType::TypeOffline <= type && type <= thresholdT ype;
36 } 36 }
37 37
38 bool isConnectionTypeSlow() 38 bool isConnectionTypeSlow()
39 { 39 {
40 return networkStateNotifier().connectionType() == WebConnectionTypeCellular2 G; 40 return networkStateNotifier().connectionType() == WebConnectionTypeCellular2 G;
41 } 41 }
42 42
43 bool shouldTriggerWebFontsIntervention(Document* document, FontDisplay display, bool isLoadedFromMemoryCache, bool isLoadedFromDataURL)
44 {
45 if (RuntimeEnabledFeatures::webFontsInterventionTriggerEnabled())
46 return true;
47 if (isLoadedFromMemoryCache || isLoadedFromDataURL)
48 return false;
49
50 bool isV2Enabled = RuntimeEnabledFeatures::webFontsInterventionV2With2GEnabl ed() || RuntimeEnabledFeatures::webFontsInterventionV2WithSlow2GEnabled();
51
52 bool networkIsSlow = isV2Enabled ? isEffectiveConnectionTypeSlowFor(document ) : isConnectionTypeSlow();
53
54 return networkIsSlow && display == FontDisplayAuto;
55 }
56
57 } // namespace 43 } // namespace
58 44
59 RemoteFontFaceSource::RemoteFontFaceSource(FontResource* font, CSSFontSelector* fontSelector, FontDisplay display) 45 RemoteFontFaceSource::RemoteFontFaceSource(FontResource* font, CSSFontSelector* fontSelector, FontDisplay display)
60 : m_font(font) 46 : m_font(font)
61 , m_fontSelector(fontSelector) 47 , m_fontSelector(fontSelector)
62 , m_display(display) 48 , m_display(display)
63 , m_period(display == FontDisplaySwap ? SwapPeriod : BlockPeriod) 49 , m_period(display == FontDisplaySwap ? SwapPeriod : BlockPeriod)
50 , m_histograms(font->url().protocolIsData() ? FontLoadHistograms::FromDataUR L : font->isLoaded() ? FontLoadHistograms::FromMemoryCache : FontLoadHistograms: :FromUnknown)
64 , m_isInterventionTriggered(false) 51 , m_isInterventionTriggered(false)
65 , m_isLoadedFromMemoryCache(font->isLoaded())
66 { 52 {
67 ThreadState::current()->registerPreFinalizer(this); 53 ThreadState::current()->registerPreFinalizer(this);
68 m_font->addClient(this); 54 m_font->addClient(this);
69 55
70 if (shouldTriggerWebFontsIntervention(m_fontSelector->document(), display, m _isLoadedFromMemoryCache, m_font->url().protocolIsData())) { 56 if (shouldTriggerWebFontsIntervention()) {
71
72 m_isInterventionTriggered = true; 57 m_isInterventionTriggered = true;
73 m_period = SwapPeriod; 58 m_period = SwapPeriod;
74 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create(Oth erMessageSource, InfoMessageLevel, "Slow network is detected. Fallback font will be used while loading: " + m_font->url().elidedString())); 59 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create(Oth erMessageSource, InfoMessageLevel, "Slow network is detected. Fallback font will be used while loading: " + m_font->url().elidedString()));
75 } 60 }
76 } 61 }
77 62
78 RemoteFontFaceSource::~RemoteFontFaceSource() 63 RemoteFontFaceSource::~RemoteFontFaceSource()
79 { 64 {
80 } 65 }
81 66
(...skipping 27 matching lines...) Expand all
109 return m_font->isLoaded(); 94 return m_font->isLoaded();
110 } 95 }
111 96
112 bool RemoteFontFaceSource::isValid() const 97 bool RemoteFontFaceSource::isValid() const
113 { 98 {
114 return !m_font->errorOccurred(); 99 return !m_font->errorOccurred();
115 } 100 }
116 101
117 void RemoteFontFaceSource::notifyFinished(Resource*) 102 void RemoteFontFaceSource::notifyFinished(Resource*)
118 { 103 {
119 m_histograms.recordRemoteFont(m_font.get(), m_isLoadedFromMemoryCache); 104 m_histograms.maySetDataSource(m_font->response().wasCached() ? FontLoadHisto grams::FromDiskCache : FontLoadHistograms::FromNetwork);
120 m_histograms.fontLoaded(m_isInterventionTriggered, !m_isLoadedFromMemoryCach e && !m_font->url().protocolIsData() && !m_font->response().wasCached()); 105 m_histograms.recordRemoteFont(m_font.get());
106 m_histograms.fontLoaded(m_isInterventionTriggered);
121 107
122 m_font->ensureCustomFontData(); 108 m_font->ensureCustomFontData();
123 // FIXME: Provide more useful message such as OTS rejection reason. 109 // FIXME: Provide more useful message such as OTS rejection reason.
124 // See crbug.com/97467 110 // See crbug.com/97467
125 if (m_font->getStatus() == Resource::DecodeError && m_fontSelector->document ()) { 111 if (m_font->getStatus() == Resource::DecodeError && m_fontSelector->document ()) {
126 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create(Oth erMessageSource, WarningMessageLevel, "Failed to decode downloaded font: " + m_f ont->url().elidedString())); 112 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create(Oth erMessageSource, WarningMessageLevel, "Failed to decode downloaded font: " + m_f ont->url().elidedString()));
127 if (m_font->otsParsingMessage().length() > 1) 113 if (m_font->otsParsingMessage().length() > 1)
128 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create (OtherMessageSource, WarningMessageLevel, "OTS parsing error: " + m_font->otsPar singMessage())); 114 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create (OtherMessageSource, WarningMessageLevel, "OTS parsing error: " + m_font->otsPar singMessage()));
129 } 115 }
130 116
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 } 156 }
171 157
172 void RemoteFontFaceSource::switchToFailurePeriod() 158 void RemoteFontFaceSource::switchToFailurePeriod()
173 { 159 {
174 if (m_period == BlockPeriod) 160 if (m_period == BlockPeriod)
175 switchToSwapPeriod(); 161 switchToSwapPeriod();
176 ASSERT(m_period == SwapPeriod); 162 ASSERT(m_period == SwapPeriod);
177 m_period = FailurePeriod; 163 m_period = FailurePeriod;
178 } 164 }
179 165
166 bool RemoteFontFaceSource::shouldTriggerWebFontsIntervention()
167 {
168 if (RuntimeEnabledFeatures::webFontsInterventionTriggerEnabled())
169 return true;
170 if (m_histograms.dataSource() == FontLoadHistograms::FromMemoryCache || m_hi stograms.dataSource() == FontLoadHistograms::FromDataURL)
171 return false;
172
173 bool isV2Enabled = RuntimeEnabledFeatures::webFontsInterventionV2With2GEnabl ed() || RuntimeEnabledFeatures::webFontsInterventionV2WithSlow2GEnabled();
174
175 bool networkIsSlow = isV2Enabled ? isEffectiveConnectionTypeSlowFor(m_fontSe lector->document()) : isConnectionTypeSlow();
176
177 return networkIsSlow && m_display == FontDisplayAuto;
178 }
179
180
180 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData(const FontDescri ption& fontDescription) 181 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData(const FontDescri ption& fontDescription)
181 { 182 {
182 if (!isLoaded()) 183 if (!isLoaded())
183 return createLoadingFallbackFontData(fontDescription); 184 return createLoadingFallbackFontData(fontDescription);
184 185
185 if (!m_font->ensureCustomFontData() || m_period == FailurePeriod) 186 if (!m_font->ensureCustomFontData() || m_period == FailurePeriod)
186 return nullptr; 187 return nullptr;
187 188
188 m_histograms.recordFallbackTime(m_font.get()); 189 m_histograms.recordFallbackTime(m_font.get());
189 190
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 if (!m_loadStartTime) 232 if (!m_loadStartTime)
232 m_loadStartTime = currentTimeMS(); 233 m_loadStartTime = currentTimeMS();
233 } 234 }
234 235
235 void RemoteFontFaceSource::FontLoadHistograms::fallbackFontPainted(DisplayPeriod period) 236 void RemoteFontFaceSource::FontLoadHistograms::fallbackFontPainted(DisplayPeriod period)
236 { 237 {
237 if (period == BlockPeriod && !m_blankPaintTime) 238 if (period == BlockPeriod && !m_blankPaintTime)
238 m_blankPaintTime = currentTimeMS(); 239 m_blankPaintTime = currentTimeMS();
239 } 240 }
240 241
241 void RemoteFontFaceSource::FontLoadHistograms::fontLoaded(bool isInterventionTri ggered, bool isLoadedFromNetwork) 242 void RemoteFontFaceSource::FontLoadHistograms::fontLoaded(bool isInterventionTri ggered)
242 { 243 {
243 if (!m_isLongLimitExceeded) 244 if (!m_isLongLimitExceeded)
244 recordInterventionResult(isInterventionTriggered, isLoadedFromNetwork); 245 recordInterventionResult(isInterventionTriggered);
245 } 246 }
246 247
247 void RemoteFontFaceSource::FontLoadHistograms::longLimitExceeded(bool isInterven tionTriggered) 248 void RemoteFontFaceSource::FontLoadHistograms::longLimitExceeded(bool isInterven tionTriggered)
248 { 249 {
249 m_isLongLimitExceeded = true; 250 m_isLongLimitExceeded = true;
250 recordInterventionResult(isInterventionTriggered, true); 251 if (m_dataSource == FromUnknown)
252 m_dataSource = FromNetwork;
253 recordInterventionResult(isInterventionTriggered);
251 } 254 }
252 255
253 void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime(const FontReso urce* font) 256 void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime(const FontReso urce* font)
254 { 257 {
255 if (m_blankPaintTime <= 0) 258 if (m_blankPaintTime <= 0)
256 return; 259 return;
257 int duration = static_cast<int>(currentTimeMS() - m_blankPaintTime); 260 int duration = static_cast<int>(currentTimeMS() - m_blankPaintTime);
258 DEFINE_STATIC_LOCAL(CustomCountHistogram, blankTextShownTimeHistogram, ("Web Font.BlankTextShownTime", 0, 10000, 50)); 261 DEFINE_STATIC_LOCAL(CustomCountHistogram, blankTextShownTimeHistogram, ("Web Font.BlankTextShownTime", 0, 10000, 50));
259 blankTextShownTimeHistogram.count(duration); 262 blankTextShownTimeHistogram.count(duration);
260 m_blankPaintTime = -1; 263 m_blankPaintTime = -1;
261 } 264 }
262 265
263 void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont(const FontResour ce* font, bool isLoadedFromMemoryCache) 266 void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont(const FontResour ce* font)
264 { 267 {
265 if (m_loadStartTime > 0 && font && !font->isLoading()) { 268 if (m_loadStartTime > 0 && font && !font->isLoading()) {
269 enum { Miss, DiskHit, DataUrl, MemoryHit, CacheHitEnumMax };
270 DEFINE_STATIC_LOCAL(EnumerationHistogram, cacheHitHistogram, ("WebFont.C acheHit", CacheHitEnumMax));
271 cacheHitHistogram.count(dataSourceMetricsValue());
272
266 int duration = static_cast<int>(currentTimeMS() - m_loadStartTime); 273 int duration = static_cast<int>(currentTimeMS() - m_loadStartTime);
267 recordLoadTimeHistogram(font, duration); 274 recordLoadTimeHistogram(font, duration);
268 m_loadStartTime = -1; 275 m_loadStartTime = -1;
269 276
270 enum { Miss, DiskHit, DataUrl, MemoryHit, CacheHitEnumMax };
271 int histogramValue = font->url().protocolIsData() ? DataUrl
272 : isLoadedFromMemoryCache ? MemoryHit
273 : font->response().wasCached() ? DiskHit
274 : Miss;
275 DEFINE_STATIC_LOCAL(EnumerationHistogram, cacheHitHistogram, ("WebFont.C acheHit", CacheHitEnumMax));
276 cacheHitHistogram.count(histogramValue);
277
278 enum { CORSFail, CORSSuccess, CORSEnumMax }; 277 enum { CORSFail, CORSSuccess, CORSEnumMax };
279 int corsValue = font->isCORSFailed() ? CORSFail : CORSSuccess; 278 int corsValue = font->isCORSFailed() ? CORSFail : CORSSuccess;
280 DEFINE_STATIC_LOCAL(EnumerationHistogram, corsHistogram, ("WebFont.CORSS uccess", CORSEnumMax)); 279 DEFINE_STATIC_LOCAL(EnumerationHistogram, corsHistogram, ("WebFont.CORSS uccess", CORSEnumMax));
281 corsHistogram.count(corsValue); 280 corsHistogram.count(corsValue);
282 } 281 }
283 } 282 }
284 283
285 void RemoteFontFaceSource::FontLoadHistograms::recordLoadTimeHistogram(const Fon tResource* font, int duration) 284 void RemoteFontFaceSource::FontLoadHistograms::recordLoadTimeHistogram(const Fon tResource* font, int duration)
286 { 285 {
286 CHECK_NE(FromUnknown, m_dataSource);
287
287 if (font->errorOccurred()) { 288 if (font->errorOccurred()) {
288 DEFINE_STATIC_LOCAL(CustomCountHistogram, loadErrorHistogram, ("WebFont. DownloadTime.LoadError", 0, 10000, 50)); 289 DEFINE_STATIC_LOCAL(CustomCountHistogram, loadErrorHistogram, ("WebFont. DownloadTime.LoadError", 0, 10000, 50));
290 DEFINE_STATIC_LOCAL(CustomCountHistogram, missedCacheLoadErrorHistogram, ("WebFont.MissedCache.DownloadTime.LoadError", 0, 10000, 50));
289 loadErrorHistogram.count(duration); 291 loadErrorHistogram.count(duration);
292 if (m_dataSource == FromNetwork)
293 missedCacheLoadErrorHistogram.count(duration);
290 return; 294 return;
291 } 295 }
292 296
293 unsigned size = font->encodedSize(); 297 unsigned size = font->encodedSize();
294 if (size < 10 * 1024) { 298 if (size < 10 * 1024) {
295 DEFINE_STATIC_LOCAL(CustomCountHistogram, under10kHistogram, ("WebFont.D ownloadTime.0.Under10KB", 0, 10000, 50)); 299 DEFINE_STATIC_LOCAL(CustomCountHistogram, under10kHistogram, ("WebFont.D ownloadTime.0.Under10KB", 0, 10000, 50));
300 DEFINE_STATIC_LOCAL(CustomCountHistogram, missedCacheUnder10kHistogram, ("WebFont.MissedCache.DownloadTime.0.Under10KB", 0, 10000, 50));
296 under10kHistogram.count(duration); 301 under10kHistogram.count(duration);
302 if (m_dataSource == FromNetwork)
303 missedCacheUnder10kHistogram.count(duration);
297 return; 304 return;
298 } 305 }
299 if (size < 50 * 1024) { 306 if (size < 50 * 1024) {
300 DEFINE_STATIC_LOCAL(CustomCountHistogram, under50kHistogram, ("WebFont.D ownloadTime.1.10KBTo50KB", 0, 10000, 50)); 307 DEFINE_STATIC_LOCAL(CustomCountHistogram, under50kHistogram, ("WebFont.D ownloadTime.1.10KBTo50KB", 0, 10000, 50));
308 DEFINE_STATIC_LOCAL(CustomCountHistogram, missedCacheUnder50kHistogram, ("WebFont.MissedCache.DownloadTime.1.10KBTo50KB", 0, 10000, 50));
301 under50kHistogram.count(duration); 309 under50kHistogram.count(duration);
310 if (m_dataSource == FromNetwork)
311 missedCacheUnder50kHistogram.count(duration);
302 return; 312 return;
303 } 313 }
304 if (size < 100 * 1024) { 314 if (size < 100 * 1024) {
305 DEFINE_STATIC_LOCAL(CustomCountHistogram, under100kHistogram, ("WebFont. DownloadTime.2.50KBTo100KB", 0, 10000, 50)); 315 DEFINE_STATIC_LOCAL(CustomCountHistogram, under100kHistogram, ("WebFont. DownloadTime.2.50KBTo100KB", 0, 10000, 50));
316 DEFINE_STATIC_LOCAL(CustomCountHistogram, missedCacheUnder100kHistogram, ("WebFont.MissedCache.DownloadTime.2.50KBTo100KB", 0, 10000, 50));
306 under100kHistogram.count(duration); 317 under100kHistogram.count(duration);
318 if (m_dataSource == FromNetwork)
319 missedCacheUnder100kHistogram.count(duration);
307 return; 320 return;
308 } 321 }
309 if (size < 1024 * 1024) { 322 if (size < 1024 * 1024) {
310 DEFINE_STATIC_LOCAL(CustomCountHistogram, under1mbHistogram, ("WebFont.D ownloadTime.3.100KBTo1MB", 0, 10000, 50)); 323 DEFINE_STATIC_LOCAL(CustomCountHistogram, under1mbHistogram, ("WebFont.D ownloadTime.3.100KBTo1MB", 0, 10000, 50));
324 DEFINE_STATIC_LOCAL(CustomCountHistogram, missedCacheUnder1mbHistogram, ("WebFont.MissedCache.DownloadTime.3.100KBTo1MB", 0, 10000, 50));
311 under1mbHistogram.count(duration); 325 under1mbHistogram.count(duration);
326 if (m_dataSource == FromNetwork)
327 missedCacheUnder1mbHistogram.count(duration);
312 return; 328 return;
313 } 329 }
314 DEFINE_STATIC_LOCAL(CustomCountHistogram, over1mbHistogram, ("WebFont.Downlo adTime.4.Over1MB", 0, 10000, 50)); 330 DEFINE_STATIC_LOCAL(CustomCountHistogram, over1mbHistogram, ("WebFont.Downlo adTime.4.Over1MB", 0, 10000, 50));
331 DEFINE_STATIC_LOCAL(CustomCountHistogram, missedCacheOver1mbHistogram, ("Web Font.MissedCache.DownloadTime.4.Over1MB", 0, 10000, 50));
315 over1mbHistogram.count(duration); 332 over1mbHistogram.count(duration);
333 if (m_dataSource == FromNetwork)
334 missedCacheOver1mbHistogram.count(duration);
316 } 335 }
317 336
318 void RemoteFontFaceSource::FontLoadHistograms::recordInterventionResult(bool isT riggered, bool isLoadedFromNetwork) 337 void RemoteFontFaceSource::FontLoadHistograms::recordInterventionResult(bool isT riggered)
319 { 338 {
339 CHECK_NE(FromUnknown, m_dataSource);
340
320 // interventionResult takes 0-3 values. 341 // interventionResult takes 0-3 values.
321 int interventionResult = 0; 342 int interventionResult = 0;
322 if (m_isLongLimitExceeded) 343 if (m_isLongLimitExceeded)
323 interventionResult |= 1 << 0; 344 interventionResult |= 1 << 0;
324 if (isTriggered) 345 if (isTriggered)
325 interventionResult |= 1 << 1; 346 interventionResult |= 1 << 1;
326 const int boundary = 1 << 2; 347 const int boundary = 1 << 2;
327 348
328 DEFINE_STATIC_LOCAL(EnumerationHistogram, interventionHistogram, ("WebFont.I nterventionResult", boundary)); 349 DEFINE_STATIC_LOCAL(EnumerationHistogram, interventionHistogram, ("WebFont.I nterventionResult", boundary));
329 DEFINE_STATIC_LOCAL(EnumerationHistogram, missedCacheInterventionHistogram, ("WebFont.InterventionResult.MissedCache", boundary)); 350 DEFINE_STATIC_LOCAL(EnumerationHistogram, missedCacheInterventionHistogram, ("WebFont.InterventionResult.MissedCache", boundary));
330 interventionHistogram.count(interventionResult); 351 interventionHistogram.count(interventionResult);
331 if (isLoadedFromNetwork) 352 if (m_dataSource == FromNetwork)
332 missedCacheInterventionHistogram.count(interventionResult); 353 missedCacheInterventionHistogram.count(interventionResult);
333 } 354 }
334 355
356 RemoteFontFaceSource::FontLoadHistograms::CacheHitMetrics RemoteFontFaceSource:: FontLoadHistograms::dataSourceMetricsValue()
357 {
358 switch (m_dataSource) {
359 case FromDataURL:
360 return DataUrl;
361 case FromMemoryCache:
362 return MemoryHit;
363 case FromDiskCache:
364 return DiskHit;
365 case FromNetwork:
366 return Miss;
367 case FromUnknown:
368 // Fall through.
369 default:
370 NOTREACHED();
371 }
372 return Miss;
373 }
374
335 } // namespace blink 375 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/RemoteFontFaceSource.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698