100 lines
6.1 KiB
HTML
100 lines
6.1 KiB
HTML
<div ng-include="'views/resultSubHeader.html'"></div>
|
|
<div class="execution board">
|
|
<div class="selectScript" ng-class="{empty:!selectedScript}">
|
|
Filter timeline and profiler by script:
|
|
<select ng-model="selectedScript" ng-options="script.shortPath for script in scripts" ng-change="changeScript()">
|
|
<option value="">All (no filter)</option>
|
|
</select>
|
|
</div>
|
|
|
|
<h2>JavaScript Timeline</h2>
|
|
<p>This graph gives a quick view of when the JavaScript interactions with the DOM occur during the loading of the page.</p>
|
|
|
|
<div class="timeline">
|
|
<div class="chart">
|
|
<div class="chartPoints">
|
|
<div ng-repeat="duration in timeline track by $index"
|
|
class="interval"
|
|
ng-class="{
|
|
domCreation: $index * timelineIntervalDuration < result.javascriptExecutionTree.data.domInteractive,
|
|
domInteractive: $index * timelineIntervalDuration >= result.javascriptExecutionTree.data.domInteractive
|
|
&& $index * timelineIntervalDuration < result.javascriptExecutionTree.data.domContentLoaded,
|
|
domContentLoaded: $index * timelineIntervalDuration >= result.javascriptExecutionTree.data.domContentLoaded
|
|
&& $index * timelineIntervalDuration < result.javascriptExecutionTree.data.domContentLoadedEnd,
|
|
domContentLoadedEnd: $index * timelineIntervalDuration >= result.javascriptExecutionTree.data.domContentLoadedEnd
|
|
&& $index * timelineIntervalDuration < result.javascriptExecutionTree.data.domComplete,
|
|
domComplete: $index * timelineIntervalDuration >= result.javascriptExecutionTree.data.domComplete
|
|
}">
|
|
<div style="height: {{100 * duration / timelineMax | number: 0}}px" class="color" ng-class="{clickable: duration > 0}" scroll-on-click="{{$index * timelineIntervalDuration}}"></div>
|
|
<div class="tooltip detailsOverlay">
|
|
<div>
|
|
Timestamp: {{$index * timelineIntervalDuration | number: 0}} ms
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="startTime">0 ms</div>
|
|
<div class="endTime">{{endTime | number: 0}} ms</div>
|
|
</div>
|
|
<div class="legend">
|
|
<div class="titles">
|
|
<div class="domCreation"><div class="color"></div>DOM creation</div>
|
|
<div class="domInteractive"><div class="color"></div>DOM interactive</div>
|
|
<div class="domContentLoaded"><div class="color"></div>DOM content loaded event</div>
|
|
<div class="domContentLoadedEnd"><div class="color"></div>Page completion</div>
|
|
<div class="domComplete"><div class="color"></div>Page is complete</div>
|
|
</div>
|
|
<div class="tips">
|
|
<div>Executing JavaScript and DOM queries here is a <b>bad practice</b> and slows down the DOM construction.</div>
|
|
<div>Some frameworks do things here, but it's not reliable and should be avoided.</div>
|
|
<div>Also known as "document ready". This is where you should execute <b>top-priority</b> scripts, like binding action buttons or launch a video player.</div>
|
|
<div>Here you can execute <b>mid-priority</b> tasks. Loading a script with createElement('script') is one way to do so.</div>
|
|
<div>The page is considered loaded, it's time for low <b>priority things</b> : trackers, social plugins, easter egg...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h2>JavaScript Profiler</h2>
|
|
<p>
|
|
The table below shows the interactions between the JavaScript and the DOM. It is useful to understand what happens while the page loads.
|
|
</p>
|
|
<div class="filters">
|
|
<div>
|
|
<input type="checkbox" name="warningsFilter" ng-model="warningsFilterOn" id="warningsFilterOn" />
|
|
<label for="warningsFilterOn">Filter on warnings and errors</label>
|
|
<div class="subFilters" ng-if="warningsFilterOn">
|
|
<div>
|
|
<input type="checkbox" name="filters" ng-model="warningsFilters.queryWithoutResults" id="queryWithoutResultsFilterOn"/>
|
|
<label for="queryWithoutResultsFilterOn">Queries without results</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" name="filters" ng-model="warningsFilters.jQueryCallOnEmptyObject" id="jQueryCallOnEmptyObjectFilterOn" />
|
|
<label for="jQueryCallOnEmptyObjectFilterOn">jQuery calls on empty object</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" name="filters" ng-model="warningsFilters.eventNotDelegated" id="eventNotDelegatedFilterOn" />
|
|
<label for="eventNotDelegatedFilterOn">Events not delegated</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" name="filters" ng-model="warningsFilters.jsError" id="jsErrorFilterOn" />
|
|
<label for="jsErrorFilterOn">Errors</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{queryWithoutResultsFilterOn}}
|
|
</div>
|
|
<div class="table" ng-class="{queryWithoutResultsFilterOn: warningsFilterOn && warningsFilters.queryWithoutResults, jQueryCallOnEmptyObjectFilterOn: warningsFilterOn && warningsFilters.jQueryCallOnEmptyObject, eventNotDelegatedFilterOn: warningsFilterOn && warningsFilters.eventNotDelegated, jsErrorFilterOn: warningsFilterOn && warningsFilters.jsError}">
|
|
<div class="headers">
|
|
<div><!-- index --></div>
|
|
<div>Type</div>
|
|
<div>Params</div>
|
|
<div><!-- details --></div>
|
|
<div>Timestamp</div>
|
|
</div>
|
|
|
|
<profiler-line ng-repeat="node in profilerData" data-index="$index" node="node"></profiler-line>
|
|
|
|
</div>
|
|
|
|
<div class="backToDashboard"><a href="#" ng-click="backToDashboard()">Back to dashboard</a></div>
|
|
</div> |