# Tracking render performance

**URL:** <https://discourse.aurelia.io/t/tracking-render-performance/1681>\
**Category:** Help Requests\
**Created:** [September 27, 2018, 3:58pm UTC](https://discourse.aurelia.io/t/tracking-render-performance/1681 "2018-09-27T15:58:20Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![fragsalat](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/fragsalat/32/270_2.png) [@fragsalat](https://discourse.aurelia.io/u/fragsalat)\
**Post date:** [September 27, 2018, 3:58pm UTC](https://discourse.aurelia.io/t/tracking-render-performance/1681/1 "2018-09-27T15:58:20Z")

</div>

Hey folks,

I want to track the performance of my site to get a baseline for improvements. I would do this via Analytics but I have the problem that I can not track the actual cost of aurelia. I’m able to track until the data is in the view model but as there can be quite a big dom as result of the data passed in it’s possible that the rendered result is visible over one second later to the user as the data was injected into the view.

I’ve already had a look at the event aggregator if there are any events published. Do you know any possibility to track when aurelia finished updating the expressions?

Thanks in advance

Best  
FragSalat

---

<div class="post-metadata">

**Author:** ![huochunpeng](https://avatars.discourse-cdn.com/v4/letter/h/49beb7/32.png) [@huochunpeng](https://discourse.aurelia.io/u/huochunpeng)\
**Post date:** [September 27, 2018, 9:43pm UTC](https://discourse.aurelia.io/t/tracking-render-performance/1681/2 "2018-09-27T21:43:58Z")

</div>

Correct me if I am wrong.  
Aurelia rendering is done by flushing micro task queue (an array of rendering tasks), You can monkey patch TaskQueue implementation to set a timer check.

```auto
queueMicroTask(task: Task | Function): void {
  if (this.microTaskQueue.length < 1) {
// record start time here
    this.requestFlushMicroTaskQueue();
  }

  if (this.longStacks) {
    task.stack = this.prepareQueueStack(microStackSeparator);
  }

  this.microTaskQueue.push(task);
}

flushMicroTaskQueue(): void {
  let queue = this.microTaskQueue;
  this._flushQueue(queue, this.microTaskQueueCapacity);
  queue.length = 0;
// record end time here, then get consumed time of rendering
}

```

---

<div class="post-metadata">

**Author:** ![fragsalat](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/fragsalat/32/270_2.png) [@fragsalat](https://discourse.aurelia.io/u/fragsalat)\
**Post date:** [September 28, 2018, 8:52am UTC](https://discourse.aurelia.io/t/tracking-render-performance/1681/3 "2018-09-28T08:52:34Z")

</div>

Indeed this is a very hacky but possible solution. One problem I have here is that the queues are flushed multiple times and I would have to catch the last one. So this will be the problem in this case. I’ll analyze it if I could do a timeout on flushing and if it hits I track the last recorded time.

---

<div class="post-metadata">

**Author:** ![fragsalat](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/fragsalat/32/270_2.png) [@fragsalat](https://discourse.aurelia.io/u/fragsalat)\
**Post date:** [September 28, 2018, 11:41am UTC](https://discourse.aurelia.io/t/tracking-render-performance/1681/4 "2018-09-28T11:41:28Z")

</div>

FYI: This solution worked until now quite good. I’m now able to track when the page rendered. Sometimes there might be another render event fired because of late evaluated binding behaviors but this is catchable with a variable to only track it once. Keep in mind that the timeout add’s 1s to the tracked time which must be removed. Here is my solution.

```auto
/**
 * Extend original function with additional functionality
 * @param {Object} proto
 * @param {string} fnName
 * @param {Function} callback
 */
export function extendFn(proto: Object, fnName: string, callback: Function): void {
  const origFn = proto[fnName];
  proto[fnName] = function extendedFn() {
    let result;
    if (typeof origFn === 'function') {
      result = origFn.apply(this, arguments);
    }
    callback.apply(this, arguments);
    return result;
  };
}

/**
 * Hook into micro task queue to track when rendering is finished
 * @param {TaskQueue} taskQueue
 * @param {EventAggregator} events
 */
function hookRendering(taskQueue: TaskQueue, events: EventAggregator): void {
  let timeoutHandle;
  extendFn(taskQueue, 'flushMicroTaskQueue', () => {
    if (timeoutHandle) {
      clearTimeout(timeoutHandle);
    }
    const actual = performance.now();
    timeoutHandle = setTimeout(() => {
      events.publish('app.rendered', performance.now() - actual);
    }, 1000);
  });
}

```

The actual page load time can be tracked this way:

```auto
let initialPageLoad = true;
events.subscribe('app.rendered', delta => {
  if (initialPageLoad) {
    initialPageLoad = false;
    log.debug(`Page loaded in ${performance.now() - delta}ms`);
  }
})

```

---

<div class="post-metadata">

**Author:** ![vegarringdal](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/vegarringdal/32/248_2.png) [@vegarringdal](https://discourse.aurelia.io/u/vegarringdal)\
**Post date:** [September 28, 2018, 5:00pm UTC](https://discourse.aurelia.io/t/tracking-render-performance/1681/5 "2018-09-28T17:00:37Z")

</div>

> **[Try Lighthouse  |  Tools for Web Developers
       | ...](https://developers.google.com/web/tools/lighthouse/run)**
>
> Run Lighthouse against any site.

why not use lighthouse for something like this?  
you get a nice report.  
using puppeteer/npm module of lighthouse will make it easier to save results/compare

 ![image](https://canada1.discourse-cdn.com/flex027/uploads/aurelia/original/2X/6/660c8f52f5af68f63b940c39a2729bc7d875da1c.png)

---

<div class="post-metadata">

**Author:** ![fragsalat](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/fragsalat/32/270_2.png) [@fragsalat](https://discourse.aurelia.io/u/fragsalat)\
**Post date:** [September 30, 2018, 1:18pm UTC](https://discourse.aurelia.io/t/tracking-render-performance/1681/6 "2018-09-30T13:18:13Z")

</div>

I think lighthouse is just for local performance measurement but not for enduser performance measurement. This means that PC’s which are not as good as mine have worse load times.

---

<div class="post-metadata">

**Author:** ![vegarringdal](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/vegarringdal/32/248_2.png) [@vegarringdal](https://discourse.aurelia.io/u/vegarringdal)\
**Post date:** [September 30, 2018, 1:39pm UTC](https://discourse.aurelia.io/t/tracking-render-performance/1681/7 "2018-09-30T13:39:03Z")

</div>

Lighthouse emulates a nexus 5x/fast 3g.  
Best way to test preformance will be have 2-3 last verions of your site on a test server and run 2-5 tests using average.  
Using the npm/puppeteer module you should be able to automate this.

Or maybe I just missunderstood the goal.  
Im no expert in performance testing so ofc I could be wrong 🙂
