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

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

Issue 2184323003: predictors: Support fonts in resource_prefetch_predictors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments. Created 4 years, 4 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 <algorithm>
8 #include <array>
7 #include <map> 9 #include <map>
8 #include <set> 10 #include <set>
9 #include <utility> 11 #include <utility>
10 12
11 #include "base/command_line.h" 13 #include "base/command_line.h"
12 #include "base/macros.h" 14 #include "base/macros.h"
13 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
14 #include "base/metrics/sparse_histogram.h" 16 #include "base/metrics/sparse_histogram.h"
15 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
(...skipping 21 matching lines...) Expand all
38 40
39 using content::BrowserThread; 41 using content::BrowserThread;
40 42
41 namespace { 43 namespace {
42 44
43 // For reporting whether a subresource is handled or not, and for what reasons. 45 // For reporting whether a subresource is handled or not, and for what reasons.
44 enum ResourceStatus { 46 enum ResourceStatus {
45 RESOURCE_STATUS_HANDLED = 0, 47 RESOURCE_STATUS_HANDLED = 0,
46 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE = 1, 48 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE = 1,
47 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE = 2, 49 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE = 2,
48 RESOURCE_STATUS_UNSUPPORTED_MIME_TYPE = 4, 50 RESOURCE_STATUS_UNSUPPORTED_RESOURCE_TYPE = 4,
49 RESOURCE_STATUS_NOT_GET = 8, 51 RESOURCE_STATUS_NOT_GET = 8,
50 RESOURCE_STATUS_URL_TOO_LONG = 16, 52 RESOURCE_STATUS_URL_TOO_LONG = 16,
51 RESOURCE_STATUS_NOT_CACHEABLE = 32, 53 RESOURCE_STATUS_NOT_CACHEABLE = 32,
52 RESOURCE_STATUS_HEADERS_MISSING = 64, 54 RESOURCE_STATUS_HEADERS_MISSING = 64,
53 RESOURCE_STATUS_MAX = 128, 55 RESOURCE_STATUS_MAX = 128,
54 }; 56 };
55 57
56 // For reporting various interesting events that occur during the loading of a 58 // For reporting various interesting events that occur during the loading of a
57 // single main frame. 59 // single main frame.
58 enum NavigationEvent { 60 enum NavigationEvent {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 bool ResourcePrefetchPredictor::ShouldRecordResponse( 206 bool ResourcePrefetchPredictor::ShouldRecordResponse(
205 net::URLRequest* response) { 207 net::URLRequest* response) {
206 const content::ResourceRequestInfo* request_info = 208 const content::ResourceRequestInfo* request_info =
207 content::ResourceRequestInfo::ForRequest(response); 209 content::ResourceRequestInfo::ForRequest(response);
208 if (!request_info) 210 if (!request_info)
209 return false; 211 return false;
210 212
211 if (!request_info->IsMainFrame()) 213 if (!request_info->IsMainFrame())
212 return false; 214 return false;
213 215
214 return request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME ? 216 content::ResourceType resource_type = request_info->GetResourceType();
215 IsHandledMainPage(response) : IsHandledSubresource(response); 217 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME
218 ? IsHandledMainPage(response)
219 : IsHandledSubresource(response, resource_type);
216 } 220 }
217 221
218 // static 222 // static
219 bool ResourcePrefetchPredictor::ShouldRecordRedirect( 223 bool ResourcePrefetchPredictor::ShouldRecordRedirect(
220 net::URLRequest* response) { 224 net::URLRequest* response) {
221 const content::ResourceRequestInfo* request_info = 225 const content::ResourceRequestInfo* request_info =
222 content::ResourceRequestInfo::ForRequest(response); 226 content::ResourceRequestInfo::ForRequest(response);
223 if (!request_info) 227 if (!request_info)
224 return false; 228 return false;
225 229
226 if (!request_info->IsMainFrame()) 230 if (!request_info->IsMainFrame())
227 return false; 231 return false;
228 232
229 return request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME && 233 return request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME &&
230 IsHandledMainPage(response); 234 IsHandledMainPage(response);
231 } 235 }
232 236
233 // static 237 // static
234 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) { 238 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) {
235 return request->url().SchemeIsHTTPOrHTTPS(); 239 return request->url().SchemeIsHTTPOrHTTPS();
236 } 240 }
237 241
238 // static 242 // static
239 bool ResourcePrefetchPredictor::IsHandledSubresource( 243 bool ResourcePrefetchPredictor::IsHandledSubresource(
240 net::URLRequest* response) { 244 net::URLRequest* response,
245 content::ResourceType resource_type) {
241 int resource_status = 0; 246 int resource_status = 0;
242 247
243 if (!response->first_party_for_cookies().SchemeIsHTTPOrHTTPS()) 248 if (!response->first_party_for_cookies().SchemeIsHTTPOrHTTPS())
244 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE; 249 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE;
245 250
246 if (!response->url().SchemeIsHTTPOrHTTPS()) 251 if (!response->url().SchemeIsHTTPOrHTTPS())
247 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE; 252 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE;
248 253
249 std::string mime_type; 254 std::string mime_type;
250 response->GetMimeType(&mime_type); 255 response->GetMimeType(&mime_type);
251 if (!mime_type.empty() && !mime_util::IsSupportedImageMimeType(mime_type) && 256 if (!IsHandledResourceType(resource_type, mime_type))
252 !mime_util::IsSupportedJavascriptMimeType(mime_type) && 257 resource_status |= RESOURCE_STATUS_UNSUPPORTED_RESOURCE_TYPE;
253 !net::MatchesMimeType("text/css", mime_type)) {
254 resource_status |= RESOURCE_STATUS_UNSUPPORTED_MIME_TYPE;
255 }
256 258
257 if (response->method() != "GET") 259 if (response->method() != "GET")
258 resource_status |= RESOURCE_STATUS_NOT_GET; 260 resource_status |= RESOURCE_STATUS_NOT_GET;
259 261
260 if (response->original_url().spec().length() > 262 if (response->original_url().spec().length() >
261 ResourcePrefetchPredictorTables::kMaxStringLength) { 263 ResourcePrefetchPredictorTables::kMaxStringLength) {
262 resource_status |= RESOURCE_STATUS_URL_TOO_LONG; 264 resource_status |= RESOURCE_STATUS_URL_TOO_LONG;
263 } 265 }
264 266
265 if (!response->response_info().headers.get()) 267 if (!response->response_info().headers.get())
266 resource_status |= RESOURCE_STATUS_HEADERS_MISSING; 268 resource_status |= RESOURCE_STATUS_HEADERS_MISSING;
267 269
268 if (!IsCacheable(response)) 270 if (!IsCacheable(response))
269 resource_status |= RESOURCE_STATUS_NOT_CACHEABLE; 271 resource_status |= RESOURCE_STATUS_NOT_CACHEABLE;
270 272
271 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.ResourceStatus", 273 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.ResourceStatus",
272 resource_status, 274 resource_status,
273 RESOURCE_STATUS_MAX); 275 RESOURCE_STATUS_MAX);
274 276
275 return resource_status == 0; 277 return resource_status == 0;
276 } 278 }
277 279
278 // static 280 // static
281 bool ResourcePrefetchPredictor::IsHandledResourceType(
282 content::ResourceType resource_type,
283 const std::string& mime_type) {
284 bool handled = resource_type == content::RESOURCE_TYPE_STYLESHEET ||
285 resource_type == content::RESOURCE_TYPE_SCRIPT ||
286 resource_type == content::RESOURCE_TYPE_IMAGE ||
287 resource_type == content::RESOURCE_TYPE_FONT_RESOURCE;
288 // Need this because content::RESOURCE_TYPE_{PREFETCH,SUB_RESOURCE} can be
289 // anything.
pasko 2016/07/28 18:42:57 This would be an easier to read comment: // Restr
Benoit L 2016/07/29 08:56:27 Done.
290 if (!handled && (resource_type == content::RESOURCE_TYPE_PREFETCH ||
pasko 2016/07/28 18:42:57 one of these values for resource_type implies (!ha
Benoit L 2016/07/29 08:56:27 Done.
291 resource_type == content::RESOURCE_TYPE_SUB_RESOURCE)) {
292 content::ResourceType resource_type_from_mime = GetResourceTypeFromMimeType(
293 mime_type, content::RESOURCE_TYPE_LAST_TYPE);
294 handled = resource_type_from_mime != content::RESOURCE_TYPE_LAST_TYPE;
295 }
296 return handled;
297 }
298
299 // static
279 bool ResourcePrefetchPredictor::IsCacheable(const net::URLRequest* response) { 300 bool ResourcePrefetchPredictor::IsCacheable(const net::URLRequest* response) {
280 if (response->was_cached()) 301 if (response->was_cached())
281 return true; 302 return true;
282 303
283 // For non cached responses, we will ensure that the freshness lifetime is 304 // For non cached responses, we will ensure that the freshness lifetime is
284 // some sane value. 305 // some sane value.
285 const net::HttpResponseInfo& response_info = response->response_info(); 306 const net::HttpResponseInfo& response_info = response->response_info();
286 if (!response_info.headers.get()) 307 if (!response_info.headers.get())
287 return false; 308 return false;
288 base::Time response_time(response_info.response_time); 309 base::Time response_time(response_info.response_time);
289 response_time += base::TimeDelta::FromSeconds(1); 310 response_time += base::TimeDelta::FromSeconds(1);
290 base::TimeDelta freshness = 311 base::TimeDelta freshness =
291 response_info.headers->GetFreshnessLifetimes(response_time).freshness; 312 response_info.headers->GetFreshnessLifetimes(response_time).freshness;
292 return freshness > base::TimeDelta(); 313 return freshness > base::TimeDelta();
293 } 314 }
294 315
295 // static 316 // static
296 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType( 317 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType(
297 const std::string& mime_type, 318 const std::string& mime_type,
298 content::ResourceType fallback) { 319 content::ResourceType fallback) {
299 if (mime_util::IsSupportedImageMimeType(mime_type)) 320 // Sorted by decreasing likelihood according to HTTP archive.
321 static const std::array<std::string, 12> font_mime_types = {
pasko 2016/07/28 18:42:57 nit: it would be less error prone to avoid indicat
Benoit L 2016/07/29 08:56:27 Done.
322 "font/woff2",
323 "application/x-font-woff",
324 "application/font-woff",
325 "application/font-woff2",
326 "font/x-woff",
327 "application/x-font-ttf",
328 "font/woff",
329 "font/ttf",
330 "application/x-font-otf",
331 "x-font/woff",
332 "application/font-sfnt",
333 "application/font-ttf"};
334
335 if (mime_type.empty()) {
336 return fallback;
337 } else if (mime_util::IsSupportedImageMimeType(mime_type)) {
300 return content::RESOURCE_TYPE_IMAGE; 338 return content::RESOURCE_TYPE_IMAGE;
301 else if (mime_util::IsSupportedJavascriptMimeType(mime_type)) 339 } else if (mime_util::IsSupportedJavascriptMimeType(mime_type)) {
302 return content::RESOURCE_TYPE_SCRIPT; 340 return content::RESOURCE_TYPE_SCRIPT;
303 else if (net::MatchesMimeType("text/css", mime_type)) 341 } else if (net::MatchesMimeType("text/css", mime_type)) {
304 return content::RESOURCE_TYPE_STYLESHEET; 342 return content::RESOURCE_TYPE_STYLESHEET;
305 else 343 } else if (std::any_of(font_mime_types.begin(), font_mime_types.end(),
306 return fallback; 344 [&mime_type](const std::string& mime) {
345 return net::MatchesMimeType(mime, mime_type);
346 })) {
pasko 2016/07/28 18:42:57 is it the way git cl format prefers this?
Benoit L 2016/07/29 08:56:27 Yes.
347 return content::RESOURCE_TYPE_FONT_RESOURCE;
348 }
349 return fallback;
307 } 350 }
308 351
309 //////////////////////////////////////////////////////////////////////////////// 352 ////////////////////////////////////////////////////////////////////////////////
310 // ResourcePrefetchPredictor structs. 353 // ResourcePrefetchPredictor structs.
311 354
312 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() 355 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
313 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), 356 : resource_type(content::RESOURCE_TYPE_LAST_TYPE),
314 was_cached(false) { 357 was_cached(false) {
315 } 358 }
316 359
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 // HistoryService is already loaded. Continue with Initialization. 1378 // HistoryService is already loaded. Continue with Initialization.
1336 OnHistoryAndCacheLoaded(); 1379 OnHistoryAndCacheLoaded();
1337 return; 1380 return;
1338 } 1381 }
1339 DCHECK(!history_service_observer_.IsObserving(history_service)); 1382 DCHECK(!history_service_observer_.IsObserving(history_service));
1340 history_service_observer_.Add(history_service); 1383 history_service_observer_.Add(history_service);
1341 return; 1384 return;
1342 } 1385 }
1343 1386
1344 } // namespace predictors 1387 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698