Skip to content

Instantly share code, notes, and snippets.

@radist2s
Created April 11, 2015 08:36
Show Gist options
  • Save radist2s/9ff67835bd48f4c65e73 to your computer and use it in GitHub Desktop.
Save radist2s/9ff67835bd48f4c65e73 to your computer and use it in GitHub Desktop.
Better Afterlag. Little fork of https://github.com/iserdmi/afterlag-js . Written by using requestAnimationFrame instead setInterval for better results.
/**
* BetterAfterlag 1.0.0 — Plugin for tracking page load lags.
* Author: Alex Batalov
* Based on Afterlag Plugin (https://github.com/iserdmi/afterlag-js) of Sergey Dmitriev (serdmi.com). Licensed MIT.
**/
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([], function () {
return (root.Afterlag = factory());
});
} if (typeof exports === 'object') {
module.exports = factory();
}
else {
root.Afterlag = factory();
}
}(this, function () {
var Afterlag, AfterlagHelper;
AfterlagHelper = (function() {
function AfterlagHelper() {}
AfterlagHelper.merge_options = function(first_object, second_object) {
var el, key, result_object;
result_object = {};
for (key in first_object) {
el = first_object[key];
result_object[key] = el;
}
for (key in second_object) {
el = second_object[key];
result_object[key] = el;
}
return result_object;
};
return AfterlagHelper;
})();
var getTime = (Date.now || function() {
return new Date().getTime();
});
var requestAnimationFrame,
cancelAnimationFrame;
;(function() {
requestAnimationFrame = window.requestAnimationFrame;
cancelAnimationFrame = window.cancelAnimationFrame;
var lastTime = 0,
vendors = ['ms', 'moz', 'webkit', 'o'];
if (!cancelAnimationFrame) {
for (var i = 0; i < vendors.length && !requestAnimationFrame; ++i) {
requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame'];
cancelAnimationFrame =
window[vendors[i] + 'CancelAnimationFrame'] || window[vendors[i] + 'CancelRequestAnimationFrame'];
}
}
}());
Afterlag = (function() {
Afterlag.defaults = {
delay: 200,
frequency: 1000 / 60, //60 fps per second
iterations: 10,
duration: null,
scatter: 10,
min_delta: null,
max_delta: null,
timeout: 1500,
need_lags: false
};
function Afterlag(options) {
var self;
if (options == null) {
options = {};
}
this._set_options(options);
this._callbacks = [];
self = this;
this.ready = false;
this._lags_was = false;
this.status = 'processing';
if (this.options.timeout > 0) {
this._timeout_process = setTimeout(function() {
return self._finish('timeout');
}, this.options.timeout);
}
this._success_iterations = 0;
this._preprocess = setTimeout(function() {
if (!requestAnimationFrame) {
return self._finish('noRequestAnimationFrame');
}
self._last_checked = self._time_started = getTime();
self._last_iteration_duration = 0
return self._process = requestAnimationFrame(function processLoop() {
var delta, elapsed, now;
now = getTime();
elapsed = now - self._last_checked;
delta = elapsed - self._last_iteration_duration;
if (self.options.min_delta < delta && delta < self.options.max_delta) {
if (!self.options.need_lags || self._lags_was) {
self._success_iterations++;
if (self._success_iterations >= self.options.iterations) {
return self._finish('success');
}
}
} else {
self._success_iterations = 0;
self._lags_was = true;
}
self._last_iteration_duration = elapsed;
self._last_checked = now;
self._process = requestAnimationFrame(processLoop)
});
}, this.options.delay);
}
Afterlag.prototype._set_options = function(options) {
this.options = AfterlagHelper.merge_options(this.constructor.defaults, options);
if (this.options.duration != null) {
this.options.iterations = Math.ceil(this.options.duration / this.options.frequency);
}
if (this.options.min_delta == null) {
this.options.min_delta = -this.options.scatter;
}
if (this.options.max_delta == null) {
return this.options.max_delta = this.options.scatter;
}
};
Afterlag.prototype.info = function() {
var now, time_passed;
if (this.time_passed != null) {
time_passed = this.time_passed;
} else {
now = getTime();
time_passed = now - this._time_started;
}
return {
status: this.status,
time_passed: time_passed,
ready: this.ready,
options: this.options
};
};
Afterlag.prototype._finish = function(status) {
var callback, i, len, now, ref, results;
if (this._preprocess != null) {
clearTimeout(this._preprocess);
}
if (this._process != null) {
cancelAnimationFrame && cancelAnimationFrame(this._process);
}
if (this._timeout_process != null) {
clearTimeout(this._timeout_process);
}
this.ready = true;
this.status = status;
now = getTime();
this.time_passed = now - this._time_started;
ref = this._callbacks;
results = [];
for (i = 0, len = ref.length; i < len; i++) {
callback = ref[i];
results.push(callback.fn.call(callback.self, this.info()));
}
return results;
};
Afterlag.prototype["do"] = function(self, fn) {
var ref;
if (fn == null) {
ref = [self, this], fn = ref[0], self = ref[1];
}
if (this.ready) {
fn.call(self, this.info());
} else {
this._callbacks.push({
fn: fn,
self: self
});
}
return this;
};
return Afterlag;
})();
return Afterlag;
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment