├── .gitignore
├── README.md
├── bower.json
├── perf-lib
├── frame-tester.html
└── perf.js
└── sample
├── elements
├── test1-element.html
└── test2-element.html
├── harness.html
├── runner.html
├── test1.html
└── test2.html
/.gitignore:
--------------------------------------------------------------------------------
1 | bower_components
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # polyperf
2 |
3 | `polyperf` is a simple performance testing harness. It loads a series of target pages
4 | (each in their own iframe) a configurable number of times, and displays the successive run
5 | times, as well as the overall minimum.
6 |
7 | ## Installing and running
8 |
9 | Run
10 | ```
11 | bower install
12 | polyserve
13 | ```
14 |
15 | Then navigate to [http://localhost:8080/components/polyperf/sample/runner.html](http://localhost:8080/components/polyperf/sample/runner.html). The results will look something like this:
16 |
17 |
18 |
19 | The tests are run by `runner.html`, which defines the list of tests to run. Edit `runner.html` to choose test pages to run, and how many times each test should be run. By default, each test runs 25 times, but you can configure it by changing the `frame-tester`'s `runs` attribute:
20 |
21 | ```
22 |
23 | ```
24 |
25 | There are two different ways to configure your tests:
26 |
27 | ### Using the harness
28 | Use this approach if you want to test the cost of
29 | an element by repeating it a number of times on the page (by default: 250 times).
30 |
31 | In `runner.html`, modify the array of tests in `document.querySelector('frame-tester').tests` as follows:
32 |
33 | ```
34 | document.querySelector('frame-tester').tests = [
35 | 'harness.html?wc-element=input',
36 | 'harness.html?wc-element=test1-element&wc-path=./elements/test1-element.html',
37 | 'harness.html?wc-element=test2-element&wc-path=./elements/test2-element.html'
38 | ];
39 | ```
40 |
41 | To test a native element (eg. `input`), use `wc-element=input`. To test a custom
42 | element, use `harness.html?wc-element=$name&wc-path=$path`, where `$name` is
43 | the name of the custom element (eg. `paper-input`), and `$path` is the path
44 | to where it lives (eg. `./elements/paper-input/paper-input.html`).
45 |
46 | To configure the number of times the element is repeated in the page, use
47 | the `wc-count` argument:
48 | `harness.html?wc-element=$name&wc-path=$path&wc-count=17`
49 |
50 | Note, the reported results are cummulative, i.e. how long the page with the repeated element took to run.
51 |
52 | ### Using specific tests
53 | Use this approach if you want to repeat a custom test that does something
54 | more than just repeating an element in a page.
55 |
56 | In `runner.html`, modify the array of tests in `document.querySelector('frame-tester').tests` as follows:
57 |
58 | ```
59 | document.querySelector('frame-tester').tests = [
60 | 'test1.html',
61 | 'test2.html'
62 | ];
63 | ```
64 |
65 | Where `test.1.html` is the specific webpage to test. Each test page should include
66 |
67 | ```
68 |
69 | ```
70 |
71 | and call
72 |
73 | ```html
74 |
77 | ```
78 |
79 | before the snippet of code to test, followed by
80 |
81 | ```html
82 |
85 | ```
86 |
87 | after the snippet of code to test.
88 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "polyperf",
3 | "version": "0.9.0",
4 | "license": "http://polymer.github.io/LICENSE.txt",
5 | "ignore": [
6 | "/.*",
7 | "/test/",
8 | "/util/",
9 | "/explainer/",
10 | "/bower_components/",
11 | "gulpfile.js",
12 | "PRIMER.md",
13 | "CONTRIBUTING.md",
14 | "CHANGELOG.md"
15 | ],
16 | "authors": [
17 | "The Polymer Authors (http://polymer.github.io/AUTHORS.txt)"
18 | ],
19 | "repository": {
20 | "type": "git",
21 | "url": "https://github.com/PolymerLabs/polyperf.git"
22 | },
23 | "dependencies": {
24 | "polymer": "Polymer/polymer#^1.4.0"
25 | },
26 | "private": true
27 | }
28 |
--------------------------------------------------------------------------------
/perf-lib/frame-tester.html:
--------------------------------------------------------------------------------
1 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/perf-lib/perf.js:
--------------------------------------------------------------------------------
1 | // x-browser compat.
2 | if (!window.performance) {
3 | var start = Date.now();
4 | // only at millisecond precision
5 | window.performance = {now: function(){ return Date.now() - start }};
6 | }
7 |
8 | console.perf = function() {
9 | if (window.HTMLImports && !HTMLImports.useNative) {
10 | var fn = console._perf.bind(console);
11 | if (!CustomElements.ready) {
12 | addEventListener('HTMLImportsLoaded', fn, true);
13 | } else {
14 | HTMLImports.whenReady(fn);
15 | }
16 | } else {
17 | console._perf();
18 | }
19 | };
20 |
21 | console._perf = function() {
22 | if (window.gc) {
23 | for (var i=0; i<20; i++) {
24 | gc();
25 | }
26 | }
27 | if (console.time) {
28 | console.time('perf');
29 | }
30 | console.profile();
31 | console.perf.time = performance.now();
32 | };
33 |
34 | console.perfEnd = function(info) {
35 | // TODO(sorvell): WCR is unnecessarily delayed via setTimeout to workaround
36 | // https://code.google.com/p/chromium/issues/detail?id=425790.
37 | // This can add significant noise to benchmarking so avoid the wait
38 | // if we know we can (native CE).
39 | // We don't need the workaround for this use case because perfEnd is typically
40 | // called via a blocking script.
41 | if (window.WebComponents && !CustomElements.useNative) {
42 | // TODO(sjmiles): we need some kind of 'whenReady' or other signal
43 | // that will work if this function is called after the event has fired
44 | if (!CustomElements.ready) {
45 | addEventListener('WebComponentsReady', function() {
46 | console._perfEnd(info);
47 | });
48 | } else {
49 | CustomElements.takeRecords();
50 | console._perfEnd(info);
51 | }
52 | } else {
53 | console._perfEnd(info);
54 | }
55 | };
56 |
57 | console._perfEnd = function(info) {
58 | // force layout
59 | document.body.offsetWidth;
60 | var time = performance.now() - console.perf.time;
61 | console.profileEnd();
62 | if (console.time) {
63 | console.timeEnd('perf');
64 | }
65 | document.title = time.toFixed(1) + 'ms: ' + document.title;
66 | if (window.top !== window) {
67 | window.top.postMessage({time: time + 'ms', info: info}, '*');
68 | }
69 | };
70 |
--------------------------------------------------------------------------------
/sample/elements/test1-element.html:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Test Element 1
17 |
18 |
19 |
20 |
30 |
--------------------------------------------------------------------------------
/sample/elements/test2-element.html:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Test Element 2
17 |
18 |
19 |
20 |
30 |
--------------------------------------------------------------------------------
/sample/harness.html:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |