OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 29 matching lines...) Expand all Loading... |
40 304: true // Underlying request is cacheable | 40 304: true // Underlying request is cacheable |
41 }; | 41 }; |
42 | 42 |
43 /** | 43 /** |
44 * @param {!Array.<!SDK.NetworkRequest>} requests | 44 * @param {!Array.<!SDK.NetworkRequest>} requests |
45 * @param {?Array.<!Common.ResourceType>} types | 45 * @param {?Array.<!Common.ResourceType>} types |
46 * @param {boolean} needFullResources | 46 * @param {boolean} needFullResources |
47 * @return {!Object.<string, !Array.<!SDK.NetworkRequest|string>>} | 47 * @return {!Object.<string, !Array.<!SDK.NetworkRequest|string>>} |
48 */ | 48 */ |
49 Audits.AuditRules.getDomainToResourcesMap = function(requests, types, needFullRe
sources) { | 49 Audits.AuditRules.getDomainToResourcesMap = function(requests, types, needFullRe
sources) { |
| 50 /** @type {!Object<string, !Array<!SDK.NetworkRequest|string>>} */ |
50 var domainToResourcesMap = {}; | 51 var domainToResourcesMap = {}; |
51 for (var i = 0, size = requests.length; i < size; ++i) { | 52 for (var i = 0, size = requests.length; i < size; ++i) { |
52 var request = requests[i]; | 53 var request = requests[i]; |
53 if (types && types.indexOf(request.resourceType()) === -1) | 54 if (types && types.indexOf(request.resourceType()) === -1) |
54 continue; | 55 continue; |
55 var parsedURL = request.url.asParsedURL(); | 56 var parsedURL = request.url().asParsedURL(); |
56 if (!parsedURL) | 57 if (!parsedURL) |
57 continue; | 58 continue; |
58 var domain = parsedURL.host; | 59 var domain = parsedURL.host; |
59 var domainResources = domainToResourcesMap[domain]; | 60 var domainResources = domainToResourcesMap[domain]; |
60 if (domainResources === undefined) { | 61 if (domainResources === undefined) { |
61 domainResources = []; | 62 domainResources = /** @type {!Array<!SDK.NetworkRequest|string>} */ ([]); |
62 domainToResourcesMap[domain] = domainResources; | 63 domainToResourcesMap[domain] = domainResources; |
63 } | 64 } |
64 domainResources.push(needFullResources ? request : request.url); | 65 domainResources.push(needFullResources ? request : request.url()); |
65 } | 66 } |
66 return domainToResourcesMap; | 67 return domainToResourcesMap; |
67 }; | 68 }; |
68 | 69 |
69 /** | 70 /** |
70 * @unrestricted | 71 * @unrestricted |
71 */ | 72 */ |
72 Audits.AuditRules.GzipRule = class extends Audits.AuditRule { | 73 Audits.AuditRules.GzipRule = class extends Audits.AuditRule { |
73 constructor() { | 74 constructor() { |
74 super('network-gzip', Common.UIString('Enable gzip compression')); | 75 super('network-gzip', Common.UIString('Enable gzip compression')); |
(...skipping 13 matching lines...) Expand all Loading... |
88 for (var i = 0, length = requests.length; i < length; ++i) { | 89 for (var i = 0, length = requests.length; i < length; ++i) { |
89 var request = requests[i]; | 90 var request = requests[i]; |
90 if (request.cached() || request.statusCode === 304) | 91 if (request.cached() || request.statusCode === 304) |
91 continue; // Do not test cached resources. | 92 continue; // Do not test cached resources. |
92 if (this._shouldCompress(request)) { | 93 if (this._shouldCompress(request)) { |
93 var size = request.resourceSize; | 94 var size = request.resourceSize; |
94 if (this._isCompressed(request)) | 95 if (this._isCompressed(request)) |
95 continue; | 96 continue; |
96 var savings = 2 * size / 3; | 97 var savings = 2 * size / 3; |
97 totalSavings += savings; | 98 totalSavings += savings; |
98 summary.addFormatted('%r could save ~%s', request.url, Number.bytesToStr
ing(savings)); | 99 summary.addFormatted('%r could save ~%s', request.url(), Number.bytesToS
tring(savings)); |
99 result.violationCount++; | 100 result.violationCount++; |
100 } | 101 } |
101 } | 102 } |
102 if (!totalSavings) { | 103 if (!totalSavings) { |
103 callback(null); | 104 callback(null); |
104 return; | 105 return; |
105 } | 106 } |
106 summary.value = Common.UIString( | 107 summary.value = Common.UIString( |
107 'Compressing the following resources with gzip could reduce their transf
er size by about two thirds (~%s):', | 108 'Compressing the following resources with gzip could reduce their transf
er size by about two thirds (~%s):', |
108 Number.bytesToString(totalSavings)); | 109 Number.bytesToString(totalSavings)); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 return; | 317 return; |
317 } | 318 } |
318 | 319 |
319 var requestsOnBusiestHost = domainToResourcesMap[hosts[0]]; | 320 var requestsOnBusiestHost = domainToResourcesMap[hosts[0]]; |
320 var entry = result.addChild( | 321 var entry = result.addChild( |
321 Common.UIString( | 322 Common.UIString( |
322 'This page makes %d parallelizable requests to %s. Increase download
parallelization by distributing the following requests across multiple hostname
s.', | 323 'This page makes %d parallelizable requests to %s. Increase download
parallelization by distributing the following requests across multiple hostname
s.', |
323 busiestHostResourceCount, hosts[0]), | 324 busiestHostResourceCount, hosts[0]), |
324 true); | 325 true); |
325 for (var i = 0; i < requestsOnBusiestHost.length; ++i) | 326 for (var i = 0; i < requestsOnBusiestHost.length; ++i) |
326 entry.addURL(requestsOnBusiestHost[i].url); | 327 entry.addURL(requestsOnBusiestHost[i].url()); |
327 | 328 |
328 result.violationCount = requestsOnBusiestHost.length; | 329 result.violationCount = requestsOnBusiestHost.length; |
329 callback(result); | 330 callback(result); |
330 } | 331 } |
331 }; | 332 }; |
332 | 333 |
333 /** | 334 /** |
334 * @unrestricted | 335 * @unrestricted |
335 */ | 336 */ |
336 Audits.AuditRules.UnusedCssRule = class extends Audits.AuditRule { | 337 Audits.AuditRules.UnusedCssRule = class extends Audits.AuditRule { |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 * @param {!SDK.NetworkRequest} request | 669 * @param {!SDK.NetworkRequest} request |
669 * @return {boolean} | 670 * @return {boolean} |
670 */ | 671 */ |
671 isPubliclyCacheable(request) { | 672 isPubliclyCacheable(request) { |
672 if (this._isExplicitlyNonCacheable(request)) | 673 if (this._isExplicitlyNonCacheable(request)) |
673 return false; | 674 return false; |
674 | 675 |
675 if (this.responseHeaderMatch(request, 'Cache-Control', 'public')) | 676 if (this.responseHeaderMatch(request, 'Cache-Control', 'public')) |
676 return true; | 677 return true; |
677 | 678 |
678 return request.url.indexOf('?') === -1 && !this.responseHeaderMatch(request,
'Cache-Control', 'private'); | 679 return request.url().indexOf('?') === -1 && !this.responseHeaderMatch(reques
t, 'Cache-Control', 'private'); |
679 } | 680 } |
680 | 681 |
681 /** | 682 /** |
682 * @param {!SDK.NetworkRequest} request | 683 * @param {!SDK.NetworkRequest} request |
683 * @param {string} header | 684 * @param {string} header |
684 * @param {string} regexp | 685 * @param {string} regexp |
685 * @return {?Array.<string>} | 686 * @return {?Array.<string>} |
686 */ | 687 */ |
687 responseHeaderMatch(request, header, regexp) { | 688 responseHeaderMatch(request, header, regexp) { |
688 return request.responseHeaderValue(header) ? request.responseHeaderValue(hea
der).match(new RegExp(regexp, 'im')) : | 689 return request.responseHeaderValue(header) ? request.responseHeaderValue(hea
der).match(new RegExp(regexp, 'im')) : |
689 null; | 690 null; |
690 } | 691 } |
691 | 692 |
692 /** | 693 /** |
693 * @param {!SDK.NetworkRequest} request | 694 * @param {!SDK.NetworkRequest} request |
694 * @return {boolean} | 695 * @return {boolean} |
695 */ | 696 */ |
696 hasExplicitExpiration(request) { | 697 hasExplicitExpiration(request) { |
697 return this.hasResponseHeader(request, 'Date') && | 698 return this.hasResponseHeader(request, 'Date') && |
698 (this.hasResponseHeader(request, 'Expires') || !!this.responseHeaderMatc
h(request, 'Cache-Control', 'max-age')); | 699 (this.hasResponseHeader(request, 'Expires') || !!this.responseHeaderMatc
h(request, 'Cache-Control', 'max-age')); |
699 } | 700 } |
700 | 701 |
701 /** | 702 /** |
702 * @param {!SDK.NetworkRequest} request | 703 * @param {!SDK.NetworkRequest} request |
703 * @return {boolean} | 704 * @return {boolean} |
704 */ | 705 */ |
705 _isExplicitlyNonCacheable(request) { | 706 _isExplicitlyNonCacheable(request) { |
706 var hasExplicitExp = this.hasExplicitExpiration(request); | 707 var hasExplicitExp = this.hasExplicitExpiration(request); |
707 return !!this.responseHeaderMatch(request, 'Cache-Control', '(no-cache|no-st
ore)') || | 708 return !!( |
| 709 !!this.responseHeaderMatch(request, 'Cache-Control', '(no-cache|no-store
)') || |
708 !!this.responseHeaderMatch(request, 'Pragma', 'no-cache') || | 710 !!this.responseHeaderMatch(request, 'Pragma', 'no-cache') || |
709 (hasExplicitExp && !this.freshnessLifetimeGreaterThan(request, 0)) || | 711 (hasExplicitExp && !this.freshnessLifetimeGreaterThan(request, 0)) || |
710 (!hasExplicitExp && !!request.url && request.url.indexOf('?') >= 0) || | 712 (!hasExplicitExp && request.url() && request.url().indexOf('?') >= 0) || |
711 (!hasExplicitExp && !this.isCacheableResource(request)); | 713 (!hasExplicitExp && !this.isCacheableResource(request))); |
712 } | 714 } |
713 | 715 |
714 /** | 716 /** |
715 * @param {!SDK.NetworkRequest} request | 717 * @param {!SDK.NetworkRequest} request |
716 * @return {boolean} | 718 * @return {boolean} |
717 */ | 719 */ |
718 isCacheableResource(request) { | 720 isCacheableResource(request) { |
719 return request.statusCode !== undefined && Audits.AuditRules.CacheableRespon
seCodes[request.statusCode]; | 721 return request.statusCode !== undefined && Audits.AuditRules.CacheableRespon
seCodes[request.statusCode]; |
720 } | 722 } |
721 }; | 723 }; |
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 } | 1451 } |
1450 | 1452 |
1451 processCookies(allCookies, requests, result) { | 1453 processCookies(allCookies, requests, result) { |
1452 var domainToResourcesMap = Audits.AuditRules.getDomainToResourcesMap( | 1454 var domainToResourcesMap = Audits.AuditRules.getDomainToResourcesMap( |
1453 requests, [Common.resourceTypes.Stylesheet, Common.resourceTypes.Image],
true); | 1455 requests, [Common.resourceTypes.Stylesheet, Common.resourceTypes.Image],
true); |
1454 var totalStaticResources = 0; | 1456 var totalStaticResources = 0; |
1455 for (var domain in domainToResourcesMap) | 1457 for (var domain in domainToResourcesMap) |
1456 totalStaticResources += domainToResourcesMap[domain].length; | 1458 totalStaticResources += domainToResourcesMap[domain].length; |
1457 if (totalStaticResources < this._minResources) | 1459 if (totalStaticResources < this._minResources) |
1458 return; | 1460 return; |
| 1461 /** @type {!Object<string, number>} */ |
1459 var matchingResourceData = {}; | 1462 var matchingResourceData = {}; |
1460 this.mapResourceCookies(domainToResourcesMap, allCookies, this._collectorCal
lback.bind(this, matchingResourceData)); | 1463 this.mapResourceCookies(domainToResourcesMap, allCookies, this._collectorCal
lback.bind(this, matchingResourceData)); |
1461 | 1464 |
1462 var badUrls = []; | 1465 var badUrls = []; |
1463 var cookieBytes = 0; | 1466 var cookieBytes = 0; |
1464 for (var url in matchingResourceData) { | 1467 for (var url in matchingResourceData) { |
1465 badUrls.push(url); | 1468 badUrls.push(url); |
1466 cookieBytes += matchingResourceData[url]; | 1469 cookieBytes += matchingResourceData[url]; |
1467 } | 1470 } |
1468 if (badUrls.length < this._minResources) | 1471 if (badUrls.length < this._minResources) |
1469 return; | 1472 return; |
1470 | 1473 |
1471 var entry = result.addChild( | 1474 var entry = result.addChild( |
1472 Common.UIString( | 1475 Common.UIString( |
1473 '%s of cookies were sent with the following static resources. Serve
these static resources from a domain that does not set cookies:', | 1476 '%s of cookies were sent with the following static resources. Serve
these static resources from a domain that does not set cookies:', |
1474 Number.bytesToString(cookieBytes)), | 1477 Number.bytesToString(cookieBytes)), |
1475 true); | 1478 true); |
1476 entry.addURLs(badUrls); | 1479 entry.addURLs(badUrls); |
1477 result.violationCount = badUrls.length; | 1480 result.violationCount = badUrls.length; |
1478 } | 1481 } |
1479 | 1482 |
| 1483 /** |
| 1484 * @param {!Object<string, number>} matchingResourceData |
| 1485 * @param {!SDK.NetworkRequest} request |
| 1486 * @param {!SDK.Cookie} cookie |
| 1487 */ |
1480 _collectorCallback(matchingResourceData, request, cookie) { | 1488 _collectorCallback(matchingResourceData, request, cookie) { |
1481 matchingResourceData[request.url] = (matchingResourceData[request.url] || 0)
+ cookie.size(); | 1489 matchingResourceData[request.url()] = (matchingResourceData[request.url()] |
| 0) + cookie.size(); |
1482 } | 1490 } |
1483 }; | 1491 }; |
OLD | NEW |