Skip to content

Instantly share code, notes, and snippets.

View mmocny's full-sized avatar

Michal Mocny mmocny

View GitHub Profile
@mmocny
mmocny / example.js
Last active February 25, 2025 18:12
AsyncContextWithPromisesDream.js
const val = AsyncContext.Variable();
async main() {
console.log(val.get()); // Expect: undefined
await val.withValue(1);
console.log(val.get()); // Expect: 1
await 1;
console.log(val.get()); // Expect: 1
@mmocny
mmocny / element_timing_hud.js
Created December 11, 2024 14:38
Add little red blocks around all elementtiming nodes (to compare e.g. LCP candidates). Note: LCP candidates don't have intersectionRect.
<script>
const observer = new PerformanceObserver(list => {
for (let entry of list.getEntries()) {
const size = entry.size || entry.intersectionRect.height * entry.intersectionRect.width;
console.log(entry.entryType, size, entry.element, entry);
if (entry.intersectionRect) showRect(entry.intersectionRect);
}
})
observer.observe({ type: 'element', buffered: true });
observer.observe({ type: 'largest-contentful-paint', buffered: true });
@mmocny
mmocny / eventtiming_polyfill.js
Last active December 6, 2024 18:41
Event Timing "polyfill" (barely) out of event listeners
const eventsForTiming = [
'keydown',
'keypress',
'keyup',
'pointerdown',
'pointerup',
'click',
];
// Add this as early as possible in order to measure events which stop propagation.
@mmocny
mmocny / elementtiming_all_the_things.js
Last active November 22, 2024 00:09
Add elementtiming attribute to all elements, as page loads or dynamically updates. Useful polyfill.
<!-- Add to <head> or as first script in body before any content -->
<script type='text/javascript'>
const observedElements = new WeakSet(); // Keep track of processed elements
new MutationObserver((mutationsList, observer) => {
for (let mutation of mutationsList) {
for (let node of mutation.addedNodes) {
if (node.nodeType === Node.ELEMENT_NODE && !observedElements.has(node)) {
node.setAttribute('elementtiming', 'test');
observedElements.add(node); // Mark the element as processed
@mmocny
mmocny / SaveEventTargets.js
Created August 30, 2023 16:27
Save Event Targets
const interestingEventTypes = [ 'pointerdown', 'pointerup', 'click', 'keydown', 'keypress', 'keyup'];
const mapOfTargets = Object.fromEntries(interestingEventTypes.map(type => [type, {}]));
interestingEventTypes.forEach(type =>
document.addEventListener(type, (event) => {
// TODO: Improve this
const nodeType = event.target.nodeName.toLowerCase();
const nodeId = event.target.id;
const nodeClasses = event.target.className.replace(/\s/g, '.');
@mmocny
mmocny / processArrayOfWork.js
Last active July 28, 2023 12:08
processArrayOfWork with PostTask
function processArrayOfWork(arr) {
const item = arr.shift();
console.log(`Processing array item: ${item}`);
if (arr.length > 0) {
// Recursive call.
processArrayOfWork(arr);
} else {
console.log('End processing array of data.');
}
@mmocny
mmocny / whyNP.js
Last active August 16, 2023 14:43
(() => {
// processLoAFEntry.js
function floorObject(o) {
return Object.fromEntries(
Array.from(Object.entries(o)).map(([key, value]) => [
key,
typeof value === "number" ? Math.floor(value) : value
])
);
}
@mmocny
mmocny / logInteractions.js
Created June 16, 2023 20:28
Log all Interaction in pretty style
const RATING_COLORS = {
good: "#0CCE6A",
"needs-improvement": "#FFA400",
poor: "#FF4E42"
};
function onInteraction(callback) {
const valueToRating = (score) =>
score <= 200 ? "good" : score <= 500 ? "needs-improvement" : "poor";
@mmocny
mmocny / inp-devtools-watch.js
Created April 14, 2023 14:12
Add these snippets to DevTools (console) Watch expressions
// max-INP:
(()=>{let o=globalThis;return void 0===o.winp&&(o.winp=0,new PerformanceObserver(n=>{for(let e of n.getEntries()){if(!e.interactionId)continue;o.winp=Math.max(e.duration,o.winp);let r=o=>o<=200?"color: green":o<=500?"color: yellow":"color: red";console.log(`%c[Interaction: ${e.name.padEnd(12)}] %cDuration: %c${e.duration}`,"color: grey; font-family: Consolas,monospace","",r(e.duration))}}).observe({type:"event",durationThreshold:0,buffered:!0})),o.winp})();
// interactionCount
performance.interactionCount;
@mmocny
mmocny / soft-navs.js
Last active December 11, 2024 01:57
Measure FCP/LCP + Soft Navs
const RATING_COLORS = {
"good": "#0CCE6A",
"needs-improvement": "#FFA400",
"poor": "#FF4E42",
"invalid": "#FFC0CB",
"default": "inherit", // Will default to this, anyway
};
function log(metric) {
const prettyScore = metric.value.toLocaleString(undefined, { maximumFractionDigits: 0 });