UNPKG

@dcloudio/uni-debugger

Version:

uni-app debugger

280 lines (249 loc) 8.45 kB
// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @unrestricted */ Network.NetworkOverview = class extends PerfUI.TimelineOverviewBase { constructor() { super(); this._selectedFilmStripTime = -1; this.element.classList.add('network-overview'); /** @type {number} */ this._numBands = 1; /** @type {boolean} */ this._updateScheduled = false; SDK.targetManager.addModelListener( SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this); SDK.targetManager.addModelListener( SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this); this.reset(); } /** * @param {?SDK.FilmStripModel} filmStripModel */ setFilmStripModel(filmStripModel) { this._filmStripModel = filmStripModel; this.scheduleUpdate(); } /** * @param {number} time */ selectFilmStripFrame(time) { this._selectedFilmStripTime = time; this.scheduleUpdate(); } clearFilmStripFrame() { this._selectedFilmStripTime = -1; this.scheduleUpdate(); } /** * @param {!Common.Event} event */ _loadEventFired(event) { const time = /** @type {number} */ (event.data.loadTime); if (time) this._loadEvents.push(time * 1000); this.scheduleUpdate(); } /** * @param {!Common.Event} event */ _domContentLoadedEventFired(event) { const data = /** @type {number} */ (event.data); if (data) this._domContentLoadedEvents.push(data * 1000); this.scheduleUpdate(); } /** * @param {string} connectionId * @return {number} */ _bandId(connectionId) { if (!connectionId || connectionId === '0') return -1; if (this._bandMap.has(connectionId)) return /** @type {number} */ (this._bandMap.get(connectionId)); const result = this._nextBand++; this._bandMap.set(connectionId, result); return result; } /** * @param {!SDK.NetworkRequest} request */ updateRequest(request) { if (!this._requestsSet.has(request)) { this._requestsSet.add(request); this._requestsList.push(request); } this.scheduleUpdate(); } /** * @override */ wasShown() { this.onResize(); } /** * @override */ onResize() { const width = this.element.offsetWidth; const height = this.element.offsetHeight; this.calculator().setDisplayWidth(width); this.resetCanvas(); const numBands = (((height - 1) / Network.NetworkOverview._bandHeight) - 1) | 0; this._numBands = (numBands > 0) ? numBands : 1; this.scheduleUpdate(); } /** * @override */ reset() { /** @type {?SDK.FilmStripModel} */ this._filmStripModel = null; /** @type {number} */ this._span = 1; /** @type {?Network.NetworkTimeBoundary} */ this._lastBoundary = null; /** @type {number} */ this._nextBand = 0; /** @type {!Map.<string, number>} */ this._bandMap = new Map(); /** @type {!Array.<!SDK.NetworkRequest>} */ this._requestsList = []; /** @type {!Set.<!SDK.NetworkRequest>} */ this._requestsSet = new Set(); /** @type {!Array.<number>} */ this._loadEvents = []; /** @type {!Array.<number>} */ this._domContentLoadedEvents = []; // Clear screen. this.resetCanvas(); } /** * @protected */ scheduleUpdate() { if (this._updateScheduled || !this.isShowing()) return; this._updateScheduled = true; this.element.window().requestAnimationFrame(this.update.bind(this)); } /** * @override */ update() { this._updateScheduled = false; const calculator = this.calculator(); const newBoundary = new Network.NetworkTimeBoundary(calculator.minimumBoundary(), calculator.maximumBoundary()); if (!this._lastBoundary || !newBoundary.equals(this._lastBoundary)) { const span = calculator.boundarySpan(); while (this._span < span) this._span *= 1.25; calculator.setBounds(calculator.minimumBoundary(), calculator.minimumBoundary() + this._span); this._lastBoundary = new Network.NetworkTimeBoundary(calculator.minimumBoundary(), calculator.maximumBoundary()); } const context = this.context(); const linesByType = {}; const paddingTop = 2; /** * @param {string} type * @param {string} strokeStyle */ function drawLines(type, strokeStyle) { const lines = linesByType[type]; if (!lines) return; const n = lines.length; context.beginPath(); context.strokeStyle = strokeStyle; for (let i = 0; i < n;) { const y = lines[i++] * Network.NetworkOverview._bandHeight + paddingTop; const startTime = lines[i++]; let endTime = lines[i++]; if (endTime === Number.MAX_VALUE) endTime = calculator.maximumBoundary(); context.moveTo(calculator.computePosition(startTime), y); context.lineTo(calculator.computePosition(endTime) + 1, y); } context.stroke(); } /** * @param {string} type * @param {number} y * @param {number} start * @param {number} end */ function addLine(type, y, start, end) { let lines = linesByType[type]; if (!lines) { lines = []; linesByType[type] = lines; } lines.push(y, start, end); } const requests = this._requestsList; const n = requests.length; for (let i = 0; i < n; ++i) { const request = requests[i]; const band = this._bandId(request.connectionId); const y = (band === -1) ? 0 : (band % this._numBands + 1); const timeRanges = Network.RequestTimingView.calculateRequestTimeRanges(request, this.calculator().minimumBoundary()); for (let j = 0; j < timeRanges.length; ++j) { const type = timeRanges[j].name; if (band !== -1 || type === Network.RequestTimeRangeNames.Total) addLine(type, y, timeRanges[j].start * 1000, timeRanges[j].end * 1000); } } context.clearRect(0, 0, this.width(), this.height()); context.save(); context.scale(window.devicePixelRatio, window.devicePixelRatio); context.lineWidth = 2; drawLines(Network.RequestTimeRangeNames.Total, '#CCCCCC'); drawLines(Network.RequestTimeRangeNames.Blocking, '#AAAAAA'); drawLines(Network.RequestTimeRangeNames.Connecting, '#FF9800'); drawLines(Network.RequestTimeRangeNames.ServiceWorker, '#FF9800'); drawLines(Network.RequestTimeRangeNames.ServiceWorkerPreparation, '#FF9800'); drawLines(Network.RequestTimeRangeNames.Push, '#8CDBff'); drawLines(Network.RequestTimeRangeNames.Proxy, '#A1887F'); drawLines(Network.RequestTimeRangeNames.DNS, '#009688'); drawLines(Network.RequestTimeRangeNames.SSL, '#9C27B0'); drawLines(Network.RequestTimeRangeNames.Sending, '#B0BEC5'); drawLines(Network.RequestTimeRangeNames.Waiting, '#00C853'); drawLines(Network.RequestTimeRangeNames.Receiving, '#03A9F4'); const height = this.element.offsetHeight; context.lineWidth = 1; context.beginPath(); context.strokeStyle = '#8080FF'; // Keep in sync with .network-blue-divider CSS rule. for (let i = this._domContentLoadedEvents.length - 1; i >= 0; --i) { const x = Math.round(calculator.computePosition(this._domContentLoadedEvents[i])) + 0.5; context.moveTo(x, 0); context.lineTo(x, height); } context.stroke(); context.beginPath(); context.strokeStyle = '#FF8080'; // Keep in sync with .network-red-divider CSS rule. for (let i = this._loadEvents.length - 1; i >= 0; --i) { const x = Math.round(calculator.computePosition(this._loadEvents[i])) + 0.5; context.moveTo(x, 0); context.lineTo(x, height); } context.stroke(); if (this._selectedFilmStripTime !== -1) { context.lineWidth = 2; context.beginPath(); context.strokeStyle = '#FCCC49'; // Keep in sync with .network-frame-divider CSS rule. const x = Math.round(calculator.computePosition(this._selectedFilmStripTime)); context.moveTo(x, 0); context.lineTo(x, height); context.stroke(); } context.restore(); } }; /** @type {number} */ Network.NetworkOverview._bandHeight = 3; /** @typedef {{start: number, end: number}} */ Network.NetworkOverview.Window;