UNPKG

boomerangjs

Version:

boomerang always comes back, except when it hits something

168 lines (141 loc) 4.76 kB
/** * Plugin to measure DNS latency. * * This code is based on Carlos Bueno's guide to DNS on the * [Facebook Note](https://www.facebook.com/note.php?note_id=10150212498738920) * * For information on how to include this plugin, see the {@tutorial building} tutorial. * * ## Setup * * Measuring DNS requires some server-side set up, as * [documented in detail](https://www.facebook.com/note.php?note_id=10150212498738920) by * Facebook engineer Carlos Bueno, so go read his post for everything you'll need to set this up. * * In brief, the points he covers are: * * 1. Set up a wildcard hostname, perferably one that does not share cookies with * your main site. Give it a low TTL, say, 60 seconds, so you don't pollute downstream caches. * 2. Set up a webserver for the wildcard hostname that serves the images named `A.gif` * and `B.gif` (from the `images/` subdirectory) as fast as possible. Make sure * that KeepAlive, Nagle, and any caching headers are turned off. * 3. Include the DNS plugin (see {@tutorial building}) * 4. Tell the DNS plugin where to get its images from * via {@link BOOMR.plugins.DNS.init DNS.base_url} * * Steps 1 and 2 are complicated, and if you don't have full control over your * DNS server, then it may be impossible for you to use this plugin. * * ## Beacon Parameters * * This plugin adds the following parameters to the beacon: * * * `dns.t`: The worst-case DNS latency from the user's browser to your DNS server. * * @class BOOMR.plugins.DNS */ (function() { BOOMR = window.BOOMR || {}; BOOMR.plugins = BOOMR.plugins || {}; if (BOOMR.plugins.DNS) { return; } var impl = { complete: false, base_url: "", t_start: null, t_dns: null, t_http: null, img: null, gen_url: "", start: function() { if (impl.gen_url) { // already running return; } var random = BOOMR.utils.generateId(10); impl.gen_url = impl.base_url.replace(/\*/, random); impl.img = new Image(); impl.img.onload = impl.A_loaded; impl.t_start = new Date().getTime(); impl.img.src = impl.gen_url + "image-l.gif?t=" + random; }, A_loaded: function() { var random = BOOMR.utils.generateId(10); impl.t_dns = new Date().getTime() - impl.t_start; impl.img = new Image(); impl.img.onload = impl.B_loaded; impl.t_start = new Date().getTime(); impl.img.src = impl.gen_url + "image-l.gif?t=" + random; }, B_loaded: function() { impl.t_http = new Date().getTime() - impl.t_start; impl.img = null; impl.done(); }, done: function() { // DNS time is the time to load the image with uncached DNS // minus the time to load the image with cached DNS var dns = impl.t_dns - impl.t_http; BOOMR.addVar("dns.t", dns); impl.complete = true; impl.gen_url = ""; BOOMR.sendBeacon(); } }; BOOMR.plugins.DNS = { /** * Initializes the plugin. * * @param {object} config Configuration * @param {string} config.DNS.base_url The `base_url` parameter tells the DNS * plugin where it can find its DNS testing images. This URL must contain * a wildcard character (`*`) which will be replaced with a random string. * * The images will be appended to this string without any other modification. * * If you have any pages served over HTTPS, then this URL should be configured * to work over HTTPS as well as HTTP. * * The protocol part of the URL will be automatically changed to fit the * current document. * * @returns {@link BOOMR.plugins.DNS} The DNS plugin for chaining * @example * BOOMR.init({ * DNS: { * base_url: "http://*.yoursite.com/images/" * } * }); * @memberof BOOMR.plugins.DNS */ init: function(config) { BOOMR.utils.pluginConfig(impl, config, "DNS", ["base_url"]); if (config && config.wait) { return this; } if (!impl.base_url) { BOOMR.warn("DNS.base_url is not set. Cannot run DNS test.", "dns"); // set to true so that is_complete doesn't block other plugins impl.complete = true; return this; } // do not run test over https if (BOOMR.window.location.protocol === "https:") { impl.complete = true; return this; } BOOMR.subscribe("page_ready", impl.start, null, impl); return this; }, /** * Whether or not this plugin is complete * * @returns {boolean} `true` if the plugin is complete * @memberof BOOMR.plugins.DNS */ is_complete: function() { return impl.complete; } }; }());