|
@@ -1,514 +0,0 @@
|
|
|
-<div ng-include="'views/resultSubHeader.html'"></div>
|
|
|
-<div class="rule board">
|
|
|
- <div class="backToDashboard"><a href="#" ng-click="backToDashboard()">Back to dashboard</a></div>
|
|
|
-
|
|
|
- <div ng-if="rule" class="ruleTable">
|
|
|
- <div class="left">
|
|
|
- <h2>{{rule.policy.label}}</h2>
|
|
|
- <grade score="rule.score" class="score"></grade>
|
|
|
- <div>{{rule.score}}/100</div>
|
|
|
- </div>
|
|
|
- <div class="right">
|
|
|
- <h3>
|
|
|
- Value:
|
|
|
- <span ng-if="rule.policy.unit == 'bytes'">{{rule.value | bytes}}</span>
|
|
|
- <span ng-if="rule.policy.unit != 'bytes'">{{rule.value}}<span ng-if="rule.policy.unit"> {{rule.policy.unit}}</span></span>
|
|
|
- </h3>
|
|
|
- <div class="okThreshold" ng-if="rule.score < 100 && rule.policy.isOkThreshold !== undefined">
|
|
|
- Have
|
|
|
- <span ng-if="rule.policy.unit == 'bytes'">{{rule.policy.isOkThreshold | bytes}}</span>
|
|
|
- <span ng-if="rule.policy.unit != 'bytes'">{{rule.policy.isOkThreshold}}<span ng-if="rule.policy.unit"> {{rule.policy.unit}}</span></span>
|
|
|
- <span ng-if="rule.policy.isOkThreshold > 0 && rule.policy.isOkThreshold < rule.policy.isBadThreshold">or less</span>
|
|
|
- <span ng-if="rule.policy.isOkThreshold > rule.policy.isBadThreshold">or more</span>
|
|
|
- to get the 100/100 score on this issue.
|
|
|
- </div>
|
|
|
- <div class="okThreshold" ng-if="rule.globalScoreIfFixed > result.scoreProfiles.generic.globalScore && rule.globalScoreIfFixed > 0 && result.scoreProfiles.generic.globalScore >= 0">
|
|
|
- Your new global score would increase by {{rule.globalScoreIfFixed - result.scoreProfiles.generic.globalScore}} points ({{rule.globalScoreIfFixed}}/100).
|
|
|
- </div>
|
|
|
- <div class="okThreshold" ng-if="rule.globalScoreIfFixed > result.scoreProfiles.generic.globalScore && rule.globalScoreIfFixed > 0 && result.scoreProfiles.generic.globalScore < 0">
|
|
|
- Your new global score would increase by {{rule.globalScoreIfFixed}} points ({{rule.globalScoreIfFixed}}/100).
|
|
|
- </div>
|
|
|
- <div class="okThreshold" ng-if="rule.globalScoreIfFixed > result.scoreProfiles.generic.globalScore && rule.globalScoreIfFixed <= 0">
|
|
|
- Your new global score would increase, but still not enough to reach 0/100. That's embarassing...
|
|
|
- </div>
|
|
|
- <div class="okThreshold" ng-if="rule.globalScoreIfFixed == result.scoreProfiles.generic.globalScore && rule.score < 100">
|
|
|
- Your new global score would slightly increase, but not enough to gain a single point.
|
|
|
- </div>
|
|
|
- <div ng-bind-html="rule.policy.message" class="message"></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div ng-if="rule.abnormal" class="warning">
|
|
|
- <h3>Warning</h3>
|
|
|
- <p>This rule reached the abnormality threshold, which means there is a real problem you should care about.</p>
|
|
|
- </div>
|
|
|
- <div class="offenders" ng-if="rule.policy.hasOffenders">
|
|
|
- <h3 ng-if="rule.offendersObj.count >= 0"><ng-pluralize count="rule.offendersObj.count" when="{'0': 'No offender', 'one': '1 offender', 'other': '{} offenders'}"></ng-pluralize></h3>
|
|
|
-
|
|
|
- <div ng-if="rule.offendersObj.list" class="offendersTable">
|
|
|
- <div ng-repeat="offender in rule.offendersObj.list track by $index">
|
|
|
- <div ng-if="offender.parseError">
|
|
|
- {{offender.parseError}}
|
|
|
- </div>
|
|
|
- <div ng-if="!offender.parseError">
|
|
|
-
|
|
|
- <div ng-if="policyName === 'iframesCount'">
|
|
|
- <span ng-if="offender.url">{{offender.url}}</span>
|
|
|
- <span ng-if="!offender.url">an iframe without URL</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'DOMidDuplicated'">
|
|
|
- <b>{{offender.id}}</b>: {{offender.count}} occurrences
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'DOMqueriesAvoidable'">
|
|
|
- <b>{{offender.query}}</b> (in <dom-element-button obj="offender.context"></dom-element-button>) using {{offender.fn}}: <b>{{offender.count}} queries</b>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'eventsScrollBound'">
|
|
|
- <span ng-if="offender.target == 'window'">Scroll event bound on <b>window</b></span>
|
|
|
- <span ng-if="offender.target == '#document'">Scroll event bound on <b>document</b></span>
|
|
|
- <span ng-if="offender.target == 'window.onscroll'"><b>window.onscroll</b> function declared</span>
|
|
|
- <div class="offenderButton" ng-if="offender.backtrace.length == 0">no backtrace</div>
|
|
|
- <div class="offenderButton opens" ng-if="offender.backtrace.length > 0">
|
|
|
- backtrace
|
|
|
- <div class="backtrace">
|
|
|
- <div ng-repeat="obj in offender.backtrace track by $index">
|
|
|
- <span ng-if="obj.functionName">{{obj.functionName}}()</span>
|
|
|
- <url-link url="obj.file" max-length="60"></url-link>
|
|
|
- line {{obj.line}}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'jsErrors'">
|
|
|
- <b>{{offender.error}}</b>
|
|
|
- <div class="offenderButton" ng-if="offender.backtrace.length == 0">no backtrace</div>
|
|
|
- <div class="offenderButton opens" ng-if="offender.backtrace.length > 0">
|
|
|
- backtrace
|
|
|
- <div class="backtrace">
|
|
|
- <div ng-repeat="obj in offender.backtrace track by $index">
|
|
|
- <span ng-if="obj.functionName">{{obj.functionName}}()</span>
|
|
|
- <url-link url="obj.file" max-length="60"></url-link>
|
|
|
- line {{obj.line}}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'jQueryFunctionsUsed'">
|
|
|
- function <b>{{offender.functionName}}</b> used {{offender.count}} times
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'documentWriteCalls'">
|
|
|
- <b>{{offender.writeFn}}</b>
|
|
|
- <span ng-if="offender.from">
|
|
|
- called from
|
|
|
- <span ng-if="offender.from.functionName">{{offender.from.functionName}}()</span>
|
|
|
- <url-link url="offender.from.file" max-length="50"></url-link>
|
|
|
- line {{offender.from.line}}
|
|
|
- </span>
|
|
|
- <span ng-if="!offender.from">
|
|
|
- called from (no backtrace available)
|
|
|
- </span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssRules'">
|
|
|
- <span ng-if="offender.url === '[inline CSS]'">inline CSS</span>
|
|
|
- <span ng-if="offender.url !== '[inline CSS]'"><url-link url="offender.url" max-length="80"></url-link></span>
|
|
|
- : <ng-pluralize count="offender.value" when="{'0': '0 rule', 'one':'1 rule','other':'{} rules'}"></ng-pluralize>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'similarColors'">
|
|
|
- <div class="similarColors checker"><div ng-style="{'background-color': offender.color1, 'color': offender.isDark ? '#FFF' : '#000'}">{{offender.color1}}</div><div ng-style="{'background-color': offender.color2, 'color': offender.isDark ? '#FFF' : '#000'}">{{offender.color2}}</div></div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssParsingErrors'">
|
|
|
- <b>{{offender.error}}</b>
|
|
|
- <file-and-line file="offender.file" line="offender.line" column="offender.column"></file-and-line>
|
|
|
- <span ng-if="offender.file">(<a href="http://jigsaw.w3.org/css-validator/validator?profile=css3&usermedium=all&warning=no&uri={{offender.file | encodeURIComponent}}" target="_blank">Check on the W3C validator</a>)</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssImports'">
|
|
|
- {{offender.css}}
|
|
|
- <file-and-line-button file="offender.file" line="offender.line" column="offender.column"></file-and-line-button>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssOldPropertyPrefixes'">
|
|
|
- <b>{{offender.property}}</b> {{offender.message}}
|
|
|
- <div ng-if="offender.rules.length" ng-click="offender.showMore = !offender.showMore" class="offenderButton">
|
|
|
- <span ng-if="!offender.showMore">show</span>
|
|
|
- <span ng-if="offender.showMore">hide</span>
|
|
|
- <ng-pluralize count="offender.rules.length" when="{'one':'1 offender','other':'{} offenders'}"></ng-pluralize>
|
|
|
- </div>
|
|
|
- <div ng-if="offender.showMore" class="smallerOffenders">
|
|
|
- <div ng-repeat="cssRule in offender.rules">
|
|
|
- {{cssRule.rule}} {{'{' + offender.property}}: {{cssRule.value + '}' }}
|
|
|
- <file-and-line-button file="cssRule.file" line="cssRule.line" column="cssRule.column"></file-and-line-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'lazyLoadableImagesBelowTheFold'">
|
|
|
- <img ng-src="{{offender.url | https}}" class="smallPreview checker"></img>
|
|
|
- <url-link url="offender.url" max-length="70"></url-link> (offset: {{offender.offset | roundNbr}}px)
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'hiddenImages'">
|
|
|
- <img ng-src="{{offender | https}}" class="smallPreview checker"></img>
|
|
|
- <url-link url="offender" max-length="100"></url-link>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'imagesTooLarge'">
|
|
|
- <img ng-src="{{offender.url | https}}" class="smallPreview checker"></img>
|
|
|
- <div>{{offender.width}}x{{offender.height}}</div>
|
|
|
- <url-link url="offender.url" max-length="100"></url-link>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'notFound' || policyName === 'emptyRequests' || policyName === 'closedConnections' || policyName === 'multipleRequests' || policyName === 'cachingDisabled' || policyName === 'cachingNotSpecified'">
|
|
|
- <url-link url="offender" max-length="100"></url-link>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cachingTooShort'">
|
|
|
- <url-link url="offender.url" max-length="100"></url-link>
|
|
|
- cached for <b>{{offender.ttlWithUnit}} {{offender.unit}}</b>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'domains'">
|
|
|
- <b>{{offender.domain}}</b>
|
|
|
- (<ng-pluralize count="offender.requests" when="{'one':'1 request','other':'{} requests'}"></ng-pluralize>)
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'globalVariables'">
|
|
|
- {{offender}}
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'jQueryVersionsLoaded'">
|
|
|
- {{offender.version}}
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'synchronousXHR'">
|
|
|
- {{offender.url}}
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'fontsCount'">
|
|
|
- <url-link url="offender.url" max-length="70"></url-link>
|
|
|
- ({{offender.size | bytes}})
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'oldHttpProtocol'">
|
|
|
- <b>{{offender.domain}}</b> sends <span ng-class="offender.requests > 4 ? 'offenderProblem' : ''"><b><ng-pluralize count="offender.requests" when="{'one':'1 request','other':'{} requests'}"></ng-pluralize></b></span> over {{offender.httpVersion}}
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'oldTlsProtocol'">
|
|
|
- <b>{{offender.domain}}</b> uses {{offender.tlsVersion}} <span ng-if="offender.beforeDomReady === true" class="offenderProblem">and seems to be on the critical path</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-repeat="fileDetails in rule.offendersObj.byFile track by $index">
|
|
|
- <h3>
|
|
|
- <ng-pluralize count="fileDetails.count" when="{'one': '1 offender', 'other': '{} offenders'}"></ng-pluralize>
|
|
|
- in
|
|
|
- <url-link ng-if="fileDetails.url !== 'Inline CSS' && fileDetails.url !== '[inline CSS]'" url="fileDetails.url" max-length="80"></url-link>
|
|
|
- <span ng-if="fileDetails.url === 'Inline CSS' || fileDetails.url === '[inline CSS]'">inline CSS</span>
|
|
|
- </h3>
|
|
|
-
|
|
|
- <div class="offendersTable">
|
|
|
- <div ng-repeat="offender in fileDetails.offenders track by $index">
|
|
|
- <div ng-if="policyName === 'cssComplexSelectors' || policyName === 'cssComplexSelectorsByAttribute' || policyName === 'cssUniversalSelectors' || policyName === 'cssRedundantBodySelectors' || policyName === 'cssRedundantChildNodesSelectors'">
|
|
|
- <span ng-if="offender.bolded" ng-bind-html="offender.bolded"></span>
|
|
|
- <b ng-if="!offender.bolded">{{offender.css}}</b>
|
|
|
- <span ng-if="offender.line !== null && offender.column !== null"> @ {{offender.line}}:{{offender.column}}</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssMobileFirst'">
|
|
|
- <b>{{offender.query}}</b> for <ng-pluralize count="offender.rules" when="{'one':'1 rule','other':'{} rules'}"></ng-pluralize>
|
|
|
- <span ng-if="offender.line !== null && offender.column !== null"> @ {{offender.line}}:{{offender.column}}</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssDuplicatedSelectors'">
|
|
|
- {{offender.rule}} (<b>x{{offender.occurrences}}</b>)
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssDuplicatedProperties'">
|
|
|
- Property <b>{{offender.property}}</b> duplicated in <b>{{offender.rule}} { }</b>
|
|
|
- <span ng-if="offender.line !== null && offender.column !== null"> @ {{offender.line}}:{{offender.column}}</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssEmptyRules'">
|
|
|
- <b>{{offender.css}} { }</b>
|
|
|
- <span ng-if="offender.line !== null && offender.column !== null"> @ {{offender.line}}:{{offender.column}}</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssImportants'">
|
|
|
- {{offender.rule}} {{ '{' + offender.property}}: {{offender.value}} <b>!important</b>}
|
|
|
- <span ng-if="offender.line !== null && offender.column !== null"> @ {{offender.line}}:{{offender.column}}</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssOldIEFixes'">
|
|
|
- <span ng-if="offender.browser"><b>{{offender.browser}} fix:</b></span>
|
|
|
- <span ng-bind-html="offender.bolded"></span>
|
|
|
- <span ng-if="offender.line !== null && offender.column !== null"> @ {{offender.line}}:{{offender.column}}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="!rule.offendersObj.list && !rule.offendersObj.byFile" class="offendersHtml">
|
|
|
-
|
|
|
- <div ng-if="policyName === 'DOMelementMaxDepth'">
|
|
|
- <dom-tree tree="rule.offendersObj.tree"></dom-tree>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssColors' && rule.offendersObj.count > 0">
|
|
|
- <p>This is the colors palette, sized by total occurrences:</p>
|
|
|
- <div class="colorPalette checker">
|
|
|
- <div ng-repeat="offender in rule.offendersObj.palette" style="background-color: {{offender.color}}; width: {{offender.occurrences * 100 / rule.offendersObj.palette[0].occurrences}}%"><div>{{offender.color}} ({{offender.occurrences}} times)</div></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'totalWeight'">
|
|
|
- <h3>Weight by MIME type</h3>
|
|
|
- <div class="totalWeightPie">
|
|
|
- <canvas class="chart chart-doughnut" chart-data="weightData" chart-labels="weightLabels" chart-options="weightOptions" chart-colors="weightColours"></canvas>
|
|
|
- </div>
|
|
|
- <div ng-repeat="type in weightLabels">
|
|
|
- <h3>{{rule.offendersObj.list.byType[type].totalWeight | bytes}} of {{type}}</h3>
|
|
|
- <div class="offendersTable">
|
|
|
- <div ng-repeat="request in rule.offendersObj.list.byType[type].requests | orderBy:'-weight'" ng-if="request.weight > 0">
|
|
|
- <div><url-link url="request.url" max-length="60"></url-link></div>
|
|
|
- <div ng-class="{offenderProblem: request.weight > 102400}">{{request.weight | bytes}}</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'DOMaccesses'">
|
|
|
- <div ng-repeat="(type, list) in rule.offendersObj.list.byType">
|
|
|
- <h3>
|
|
|
- <ng-pluralize count="list.length" when="{'0': 'No offender', 'one': '1 offender', 'other': '{} offenders'}"></ng-pluralize> from
|
|
|
- <span ng-if="type === 'DOMqueriesById'">getElementById()</span>
|
|
|
- <span ng-if="type === 'DOMqueriesByTagName'">getElementsByTagName()</span>
|
|
|
- <span ng-if="type === 'DOMqueriesByClassName'">getElementsByClassName()</span>
|
|
|
- <span ng-if="type === 'DOMqueriesByQuerySelectorAll'">querySelector() or querySelectorAll()</span>
|
|
|
- <span ng-if="type === 'DOMinserts'">appendChild() or insertBefore()</span>
|
|
|
- <span ng-if="type === 'DOMmutationsInserts'">added nodes</span>
|
|
|
- <span ng-if="type === 'DOMmutationsRemoves'">removed nodes</span>
|
|
|
- <span ng-if="type === 'DOMmutationsAttributes'">attribute changes</span>
|
|
|
- <span ng-if="type === 'eventsBound'">addEventListener()</span>
|
|
|
- </h3>
|
|
|
- <div class="offendersTable">
|
|
|
- <div ng-repeat="access in list">
|
|
|
- <div ng-if="type === 'DOMqueriesById'">#{{access.id}}</div>
|
|
|
- <div ng-if="type === 'DOMqueriesByTagName'">{{access.tag}} <b>on</b> <span title="{{access.node}}">{{access.node | lastDOMNode}}</span></div>
|
|
|
- <div ng-if="type === 'DOMqueriesByClassName'">.{{access.class}} <b>on</b> <span title="{{access.node}}">{{access.node | lastDOMNode}}</span></div>
|
|
|
- <div ng-if="type === 'DOMqueriesByQuerySelectorAll'">{{access.selector}} <b>on</b> <span title="{{access.node}}">{{access.node | lastDOMNode}}</span></div>
|
|
|
- <div ng-if="type === 'DOMinserts'"><span title="{{access.append}}">{{access.append | lastDOMNode}}</span> <b>added to</b> <span title="{{access.node}}">{{access.node | lastDOMNode}}</span></div>
|
|
|
- <div ng-if="type === 'DOMmutationsInserts'">{{access.node}} <b>added to</b> {{access.target}}</div>
|
|
|
- <div ng-if="type === 'DOMmutationsRemoves'">{{access.node}} <b>removed from</b> {{access.target}}</div>
|
|
|
- <div ng-if="type === 'DOMmutationsAttributes'">{{access.attribute}} <b>changed on</b> {{access.node}}</div>
|
|
|
- <div ng-if="type === 'eventsBound'">{{access.eventType}} <b>on</b> <span title="{{access.path}}">{{access.path | lastDOMNode}}</span></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'imageOptimization'">
|
|
|
- <h3 ng-if="rule.value > 0">{{rule.value | bytes}} could be saved on <ng-pluralize count="rule.offendersObj.list.images.length" when="{'one': '1 image', 'other': '{} images'}"></ng-pluralize></h3>
|
|
|
- <div class="imageOffenders">
|
|
|
- <div ng-repeat="image in rule.offendersObj.list.images | orderBy:'-gain'">
|
|
|
- <div>
|
|
|
- Current file: <url-link url="image.url" max-length="50"></url-link>
|
|
|
- <div><a href="{{image.url}}" target="_blank"><img ng-src="{{image.url | https}}" class="checker" /></a></div>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <p ng-if="!image.isCompressible || image.isCompressed">Current weight: {{image.originalWeigth | bytes}}</p>
|
|
|
- <p ng-if="image.isCompressible && !image.isCompressed">Current weight: {{image.originalWeigth | bytes}} ({{image.originalCompressedWeight | bytes}} compressed)</p>
|
|
|
-
|
|
|
- <p ng-if="image.lossless && image.isCompressible">With a lossless optimization:<br/>{{image.afterOptimizationAndCompression | bytes}} compressed (<b>-{{image.gain | bytes}}</b> compressed)</p>
|
|
|
- <p ng-if="image.lossless && !image.isCompressible">With a lossless optimization:<br/>{{image.lossless | bytes}} <span ng-if="!image.lossy">(<b>-{{image.gain | bytes}}</b>)</span></p>
|
|
|
-
|
|
|
- <p ng-if="image.lossy && image.isCompressible">With a lossy optimization:<br/>{{image.afterOptimizationAndCompression | bytes}} compressed (<b>-{{image.gain | bytes}} compressed</b>)</p>
|
|
|
- <p ng-if="image.lossy && !image.isCompressible">With a lossy optimization:<br/>{{image.lossy | bytes}} (<b>-{{image.gain | bytes}}</b>)</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'compression'">
|
|
|
- <h3 ng-if="rule.value > 0">{{rule.value | bytes}} could be saved on <ng-pluralize count="rule.offendersObj.list.files.length" when="{'one': '1 file', 'other': '{} files'}"></ng-pluralize></h3>
|
|
|
- <div class="table">
|
|
|
- <div class="headers">
|
|
|
- <div>File</div>
|
|
|
- <div>Current weight</div>
|
|
|
- <div>Gzip weight</div>
|
|
|
- <div>Brotli</div>
|
|
|
- <div>Gain</div>
|
|
|
- </div>
|
|
|
- <div ng-repeat="file in rule.offendersObj.list.files | orderBy:'-gain'">
|
|
|
- <div>
|
|
|
- <url-link url="file.url" max-length="60"></url-link>
|
|
|
- </div>
|
|
|
- <div>{{file.originalSize | bytes}}</div>
|
|
|
-
|
|
|
- <div ng-if="file.wasCompressed"><i>already gzipped</i></div>
|
|
|
- <div ng-if="!file.wasCompressed">{{file.gzipped | bytes}}</div>
|
|
|
-
|
|
|
- <div>{{file.brotlified | bytes}}</div>
|
|
|
-
|
|
|
- <div><b>-{{file.gain | bytes}}</b></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'fileMinification'">
|
|
|
- <h3 ng-if="rule.value > 0">{{rule.value | bytes}} could be saved on <ng-pluralize count="rule.offendersObj.list.files.length" when="{'one': '1 file', 'other': '{} files'}"></ng-pluralize></h3>
|
|
|
- <div class="table">
|
|
|
- <div class="headers">
|
|
|
- <div>File</div>
|
|
|
- <div>Current weight</div>
|
|
|
- <div>Minified</div>
|
|
|
- <div>Gain</div>
|
|
|
- </div>
|
|
|
- <div ng-repeat="file in rule.offendersObj.list.files | orderBy:'-gain'">
|
|
|
- <div>
|
|
|
- <url-link url="file.url" max-length="60"></url-link>
|
|
|
- </div>
|
|
|
- <div ng-if="file.isCompressed">{{file.originalWeigth | bytes}} (compressed)</div>
|
|
|
- <div ng-if="!file.isCompressed">{{file.originalWeigth | bytes}} ({{file.originalCompressedWeight | bytes}} compressed)</div>
|
|
|
- <div ng-if="file.isCompressed">{{file.afterOptimizationAndCompression | bytes}} (compressed)</div>
|
|
|
- <div ng-if="!file.isCompressed">{{file.optimized | bytes}} ({{file.afterOptimizationAndCompression | bytes}} compressed)</div>
|
|
|
- <div><b>-{{file.gain | bytes}}</b></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'totalRequests'">
|
|
|
- <h3>Requests by MIME type</h3>
|
|
|
- <div ng-repeat="(type, requests) in rule.offendersObj.list.byType">
|
|
|
- <h3><ng-pluralize count="requests.length" when="{'0': 'No ' + type + ' request', 'one': '1 ' + type + ' request', 'other': '{} ' + type + ' requests'}"></ng-pluralize></h3>
|
|
|
- <p ng-if="type == 'css' && requests.length > 2">Reduce the number of stylesheets by concatenating them.</p>
|
|
|
- <p ng-if="type == 'js' && requests.length > 3">Reduce the number of scripts by concatenating them.</p>
|
|
|
- <p ng-if="type == 'image' && requests.length > 5">Reduce the number of images by lazyloading them or by spriting them.</p>
|
|
|
- <p ng-if="type == 'webfont' && requests.length > 1">Fonts are generally loaded on the critical path of the head. Load as few as possible.</p>
|
|
|
- <p ng-if="type == 'other' && requests.length > 0">They can be Flash, XML, music or any undetected format.</p>
|
|
|
- <div class="offendersTable">
|
|
|
- <div ng-repeat="request in requests track by $index">
|
|
|
- <div><url-link url="request" max-length="100"></url-link></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'identicalFiles'">
|
|
|
- <div ng-repeat="offender in rule.offendersObj.list track by $index">
|
|
|
- <h4>A file of {{offender.weight | bytes}} is loaded {{offender.urls.length}} times:</h4>
|
|
|
- <div class="offendersTable">
|
|
|
- <div ng-repeat="url in offender.urls">
|
|
|
- <div><url-link url="url" max-length="100"></url-link></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'cssBreakpoints'">
|
|
|
- <div ng-if="rule.value > 0">
|
|
|
- <h3>Breakpoints list</h3>
|
|
|
- <div class="offendersTable">
|
|
|
- <div ng-repeat="offender in rule.offendersObj | orderBy:'pixels'">
|
|
|
- <div>Breakpoint <b>{{offender.breakpoint}}</b> involves <ng-pluralize count="offender.count" when="{'one': '1 rule', 'other': '{} rules'}"></ng-pluralize></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div ng-if="rule.value === 0">
|
|
|
- No breakpoint
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'heavyFonts'">
|
|
|
- <div ng-repeat="font in rule.offendersObj.fonts | orderBy:'-weight' track by $index">
|
|
|
- <h3><url-link url="font.url" max-length="80"></url-link></h3>
|
|
|
- <div class="offendersTable">
|
|
|
- <div>
|
|
|
- <div>Weight</div>
|
|
|
- <div ng-if="font.weight <= 40960">{{font.weight | bytes}}</div>
|
|
|
- <div ng-if="font.weight > 40960" class="offenderProblem">{{font.weight | bytes}}</div>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <div>Number of glyphs</div>
|
|
|
- <div ng-if="font.numGlyphs <= 500">{{font.numGlyphs}}</div>
|
|
|
- <div ng-if="font.numGlyphs > 500" class="offenderProblem">{{font.numGlyphs}} (better < 500)</div>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <div>Average glyph complexity</div>
|
|
|
- <div ng-if="font.averageGlyphComplexity <= 35">{{font.averageGlyphComplexity}}</div>
|
|
|
- <div ng-if="font.averageGlyphComplexity > 35" class="offenderProblem">{{font.averageGlyphComplexity}} (better < 35)</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'unusedUnicodeRanges'">
|
|
|
- <div ng-repeat="font in rule.offendersObj.fonts | orderBy:'-compressedWeigth' track by $index">
|
|
|
- <h3><url-link url="font.url" max-length="60"></url-link> ({{font.weight | bytes}})</h3>
|
|
|
- <div ng-if="font.isIconFont" class="offendersTable">
|
|
|
- <div>
|
|
|
- <div>
|
|
|
- This font seems to be an icon font
|
|
|
- <span ng-if="font.numGlyphsInCommonWithPageContent / font.glyphs <= 0.05" class="offenderProblem">but only {{font.numGlyphsInCommonWithPageContent}} of its {{font.glyphs}} glyphs <ng-pluralize count="font.numGlyphsInCommonWithPageContent" when="{'one': 'is', 'other': 'are'}"></ng-pluralize> possibly used!</span>
|
|
|
- <span ng-if="font.numGlyphsInCommonWithPageContent / font.glyphs > 0.05">and {{font.numGlyphsInCommonWithPageContent}} of its {{font.glyphs}} glyphs <ng-pluralize count="font.numGlyphsInCommonWithPageContent" when="{'one': 'is', 'other': 'are'}"></ng-pluralize> possibly used.</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div ng-if="!font.isIconFont" class="offendersTable">
|
|
|
- <div ng-repeat="range in font.unicodeRanges track by $index">
|
|
|
- <div><b>{{range.name}}</b></div>
|
|
|
- <div ng-if="!range.underused">{{range.numGlyphsInCommonWithPageContent}} of its {{range.charset.length}} glyphs <ng-pluralize count="range.numGlyphsInCommonWithPageContent" when="{'one': 'is', 'other': 'are'}"></ng-pluralize> possibly used</div>
|
|
|
- <div ng-if="range.underused" class="offenderProblem">{{range.numGlyphsInCommonWithPageContent}} of its {{range.charset.length}} glyphs are used</div>
|
|
|
- <div>
|
|
|
- <div class="offenderButton opens">
|
|
|
- glyphes list
|
|
|
- <div>{{range.charset | addSpaces}}</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div ng-if="font.ligaturesOrHiddenChars > 0">
|
|
|
- <div><b>Ligatures or hidden chars</b></div>
|
|
|
- <div ng-class="{offenderProblem: (font.ligaturesOrHiddenChars > 25)}">{{font.ligaturesOrHiddenChars}} glyphs</div>
|
|
|
- <div></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="policyName === 'nonWoff2Fonts'">
|
|
|
- <h3 ng-if="rule.value > 0">{{rule.value | bytes}} could be saved on <ng-pluralize count="rule.offendersObj.list.fonts.length" when="{'one': '1 file', 'other': '{} files'}"></ng-pluralize></h3>
|
|
|
- <div class="table">
|
|
|
- <div class="headers">
|
|
|
- <div>File</div>
|
|
|
- <div>Current weight</div>
|
|
|
- <div>WOFF 2 weight</div>
|
|
|
- <div>Gain</div>
|
|
|
- </div>
|
|
|
- <div ng-repeat="file in rule.offendersObj.list.fonts | orderBy:'-gain'">
|
|
|
- <div>
|
|
|
- <url-link url="file.url" max-length="70"></url-link>
|
|
|
- </div>
|
|
|
- <div>{{file.originalSize | bytes}}</div>
|
|
|
- <div>{{file.woff2Size | bytes}}</div>
|
|
|
- <div><b>-{{file.gain | bytes}}</b></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div ng-if="!rule && rule !== null" class="notFound">
|
|
|
- <h2>404</h2>
|
|
|
- Rule "{{policyName}}"" not found
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="backToDashboard"><a href="#" ng-click="backToDashboard()">Back to dashboard</a></div>
|
|
|
-</div>
|