choojs / nanotiming

⏲ - Small timing library
MIT License
35 stars 11 forks source link

Uncaught DOMException: Failed to execute 'measure' on 'Performance' #18

Open nicknikolov opened 6 years ago

nicknikolov commented 6 years ago

Uncaught DOMException: Failed to execute 'measure' on 'Performance': The mark 'end-24206000-nanocomponent.render' does not exist.

@yoshuawuyts :

nicknikolov: okay: what I suspect is happening is that your performance timer buffer is full 13:44 and you have a mismatched pair of performance timings 13:44 e.g. it wrote the first one, but can't write the last one nicknikolov: what we should do is if the performance timer buffer can only store 10 or so more items, we don't start the measure 13:45 convert it to a noop 13:45 usually it means you've already stored 140 entries already 13:45 which probably means you're not clearing them

btheado commented 6 years ago

I think uuid collision at https://github.com/choojs/nanotiming/blob/master/browser.js#L18 is another way this error can happen. If the performance mark name is the same, then the mark will be cleared after the first measure is taken and cause this error the second time?

I'm using https://github.com/graforlock/choo-detached to embed multiple choo apps into a single page and I'm seeing this error often for choo.use and choo.emit. I haven't created a simplified test case yet, so I'm not 100% sure on my analysis...

btheado commented 6 years ago

Simple test cases I constructed failed to duplicate the issue I was seeing with multple embedded choo apps. In additon, 'npm update' on one of my embedded apps caused the issue to go away. So I have little confidence in my uuid collision theory. I will report back if I encounter it again and can gather some useful information.

yoshuawuyts commented 6 years ago

uuid collision theory

yeah, we don't generate UUIDS, but rather nanosecond-precision timestamps. There should be no conflicts here.

mantoni commented 6 years ago

This bugs me too. I've created a minimal reproducible test case:

const choo = require('choo');
const html = require('choo/html');

const app = choo();

app.use(() => {});
app.use(() => {}); // <-- this makes it throw in Safari

app.route('/', () => html`<h1>Oh, hi!</h1>`);

document.body.appendChild(app.start());

This happens because choo calls nanotiming for each store in a loop. If two or more stores are used, the exception is throw. Apparently perf.now() always returns the same value in this case.

Here are two solutions that I found to make it work:

I can make a PR with either change, or maybe somebody has a better idea.