Skip to content

Commit

Permalink
DRY
Browse files Browse the repository at this point in the history
  • Loading branch information
sbma44 committed Jun 1, 2018
1 parent 7f31d7c commit 2fea81b
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 79 deletions.
28 changes: 5 additions & 23 deletions src/source/geojson_worker_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { getJSON } from '../util/ajax';

import perf from '../util/performance';
import performance from '../util/performance';
import rewind from 'geojson-rewind';
import GeoJSONWrapper from './geojson_wrapper';
import vtpbf from 'vt-pbf';
Expand Down Expand Up @@ -153,15 +153,8 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
delete this._pendingCallback;
delete this._pendingLoadDataParams;

const marks = {};
const url = params && params.request && params.request.url;
const collectResourceTiming = params && params.request && params.request.collectResourceTiming;
if (url && collectResourceTiming) {
marks.start = [url, '#start'].join('#');
marks.end = [url, '#end'].join('#');
marks.measure = url.toString();
perf.mark(marks.start);
}
const perf = (params && params.request && params.request.collectResourceTiming) ?
new performance.Performance(params.request) : false;

this.loadGeoJSON(params, (err, data) => {
if (err || !data) {
Expand All @@ -182,19 +175,8 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
this.loaded = {};

const result = {};
if (params.request && params.request.collectResourceTiming) {
if (params.request && params.request.collectResourceTiming)
perf.mark(marks.end);
let resourceTimingData = perf.getEntriesByName(params.request.url);
// fallback if web worker implementation of perf.getEntriesByName returns empty
if (marks.start && (resourceTimingData.length === 0)) {
perf.measure(marks.measure, marks.start, marks.end);
resourceTimingData = perf.getEntriesByName(marks.measure);
// cleanup
perf.clearMarks(marks.start);
perf.clearMarks(marks.end);
perf.clearMeasures(marks.measure);
}
if (perf) {
const resourceTimingData = perf.finish();
// it's necessary to eval the result of getEntriesByName() here via parse/stringify
// late evaluation in the main thread causes TypeError: illegal invocation
if (resourceTimingData) {
Expand Down
29 changes: 6 additions & 23 deletions src/source/vector_tile_worker_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import vt from '@mapbox/vector-tile';
import Protobuf from 'pbf';
import WorkerTile from './worker_tile';
import { extend } from '../util/util';
import perf from '../util/performance';
import performance from '../util/performance';

import type {
WorkerSource,
Expand Down Expand Up @@ -102,15 +102,8 @@ class VectorTileWorkerSource implements WorkerSource {
if (!this.loading)
this.loading = {};

const marks = {};
const url = params && params.request && params.request.url;
const collectResourceTiming = params && params.request && params.request.collectResourceTiming;
if (url && collectResourceTiming) {
marks.start = [url, '#start'].join('#');
marks.end = [url, '#end'].join('#');
marks.measure = url.toString();
perf.mark(marks.start);
}
const perf = (params && params.request && params.request.collectResourceTiming) ?
new performance.Performance(params.request) : false;

const workerTile = this.loading[uid] = new WorkerTile(params);
workerTile.abort = this.loadVectorData(params, (err, response) => {
Expand All @@ -124,20 +117,10 @@ class VectorTileWorkerSource implements WorkerSource {
const cacheControl = {};
if (response.expires) cacheControl.expires = response.expires;
if (response.cacheControl) cacheControl.cacheControl = response.cacheControl;

const resourceTiming = {};
if (params.request && params.request.collectResourceTiming) {
if (params.request && params.request.collectResourceTiming)
perf.mark(marks.end);
let resourceTimingData = perf.getEntriesByName(params.request.url);
// fallback if web worker implementation of perf.getEntriesByName returns empty
if (resourceTimingData.length === 0) {
perf.measure(marks.measure, marks.start, marks.end);
resourceTimingData = perf.getEntriesByName(marks.measure);
// cleanup
perf.clearMarks(marks.start);
perf.clearMarks(marks.end);
perf.clearMeasures(marks.measure);
}
if (perf) {
const resourceTimingData = perf.finish();
// it's necessary to eval the result of getEntriesByName() here via parse/stringify
// late evaluation in the main thread causes TypeError: illegal invocation
if (resourceTimingData)
Expand Down
112 changes: 79 additions & 33 deletions src/util/performance.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,85 @@
// @flow

// Wraps performance.getEntriesByName to facilitate testing
import type {RequestParameters} from '../util/ajax';

// Wraps performance to facilitate testing
// Not incorporated into browser.js because the latter is poisonous when used outside the main thread
const performanceExists = typeof performance !== 'undefined';
const exported = {
getEntriesByName: (url: string) => {
if (performanceExists && performance && performance.getEntriesByName)
return performance.getEntriesByName(url);
else
return false;
},
mark: (name: string) => {
if (performanceExists && performance && performance.mark)
return performance.mark(name);
else
return false;
},
measure: (name: string, startMark: string, endMark: string) => {
if (performanceExists && performance && performance.measure)
return performance.measure(name, startMark, endMark);
else
return false;
},
clearMarks: (name: string) => {
if (performanceExists && performance && performance.clearMarks)
return performance.clearMarks(name);
else
return false;
},
clearMeasures: (name: string) => {
if (performanceExists && performance && performance.clearMeasures)
return performance.clearMeasures(name);
else
return false;
}
const wrapper = {};

wrapper.getEntriesByName = (url: string) => {
if (performanceExists && performance && performance.getEntriesByName)
return performance.getEntriesByName(url);
else
return false;
};

wrapper.mark = (name: string) => {
if (performanceExists && performance && performance.mark)
return performance.mark(name);
else
return false;
};

wrapper.measure = (name: string, startMark: string, endMark: string) => {
if (performanceExists && performance && performance.measure)
return performance.measure(name, startMark, endMark);
else
return false;
};

wrapper.clearMarks = (name: string) => {
if (performanceExists && performance && performance.clearMarks)
return performance.clearMarks(name);
else
return false;
};

wrapper.clearMeasures = (name: string) => {
if (performanceExists && performance && performance.clearMeasures)
return performance.clearMeasures(name);
else
return false;
};

export default exported;
/**
* Safe wrapper for the performance resource timing API in web workers with graceful degradation
*
* @param {RequestParameters} request
* @private
*/
class Performance {
_marks: {start: string, end: string, measure: string};

constructor (request: RequestParameters) {
this._marks = {
start: [request.url, 'start'].join('#'),
end: [request.url, 'end'].join('#'),
measure: request.url.toString()
};

wrapper.mark(this._marks.start);
}

finish() {
wrapper.mark(this._marks.end);
let resourceTimingData = wrapper.getEntriesByName(this._marks.measure);

// fallback if web worker implementation of perf.getEntriesByName returns empty
if (resourceTimingData.length === 0) {
wrapper.measure(this._marks.measure, this._marks.start, this._marks.end);
resourceTimingData = wrapper.getEntriesByName(this._marks.measure);

// cleanup
wrapper.clearMarks(this._marks.start);
wrapper.clearMarks(this._marks.end);
wrapper.clearMeasures(this._marks.measure);
}

return resourceTimingData;
}
}

wrapper.Performance = Performance;

export default wrapper;

0 comments on commit 2fea81b

Please sign in to comment.