UNPKG

ember-keen

Version:

An Ember add-on to work with Keen.IO

188 lines (162 loc) 5.07 kB
import { inject as service } from '@ember/service'; import { set, get } from '@ember/object'; import Mixin from '@ember/object/mixin'; import { typeOf as getTypeOf } from '@ember/utils'; import { run } from '@ember/runloop'; import RSVP from 'rsvp'; import { assert, deprecate } from '@ember/debug'; /** * A mixin to track page views with Keen.IO. * * @namespace EmberKeen.Mixin * @class KeenTrackPageview * @extends Ember.Mixin * @public */ export default Mixin.create({ keen: service(), /** * This property is set to true when the performance tracking has already started before this route is entered. * This means that the model_load_time will include time from the parent route. * * @property _wasAlreadyTracking * @type {Boolean} * @default false * @protected */ _wasAlreadyTracking: false, /** * Setup a listener to check how long the page view took. * * @method beforeModel * @param {Transition} transition * @override * @return {*} * @public */ beforeModel() { assert('You have set up automatic page view tracking - please remove the KeenTrackPageView mixin', !this.keen._isTrackingPageViews); deprecate('The keen page view mixin has been deprecated in favor of using `keen.trackAllPageViews()`, which will automate tracking over all pages. This requires ember-source@3.6 to work.', false, { id: 'ember-keen.page-view-mixin', until: '4.0.0' }); this._setLoadTrackStart(); return this._super(...arguments); }, /** * Set the start time of the page load on the keen service. * * @method _setLoadTrackStart * @protected */ _setLoadTrackStart() { let keen = get(this, 'keen'); if (keen.isPerformanceTracking('page-view')) { set(this, '_wasAlreadyTracking', true); } keen.startPerformanceTrack('page-view'); }, /** * Get the query params for tracking the page view. * * @method _getTrackingParams * @return {Object} * @protected */ _getTrackingParams() { return this.paramsFor(get(this, 'routeName')) || {}; }, /** * Get the route name of the page to track. * * @method _getTrackingRouteName * @return {String} * @protected */ _getTrackingRouteName() { // In engines, fullRouteName will give you the full path return get(this, 'fullRouteName') || get(this, 'routeName'); }, /** * Get the time it took to enter the route * * @method _getPageLoadTime * @return {Number} * @protected */ _getPageLoadTime() { return get(this, 'keen').endPerformanceTrack('page-view'); }, /** * Get the render time. * This returns a promise that resolves after rendering. * * @method _getPageRenderTime * @return {RSVP.Promise<Number>} * @protected */ _getPageRenderTime() { let keen = get(this, 'keen'); keen.startPerformanceTrack('page-view-render-time'); return new RSVP.Promise((resolve) => { run.schedule('afterRender', this, function() { let timeDiff = keen.endPerformanceTrack('page-view-render-time'); resolve(timeDiff); }); }); }, /** * Get the render time, and then track the page view. * * @method _trackPageViewWithRender * @private */ _trackPageViewWithRender() { this._getPageRenderTime().then(this._trackPageView.bind(this)); }, /** * Track a page view for a given transition with Keen.IO. * * @method _trackPageView * @protected */ _trackPageView(renderTime = 0) { let keen = get(this, 'keen'); if (!renderTime || getTypeOf(renderTime) !== 'number') { renderTime = 0; } let queryParams = this._getTrackingParams(); let routeName = this._getTrackingRouteName(); let modelLoadTime = this._getPageLoadTime(); // If the performance tracking started before this route, it means that it includes load time from it's parent // This can have an effect on the model load time, and thus can be used to further drill down into load times let wasAlreadyTracking = get(this, '_wasAlreadyTracking'); set(this, '_wasAlreadyTracking', false); let totalTime = renderTime + (modelLoadTime || 0); /* eslint-disable camelcase */ let keenData = { page: routeName, query_params: queryParams, previous_page: get(keen, '_previousPage'), performance: { total_time: totalTime, model_load_time: modelLoadTime, render_time: renderTime, total_time_seconds: (totalTime / 1000).toFixed(2) * 1, model_load_time_seconds: (modelLoadTime / 1000).toFixed(2) * 1, render_time_seconds: (renderTime / 1000).toFixed(2) * 1, model_load_time_includes_parent: wasAlreadyTracking } }; set(keen, '_previousPage', { page: keenData.page, query_params: keenData.query_params }); /* eslint-enable camelcase */ keen.sendEvent('page-view', keenData); }, actions: { didTransition() { this._super(...arguments); this._trackPageViewWithRender(); return true; } } });