cyrus-and / chrome-har-capturer

Capture HAR files from a Chrome instance
MIT License
535 stars 90 forks source link

Log firstContentfulPaint as timing metric #79

Closed waqaraqeel closed 4 years ago

waqaraqeel commented 4 years ago

firstContentfulPaint is an important performance metric for which the debugger doesn't seem to send a message. Worked around by executing JS in page context. I'm not very familiar with node, so let me know if I'm breaking any patterns. Thanks

cyrus-and commented 4 years ago

This isn't standard HAR though, right?

waqaraqeel commented 4 years ago

This isn't standard HAR though, right?

Correct. I guess it's something only I needed... Closing.

cyrus-and commented 4 years ago

No I mean, there are specific ways to include nonstandard information in HAR, I don't have time to look into this right now, but maybe it can be a nice thing to have.

waqaraqeel commented 4 years ago

No I mean, there are specific ways to include nonstandard information in HAR, I don't have time to look into this right now, but maybe it can be a nice thing to have.

Great! I'll look into it and report back. I'm also pressed for time these days...

cyrus-and commented 4 years ago

Let me clarify, the "specific way" is just to use underscores see here ("Custom fields").

I was saying that my time is scarce for reviewing your PR and determining if that's the correct way to obtain the firstContentfulPaint metric. For example, it can be preferable to just use the protocol and not inject JavaScript:

$ chrome-remote-interface inspect
>>> Performance.enable()
{}
>>> Page.navigate({url: 'https://github.com'})
{ frameId: '95F69F38F06F40B138661652BAE94D60',
  loaderId: '5B73196A05FACE06613143C059E77357' }
>>> Performance.getMetrics()
{ metrics:
   [ { name: 'Timestamp', value: 46616.041986 },
     { name: 'AudioHandlers', value: 0 },
     { name: 'Documents', value: 10 },
     { name: 'Frames', value: 9 },
     { name: 'JSEventListeners', value: 189 },
     { name: 'LayoutObjects', value: 1802 },
     { name: 'MediaKeySessions', value: 0 },
     { name: 'MediaKeys', value: 0 },
     { name: 'Nodes', value: 3897 },
     { name: 'Resources', value: 47 },
     { name: 'ContextLifecycleStateObservers', value: 23 },
     { name: 'V8PerContextDatas', value: 1 },
     { name: 'WorkerGlobalScopes', value: 0 },
     { name: 'UACSSResources', value: 0 },
     { name: 'RTCPeerConnections', value: 0 },
     { name: 'ResourceFetchers', value: 10 },
     { name: 'AdSubframes', value: 0 },
     { name: 'DetachedScriptStates', value: 1 },
     { name: 'LayoutCount', value: 2 },
     { name: 'RecalcStyleCount', value: 3 },
     { name: 'LayoutDuration', value: 0.015086 },
     { name: 'RecalcStyleDuration', value: 0.029976 },
     { name: 'ScriptDuration', value: 0.019278 },
     { name: 'V8CompileDuration', value: 0.0005 },
     { name: 'TaskDuration', value: 0.239245 },
     { name: 'TaskOtherDuration', value: 0.174905 },
     { name: 'ThreadTime', value: 0.228566 },
     { name: 'JSHeapUsedSize', value: 2178404 },
     { name: 'JSHeapTotalSize', value: 4591616 },
     { name: 'FirstMeaningfulPaint', value: 46613.365618 },
     { name: 'DomContentLoaded', value: 46613.335795 },
     { name: 'NavigationStart', value: 46613.098441 } ] }
cyrus-and commented 4 years ago

I added a more general solution, it should be good enough for now, from the command line you can add something like:

--userCode "({'first-contentful-paint': performance.getEntriesByName('first-contentful-paint')[0].startTime})"

When used as library just add a postHook that does the same.