Skip to content

Instantly share code, notes, and snippets.

@eliperelman
Last active August 29, 2015 14:02
Show Gist options
  • Save eliperelman/0976c8cae9455dc54fe2 to your computer and use it in GitHub Desktop.
Save eliperelman/0976c8cae9455dc54fe2 to your computer and use it in GitHub Desktop.

Revisions

  1. eliperelman revised this gist Oct 3, 2014. 1 changed file with 10 additions and 35 deletions.
    45 changes: 10 additions & 35 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -49,7 +49,7 @@ In wanting to make this process more intuitive and re-usable, I came up with the
    ### 1. Introduce `PerformanceEvent`
    A new event constructor of `PerformanceEvent` will give us a proper API for triggering events concerned with the timing of key launch phases.
    A new event constructor of `PerformanceEvent` will give us a proper API for triggering events concerned with the timing of any performance indicator. Dispatching a `PerformanceEvent` can then be utilized by the underlying engine (e.g. Gecko) to perform other actions. For example, maybe dispatching a `PerformanceEvent('mozAppVisuallyComplete')` can be utilized by Gecko to perform deterministic first-paints for Firefox OS apps, or relaying these to the Firefox OS System app for other purposes.
    ```
    // Constructor for PerformanceEvent
    @@ -71,7 +71,7 @@ new PerformanceEvent('mozAppLoaded', {
    ### 2. Introduce `performancetiming` event
    With a standard `performancetiming` event, the application as well as the underlying engine can be aware of the exact occurrence of launch or performance events.
    With a standard `performancetiming` event, an application can have a decoupled mechanism for being aware of the exact occurrence of launch or performance events.
    ```javascript
    // Usage
    @@ -89,21 +89,21 @@ window.addEventListener('performancetiming', function (e) {
    ### 3. Propose inclusion of performance events on `window.performance.timing`
    In order to save from having to bind event handlers up front, it would be better for testing if we could attach after the fact and still get the valued performance launch data. This is, in fact, how the `window.performance.timing` hash currently works. Throughout the load lifecycle of an application, several standardized timings are captured and populated by the engine into `window.performance.timing`, each property the name of a timing event, which is mapped to a timestamp (Unix epoch in Gecko, high-resolution timestamp in Blink). I would like to see us able to automatically publish abitrary keys into `window.performance.timing` which contain relevant and useful timings for later retrieval.
    In order to save from having to bind event handlers up front, it would be better for testing if we could attach after the fact and still get the valued performance launch data. This is, in fact, how the `window.performance.timing` hash currently works. Throughout the load lifecycle of an application, several standardized timings are captured and populated by the engine into `window.performance.timing`, each property the name of a timing event, which is mapped to a timestamp (Unix epoch in Gecko, high-resolution timestamp in Blink). I would like to see us able to automatically publish abitrary keys into `window.performance.timing` which contain relevant and useful timings for later retrieval. With a standard cache for containing all aggregated performance events that have occurred with the current application, we have an easy place to calculate deltas of the duration of these important events.
    I propose that new properties are added to `window.performance.timing` every time a new `PerformanceEvent` is dispatched.
    ```javascript
    window.performance.timing.requestStart; // 1402552218684
    window.performance.timing.mozContentInteractive; // 1402555613020
    window.performance.timing.navigationStart; // 1402552218684
    window.performance.timing.mozAppVisuallyComplete; // 1402555613020
    ```
    ```javascript
    window.dispatchEvent(new PerformanceEvent('mozContentInteractive'));
    window.dispatchEvent(new PerformanceEvent('mozAppVisuallyComplete'));

    ...

    window.performance.timing.mozContentInteractive; // 1402555613020
    window.performance.timing.mozAppVisuallyComplete; // 1402555613020
    ```
    If you are concerned about adding vendor specific timings here, note that the [W3C recommendation](http://www.w3.org/TR/navigation-timing/#vendor-prefixes) technically allows these extensions provided they follow the established conventions and are prefixed with `moz`.
    @@ -119,8 +119,8 @@ window.addEventListener('performancetiming', function (e) {
    }

    console.log(
    window.performance.timing.mozContentInteractive -
    window.performance.timing.requestStart
    window.performance.timing.mozAppVisuallyComplete -
    window.performance.timing.navigationStart
    ); // 3394336
    });
    ```
    @@ -135,32 +135,7 @@ Attempting to solve the previously outlined limitations:
    2. With no listener script, launch timings are no longer affected by the capturing of metrics.
    3. No listener script means no duplication or maintainability concerns.
    4. Applications that want to time performance events outside of the standard platform launch events can do so easily by just dispatching a `PerformanceEvent`.
    5. Efficiency is improved by pushing logic into a standardized system which can be re-used from the platform level.
    ## Viability
    As a proof of concept, I was able to successfully create and trigger custom `PeformanceEvent`s with a minimal polyfill.
    ```javascript
    // dirty PerformanceEvent polyfill
    window.PerformanceEvent = function (timing, props) {
    var event = new Event('performancetiming', props);
    event.timing = timing;
    return event;
    };

    PerformanceEvent.prototype = Object.create(Event.prototype);
    PerformanceEvent.prototype.constructor = PerformanceEvent;
    ```
    ```javascript
    window.addEventListener('performancetiming', function (e) {
    console.log('[%d] %s Peformance Event', e.timeStamp, e.timing);
    });

    window.dispatchEvent(new PerformanceEvent('mozContentInteractive'));
    // [1402555613020] mozContentInteractive Performance Event
    ```
    5. Efficiency is improved by pushing logic into a standardized system which can be re-used from the platform level, e.g. usage with Gecko or relaying to the System app.
    ## Conclusion
  2. eliperelman revised this gist Jul 22, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion thoughts.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    ## Problem

    The current process of timing the launching of Firefox OS applications is tricky. At the time of writing, most tests rely on the firing of the `window` `onload` event in order to determine when it is ready to use. Unfortunately with the state of dynamic script and view loading, it's impossible to tell when an application is truly ready to be interacted with. The loading of these assets can be deferred, sometimes even to the point where it occurs after `window` `onload`. If we want to hold an application accountable to recommended launch times, engineers need only defer more loading until the test measurement completes in order to make metrics look attractive. Couple this with the fact that the event isn't truly indicative of user interactivity and you can see that the current state is unsustrainable.
    The current process of timing the launching of Firefox OS applications is tricky. At the time of writing, most tests rely on the firing of the `window` `onload` event in order to determine when it is ready to use. Unfortunately with the state of dynamic script and view loading, it's impossible to tell when an application is truly ready to be interacted with. The loading of these assets can be deferred, sometimes even to the point where it occurs after `window` `onload`. If we want to hold an application accountable to recommended launch times, engineers need only defer more loading until the test measurement completes in order to make metrics look attractive. Couple this with the fact that the event isn't truly indicative of user interactivity and you can see that the current state is unsustainable.

    ## Interim Solution

  3. eliperelman revised this gist Jul 19, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion thoughts.md
    Original file line number Diff line number Diff line change
    @@ -164,4 +164,4 @@ window.dispatchEvent(new PerformanceEvent('mozContentInteractive'));
    ## Conclusion
    Our current methodology for conducting automated performance testing is functional, but can be improved and expanded on. By opening up and leveraging existing and familiar web APIs, we can improve the intuitiveness of the testing, and hence encouage more engineers to outfit their applications for performance evalation. These changes will also give a richer indicator to the platform for making further optimizations to the loading of applications. I also believe that through these efforts we can improve the tooling and ease its implementation, creating better value for the web.
    Our current methodology for conducting automated performance testing is functional, but can be improved and expanded on. By opening up and leveraging existing and familiar web APIs, we can improve the intuitiveness of the testing, and hence encouage more engineers to outfit their applications for performance evaluation. These changes will also give a richer indicator to the platform for making further optimizations to the loading of applications. I also believe that through these efforts we can improve the tooling and ease its implementation, creating better value for the web.
  4. eliperelman revised this gist Jul 19, 2014. 1 changed file with 5 additions and 6 deletions.
    11 changes: 5 additions & 6 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -131,12 +131,11 @@ Applications can get the data about their own loading lifecycle, and can be info
    Attempting to solve the previously outlined limitations:
    1. No external script is needed to capture the events, meaning no miss values. Data is cached by the platform and stored in `window.performance.timing`. No dependency qualms.
    2. In order to catch the performance event, the script which listens for the event must be included prior to the firing of the event. This has the potential to miss events if fired out of order and causes undue dependencies, violating Inversion of Control.
    3. With no listener script, launch timings are no longer affected by the capturing of metrics.
    4. No listener script means no duplication or maintainability concerns.
    5. Applications that want to time performance events outside of the standard platform launch events can do so easily by just dispatching a `PerformanceEvent`.
    6. Efficiency is improved by pushing logic into a standardized system which can be re-used from the platform level.
    1. No external script is needed to capture the events, meaning no missed values. Data is cached by the platform and stored in `window.performance.timing`. No dependency qualms.
    2. With no listener script, launch timings are no longer affected by the capturing of metrics.
    3. No listener script means no duplication or maintainability concerns.
    4. Applications that want to time performance events outside of the standard platform launch events can do so easily by just dispatching a `PerformanceEvent`.
    5. Efficiency is improved by pushing logic into a standardized system which can be re-used from the platform level.
    ## Viability
  5. eliperelman revised this gist Jun 12, 2014. 1 changed file with 10 additions and 0 deletions.
    10 changes: 10 additions & 0 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -91,11 +91,21 @@ window.addEventListener('performancetiming', function (e) {
    In order to save from having to bind event handlers up front, it would be better for testing if we could attach after the fact and still get the valued performance launch data. This is, in fact, how the `window.performance.timing` hash currently works. Throughout the load lifecycle of an application, several standardized timings are captured and populated by the engine into `window.performance.timing`, each property the name of a timing event, which is mapped to a timestamp (Unix epoch in Gecko, high-resolution timestamp in Blink). I would like to see us able to automatically publish abitrary keys into `window.performance.timing` which contain relevant and useful timings for later retrieval.
    I propose that new properties are added to `window.performance.timing` every time a new `PerformanceEvent` is dispatched.
    ```javascript
    window.performance.timing.requestStart; // 1402552218684
    window.performance.timing.mozContentInteractive; // 1402555613020
    ```
    ```javascript
    window.dispatchEvent(new PerformanceEvent('mozContentInteractive'));

    ...

    window.performance.timing.mozContentInteractive; // 1402555613020
    ```
    If you are concerned about adding vendor specific timings here, note that the [W3C recommendation](http://www.w3.org/TR/navigation-timing/#vendor-prefixes) technically allows these extensions provided they follow the established conventions and are prefixed with `moz`.
    ### 4. Allow all members of `window.performance.timing` to fire `performancetiming`
  6. eliperelman revised this gist Jun 12, 2014. 1 changed file with 0 additions and 16 deletions.
    16 changes: 0 additions & 16 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -117,22 +117,6 @@ window.addEventListener('performancetiming', function (e) {
    Applications can get the data about their own loading lifecycle, and can be informed throughout the process as well (for stages that are relevant and available at the time of loading) for built-in timings as well as custom timings.
    ### 5. Optional: Convert `window.performance.timing`s to use High-Resolution Timers
    Our current measurements for launch lifecycle are completed with high-resolution timers gathered from `window.performance.now()`. For parity with these measurements, stored timing values should also use high-resolution timers.
    As a side note, I feel that any browser that implements [`window.performance.timing`](http://www.w3.org/TR/navigation-timing/) along with [high-resolution timing](http://www.w3.org/TR/hr-time/) should have its performance values indicated in high-resolution times. The standard allows for this, and the precedent is already there with Chrome.
    ```javascript
    // Current
    window.performance.timing.requestStart; // 1402552218684
    window.performance.timing.mozContentInteractive; // 1402555613020

    // Proposed
    window.performance.timing.requestStart; // 3669154.52043
    window.performance.timing.mozContentInteractive; // 3675353.7010230003
    ```
    ## Benefits
    Attempting to solve the previously outlined limitations:
  7. eliperelman revised this gist Jun 12, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion thoughts.md
    Original file line number Diff line number Diff line change
    @@ -100,7 +100,7 @@ If you are concerned about adding vendor specific timings here, note that the [W
    ### 4. Allow all members of `window.performance.timing` to fire `performancetiming`
    Coming full circle, it would then make sense for any entry in `window.performance.timing` to automatically create a `PerformanceEvent` resulting in a `performancetiming` event.
    Coming full circle, it would then make sense for any entry in `window.performance.timing` to automatically create a `PerformanceEvent` resulting in a `performancetiming` event. This would include standardized timings such as `navigationStart`, `requestStart`, and `responseEnd` to fire the `performancetiming` event in addition to the custom ones needed by applications.
    ```javascript
    window.addEventListener('performancetiming', function (e) {
  8. eliperelman revised this gist Jun 12, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    ## Problem

    The current process of timing the launching of Firefox OS applications is tricky. At the time of writing, most tests rely on the firing of the `window` `onload` event in order to determine when it is ready to use. Unfortunately with the state of dynamic script and view loading, it's impossible to tell when an application is truly ready to be interacted with. The loading of these assets can be deferred, sometimes even to the point where it occurs after `window` `onload`. If we want to hold an application accountable to recommended launch times, engineers need only defer more loading until the test measurement completes in order to make metrics look attractive. Couple this with the fact that the event isn't truly indicative of user interactivity and you can see that the current state is unsustainable.
    The current process of timing the launching of Firefox OS applications is tricky. At the time of writing, most tests rely on the firing of the `window` `onload` event in order to determine when it is ready to use. Unfortunately with the state of dynamic script and view loading, it's impossible to tell when an application is truly ready to be interacted with. The loading of these assets can be deferred, sometimes even to the point where it occurs after `window` `onload`. If we want to hold an application accountable to recommended launch times, engineers need only defer more loading until the test measurement completes in order to make metrics look attractive. Couple this with the fact that the event isn't truly indicative of user interactivity and you can see that the current state is unsustrainable.

    ## Interim Solution

    @@ -89,7 +89,7 @@ window.addEventListener('performancetiming', function (e) {
    ### 3. Propose inclusion of performance events on `window.performance.timing`
    In order to save from having bind event handlers up front, it would be better for testing if we could attach after the fact and still get the valued performance launch data. This is, in fact, how the `window.performance.timing` hash currently works. Throughout the load lifecycle of an application, several standardized timings are captured and populated by the engine into `window.performance.timing`, each property the name of a timing event, which is mapped to a timestamp (Unix epoch in Gecko, high-resolution timestamp in Blink). I would like to see us able to automatically publish abitrary keys into `window.performance.timing` which contain relevant and useful timings for later retrieval.
    In order to save from having to bind event handlers up front, it would be better for testing if we could attach after the fact and still get the valued performance launch data. This is, in fact, how the `window.performance.timing` hash currently works. Throughout the load lifecycle of an application, several standardized timings are captured and populated by the engine into `window.performance.timing`, each property the name of a timing event, which is mapped to a timestamp (Unix epoch in Gecko, high-resolution timestamp in Blink). I would like to see us able to automatically publish abitrary keys into `window.performance.timing` which contain relevant and useful timings for later retrieval.
    ```javascript
    window.performance.timing.requestStart; // 1402552218684
  9. eliperelman revised this gist Jun 12, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion thoughts.md
    Original file line number Diff line number Diff line change
    @@ -71,7 +71,7 @@ new PerformanceEvent('mozAppLoaded', {
    ### 2. Introduce `performancetiming` event
    With a standard `performancetiming` event, the application as well as the underlying engine can be aware of the exact occurances of launch or performance events.
    With a standard `performancetiming` event, the application as well as the underlying engine can be aware of the exact occurrence of launch or performance events.
    ```javascript
    // Usage
  10. eliperelman revised this gist Jun 12, 2014. 1 changed file with 3 additions and 5 deletions.
    8 changes: 3 additions & 5 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -151,11 +151,9 @@ As a proof of concept, I was able to successfully create and trigger custom `Pef
    ```javascript
    // dirty PerformanceEvent polyfill
    window.PerformanceEvent = function (timing, props) {
    var event = new Event('performancetiming', props);

    event.timing = timing;

    return event;
    var event = new Event('performancetiming', props);
    event.timing = timing;
    return event;
    };

    PerformanceEvent.prototype = Object.create(Event.prototype);
  11. eliperelman revised this gist Jun 12, 2014. 1 changed file with 11 additions and 1 deletion.
    12 changes: 11 additions & 1 deletion thoughts.md
    Original file line number Diff line number Diff line change
    @@ -115,13 +115,23 @@ window.addEventListener('performancetiming', function (e) {
    });
    ```
    Applications can get the data about their own loading lifecycle, and can be informed throughout the process as well (for stages that are relevant and available at the time of loading) for built-in timings as well as custom timings.
    ### 5. Optional: Convert `window.performance.timing`s to use High-Resolution Timers
    Our current measurements for launch lifecycle are completed with high-resolution timers gathered from `window.performance.now()`. For parity with these measurements, stored timing values should also use high-resolution timers.
    As a side note, I feel that any browser that implements [`window.performance.timing`](http://www.w3.org/TR/navigation-timing/) along with [high-resolution timing](http://www.w3.org/TR/hr-time/) should have its performance values indicated in high-resolution times. The standard allows for this, and the precedent is already there with Chrome.
    So not only can applications get the data about their own loading lifecycle, but can be informed throughout the process as well (for stages that are relevant and available at the time of loading).
    ```javascript
    // Current
    window.performance.timing.requestStart; // 1402552218684
    window.performance.timing.mozContentInteractive; // 1402555613020

    // Proposed
    window.performance.timing.requestStart; // 3669154.52043
    window.performance.timing.mozContentInteractive; // 3675353.7010230003
    ```
    ## Benefits
  12. eliperelman revised this gist Jun 12, 2014. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -96,6 +96,8 @@ window.performance.timing.requestStart; // 1402552218684
    window.performance.timing.mozContentInteractive; // 1402555613020
    ```
    If you are concerned about adding vendor specific timings here, note that the [W3C recommendation](http://www.w3.org/TR/navigation-timing/#vendor-prefixes) technically allows these extensions provided they follow the established conventions and are prefixed with `moz`.
    ### 4. Allow all members of `window.performance.timing` to fire `performancetiming`
    Coming full circle, it would then make sense for any entry in `window.performance.timing` to automatically create a `PerformanceEvent` resulting in a `performancetiming` event.
    @@ -113,6 +115,12 @@ window.addEventListener('performancetiming', function (e) {
    });
    ```
    ### 5. Optional: Convert `window.performance.timing`s to use High-Resolution Timers
    Our current measurements for launch lifecycle are completed with high-resolution timers gathered from `window.performance.now()`. For parity with these measurements, stored timing values should also use high-resolution timers.
    As a side note, I feel that any browser that implements [`window.performance.timing`](http://www.w3.org/TR/navigation-timing/) along with [high-resolution timing](http://www.w3.org/TR/hr-time/) should have its performance values indicated in high-resolution times. The standard allows for this, and the precedent is already there with Chrome.
    So not only can applications get the data about their own loading lifecycle, but can be informed throughout the process as well (for stages that are relevant and available at the time of loading).
    ## Benefits
  13. eliperelman revised this gist Jun 12, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion thoughts.md
    Original file line number Diff line number Diff line change
    @@ -155,4 +155,4 @@ window.dispatchEvent(new PerformanceEvent('mozContentInteractive'));
    ## Conclusion
    Our current methodology for conducting automated performance testing is functional, but can be improved and expanded on. By opening up and leveraging existing and familiar web APIs, we can improve the intuitiveness of the testing, and hence encouage more engineers to outfit their applications for performance evalation. These changes will also give a richer indicator to the platform for making further optimizations to the loading of applications.
    Our current methodology for conducting automated performance testing is functional, but can be improved and expanded on. By opening up and leveraging existing and familiar web APIs, we can improve the intuitiveness of the testing, and hence encouage more engineers to outfit their applications for performance evalation. These changes will also give a richer indicator to the platform for making further optimizations to the loading of applications. I also believe that through these efforts we can improve the tooling and ease its implementation, creating better value for the web.
  14. eliperelman revised this gist Jun 12, 2014. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -106,9 +106,10 @@ window.addEventListener('performancetiming', function (e) {
    return;
    }

    var timing = window.performance.timing;

    console.log(timing.mozContentInteractive - timing.requestStart); // 3394336
    console.log(
    window.performance.timing.mozContentInteractive -
    window.performance.timing.requestStart
    ); // 3394336
    });
    ```
  15. eliperelman created this gist Jun 12, 2014.
    157 changes: 157 additions & 0 deletions thoughts.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,157 @@
    ## Problem

    The current process of timing the launching of Firefox OS applications is tricky. At the time of writing, most tests rely on the firing of the `window` `onload` event in order to determine when it is ready to use. Unfortunately with the state of dynamic script and view loading, it's impossible to tell when an application is truly ready to be interacted with. The loading of these assets can be deferred, sometimes even to the point where it occurs after `window` `onload`. If we want to hold an application accountable to recommended launch times, engineers need only defer more loading until the test measurement completes in order to make metrics look attractive. Couple this with the fact that the event isn't truly indicative of user interactivity and you can see that the current state is unsustainable.

    ## Interim Solution

    I suggested that if we were to get an accurate pulse on when launch times occur, it was going to take being told by the application itself. There are techniques we can use to try and infer when this occurs, but it will most likely be inaccurate, latent, or not verbose enough to outline the many stages of the application launch lifecycle.

    I then proposed a series of application-raised events that would cover the launch lifecycle that would be generic between all applications. Suggestions by others brought to my attention the need for these events to also be consumed by the platform itself as indicators for usage beyond performance testing (at the time I was only looking to improve the situation for gathering metrics on the performance lifecycle). At the present time, these events are outlined and raised as follows (and outlined in [bug 996038](https://bugzilla.mozilla.org/show_bug.cgi?id=996038)):

    ```javascript
    // This particular event denotes an app has loaded
    // and bound the events needed to interact with its core UI
    window.dispatchEvent(new CustomEvent('moz-content-interactive'));
    ```

    In order for the event to be useful for performance testing, each application includes a script which listens for these events so they can be re-triggered and picked up by the testing harness (script abbreviated for clarity):

    ```javascript
    window.addEventListener('moz-content-interactive', function () {
    if (!window.mozPerfHasListener) {
    return;
    }

    var now = window.performance.now();

    setTimeout(function () {
    window.dispatchEvent(new CustomEvent('x-moz-perf', {
    detail: {
    name: 'moz-content-interactive',
    timestamp: now
    }
    });
    });
    });
    ```
    So we listen for the custom events, capture the timestamp, and re-broadcast to the generic event the testing harness is listening to. While this works as an interim solution, I still believe it has limitations:
    1. In order to catch the performance event, the script which listens for the event must be included prior to the firing of the event. This has the potential to miss events if fired out of order and causes undue dependencies, violating Inversion of Control.
    2. The inclusion of the listener script itself will affect the launch timings.
    3. The listener script must be individually included for every concerned application, causing either duplication concerns or maintainability problems when copied and revisions are made.
    4. Applications wanting timing metrics for custom events not generic to all applications must bypass the intuitiveness of the `window` event dispatching and must trigger the low-level event manually.
    5. The performance listener script is not efficient and will need modification for new standardized launch metrics.
    ## Longer-term Idea
    In wanting to make this process more intuitive and re-usable, I came up with the following idea for expanding the web APIs which I believe solve many of the previous concerns.
    ### 1. Introduce `PerformanceEvent`
    A new event constructor of `PerformanceEvent` will give us a proper API for triggering events concerned with the timing of key launch phases.
    ```
    // Constructor for PerformanceEvent
    [Partial]
    [Constructor(DOMString timing, optional EventInit eventInitDict)]
    interface PerformanceEvent : Event {
    ...
    }
    ```
    ```javascript
    // Usage
    new PerformanceEvent('mozContentInteractive');

    new PerformanceEvent('mozAppLoaded', {
    detail: { example: 'property' }
    });
    ```
    ### 2. Introduce `performancetiming` event
    With a standard `performancetiming` event, the application as well as the underlying engine can be aware of the exact occurances of launch or performance events.
    ```javascript
    // Usage
    window.addEventListener('performancetiming', function (e) {
    // e is a PerformanceEvent

    e.timing; // e.g. mozContentInteractive, mozAppLoaded, etc.

    // we still have access to standard properties, and importantly,
    // we have access to when the event was triggered, saving us from
    // having to manually capture when the event occurred
    e.timeStamp;
    });
    ```
    ### 3. Propose inclusion of performance events on `window.performance.timing`
    In order to save from having bind event handlers up front, it would be better for testing if we could attach after the fact and still get the valued performance launch data. This is, in fact, how the `window.performance.timing` hash currently works. Throughout the load lifecycle of an application, several standardized timings are captured and populated by the engine into `window.performance.timing`, each property the name of a timing event, which is mapped to a timestamp (Unix epoch in Gecko, high-resolution timestamp in Blink). I would like to see us able to automatically publish abitrary keys into `window.performance.timing` which contain relevant and useful timings for later retrieval.
    ```javascript
    window.performance.timing.requestStart; // 1402552218684
    window.performance.timing.mozContentInteractive; // 1402555613020
    ```
    ### 4. Allow all members of `window.performance.timing` to fire `performancetiming`
    Coming full circle, it would then make sense for any entry in `window.performance.timing` to automatically create a `PerformanceEvent` resulting in a `performancetiming` event.
    ```javascript
    window.addEventListener('performancetiming', function (e) {
    if (!e.timing === 'mozAppLoaded') {
    return;
    }

    var timing = window.performance.timing;

    console.log(timing.mozContentInteractive - timing.requestStart); // 3394336
    });
    ```
    So not only can applications get the data about their own loading lifecycle, but can be informed throughout the process as well (for stages that are relevant and available at the time of loading).
    ## Benefits
    Attempting to solve the previously outlined limitations:
    1. No external script is needed to capture the events, meaning no miss values. Data is cached by the platform and stored in `window.performance.timing`. No dependency qualms.
    2. In order to catch the performance event, the script which listens for the event must be included prior to the firing of the event. This has the potential to miss events if fired out of order and causes undue dependencies, violating Inversion of Control.
    3. With no listener script, launch timings are no longer affected by the capturing of metrics.
    4. No listener script means no duplication or maintainability concerns.
    5. Applications that want to time performance events outside of the standard platform launch events can do so easily by just dispatching a `PerformanceEvent`.
    6. Efficiency is improved by pushing logic into a standardized system which can be re-used from the platform level.
    ## Viability
    As a proof of concept, I was able to successfully create and trigger custom `PeformanceEvent`s with a minimal polyfill.
    ```javascript
    // dirty PerformanceEvent polyfill
    window.PerformanceEvent = function (timing, props) {
    var event = new Event('performancetiming', props);

    event.timing = timing;

    return event;
    };

    PerformanceEvent.prototype = Object.create(Event.prototype);
    PerformanceEvent.prototype.constructor = PerformanceEvent;
    ```
    ```javascript
    window.addEventListener('performancetiming', function (e) {
    console.log('[%d] %s Peformance Event', e.timeStamp, e.timing);
    });

    window.dispatchEvent(new PerformanceEvent('mozContentInteractive'));
    // [1402555613020] mozContentInteractive Performance Event
    ```
    ## Conclusion
    Our current methodology for conducting automated performance testing is functional, but can be improved and expanded on. By opening up and leveraging existing and familiar web APIs, we can improve the intuitiveness of the testing, and hence encouage more engineers to outfit their applications for performance evalation. These changes will also give a richer indicator to the platform for making further optimizations to the loading of applications.