Skip to content

Commit

Permalink
Refactor to be a lot more idiomatic
Browse files Browse the repository at this point in the history
  • Loading branch information
mmocny committed Nov 8, 2023
1 parent 6c7359d commit bfb3a21
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 108 deletions.
12 changes: 11 additions & 1 deletion sandbox/web-mightals.js/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pageSlicer from "./lib/pageSlicer";
import webMightals from "./lib/webMightals";

function block(ms) {
Expand All @@ -11,9 +12,18 @@ myButton.addEventListener('click', (event) => {
block(Math.random() * 400);
});

const pages = pageSlicer().subscribe((url) => {
console.log('Navigate', url);

});

const obs = webMightals().subscribe({
next: (value) => {
console.log(value);
console.group('webMightals');
for (let [k,v] of Object.entries(value)) {
console.log(k, +v.score.toFixed(5), { entries: v.entries });
}
console.groupEnd();
},
complete: () => {
console.log('done');
Expand Down
47 changes: 19 additions & 28 deletions sandbox/web-mightals.js/lib/cls.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,25 @@
import { Observable, mergeMap } from "rxjs";
import { Observable, mergeMap, scan } from "rxjs";
import fromPerformanceObserver from "./fromPerformanceObserver";

// TODO: refactor to expose all shifts first, then convert to CLS
export function cls() {
return new Observable(subscriber => {
let totalCls = 0;
const entries = [];

const obs = fromPerformanceObserver({
type: 'layout-shift',
buffered: true,
}).pipe(
mergeMap(
list => list.getEntries()
)
);

obs.subscribe((entry) => {
if (!entry.hadRecentInput) {
entries.push(entry);
totalCls += entry.value;
subscriber.next({
score: totalCls,
entries,
});
}
});

// TODO: test this
return obs.unsubscribe;
});
return fromPerformanceObserver({
type: 'layout-shift',
// buffered: true,
}).pipe(
mergeMap(
list => list.getEntries()
.filter(entry => !entry.hadRecentInput)
.map(entry => ({
score: entry.value,
entries: [entry],
}))
),
scan((acc, curr) => ({
score: acc.score + curr.score,
entries: acc.entries.concat(curr.entries),
}), { score: 0, entries: [] })
);
}

export default cls;
52 changes: 18 additions & 34 deletions sandbox/web-mightals.js/lib/inp.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,26 @@
import { Observable, filter, mergeAll, mergeMap } from "rxjs";
import { Observable, distinctUntilChanged, filter, groupBy, map, mergeAll, mergeMap, scan } from "rxjs";
import fromPerformanceObserver from "./fromPerformanceObserver";
import interactions from "./interactions";

export function inp() {
return new Observable(subscriber => {
const idToEventMap = {};
let maxInp = 0;
let maxInp = 0;

const obs = fromPerformanceObserver({
type: 'event',
buffered: true,
durationThreshold: 0,
}).pipe(
mergeMap(
list => list.getEntries()
),
filter(
et => !!et.interactionId
)
return interactions()
.pipe(
groupBy((value) => value.entries[0].interactionId),
mergeMap((group$) => {
return group$.pipe(
scan((acc, curr) => ({
score: Math.max(acc.score, curr.score),
entries: acc.entries.concat(curr.entries),
}), { score: 0, entries: [] })
);
}),
distinctUntilChanged((prev, curr) => {
// Return true if the current INP is "same" as existing
return curr.score <= prev.score;
})
);

obs.subscribe((entry) => {
const interactionEntries = (idToEventMap[entry.interactionId] ??= []);
interactionEntries.push(entry);
if (entry.duration > maxInp) {
maxInp = entry.duration;
subscriber.next({
score: entry.duration,
entries: interactionEntries,
});
}
});

// TODO: test this
return () => {
console.log('here');
obs.unsubscribe();
};
});
}

export default inp;
22 changes: 22 additions & 0 deletions sandbox/web-mightals.js/lib/interactions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Observable, filter, map, mergeAll, mergeMap } from "rxjs";
import fromPerformanceObserver from "./fromPerformanceObserver";

// TODO: Should this perhaps group interaction events together?
export function interactions() {
return fromPerformanceObserver({
type: 'event',
// buffered: true,
durationThreshold: 0,
}).pipe(
mergeMap(
list => list.getEntries()
.filter(entry => entry.interactionId != 0)
.map(entry => ({
score: entry.duration,
entries: [entry],
}))
)
);
}

export default interactions;
29 changes: 10 additions & 19 deletions sandbox/web-mightals.js/lib/lcp.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
import { Observable, mergeMap } from "rxjs";
import { mergeMap } from "rxjs";
import fromPerformanceObserver from "./fromPerformanceObserver";

export function lcp() {
return new Observable(subscriber => {
const obs = fromPerformanceObserver({
type: 'largest-contentful-paint',
buffered: true,
}).pipe(
mergeMap(
list => list.getEntries()
)
);

obs.subscribe((entry) => {
subscriber.next({
return fromPerformanceObserver({
type: 'largest-contentful-paint',
buffered: true,
}).pipe(
mergeMap(
list => list.getEntries().map(entry => ({
score: entry.startTime,
entries: [entry],
});
});

// TODO: test this
return obs.unsubscribe;
});
}))
)
);
}

export default lcp;
27 changes: 9 additions & 18 deletions sandbox/web-mightals.js/lib/loafs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,17 @@ import { Observable, mergeMap } from "rxjs";
import fromPerformanceObserver from "./fromPerformanceObserver";

export function loafs() {
return new Observable(subscriber => {
const obs = fromPerformanceObserver({
type: 'long-animation-frame',
buffered: true,
}).pipe(
mergeMap(
list => list.getEntries()
)
);

obs.subscribe((entry) => {
subscriber.next({
return fromPerformanceObserver({
type: 'long-animation-frame',
// buffered: true,
}).pipe(
mergeMap(
list => list.getEntries().map(entry => ({
score: entry.duration,
entries: [entry],
});
});

// TODO: test this
return obs.unsubscribe;
});
}))
)
);
}

export default loafs;
13 changes: 10 additions & 3 deletions sandbox/web-mightals.js/lib/pageSlicer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ import { Observable } from 'rxjs';

export function pageSlicer() {
return new Observable(subscriber => {
const value = undefined;
subscriber.next(value);
navigation.addEventListener("navigate", e => {
console.log(e);

if (!e.canIntercept || e.hashChange) {
return;
}

subscriber.next(e.destination.url);
});

// TODO: remove event listener?
const cleanup = () => {};
return cleanup;
});

}

export default pageSlicer;
30 changes: 25 additions & 5 deletions sandbox/web-mightals.js/lib/webMightals.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,41 @@
* - Each new entry added to correct slice first
*/

import { combineLatest, startWith } from "rxjs";
import { combineLatest, debounceTime, startWith } from "rxjs";
import inp from "./inp";
import cls from "./cls";
import lcp from "./lcp";
import loafs from "./loafs";
import interactions from "./interactions";

// TODO: subscribe with next: and complete: to take all vs only final scores?
// TODO: can complete() handler take the last value?
export function webMightals() {
const mightals = {
"inp": inp().pipe(startWith({ score: 0, entries: [] })),
"cls": cls().pipe(startWith({ score: 0, entries: [] })),
"lcp": lcp().pipe(startWith({ score: 0, entries: [] })),
"inp": inp(),
"cls": cls(),
"lcp": lcp(),

// "interactions": interactions(),
"loafs": loafs(),
};

return combineLatest(mightals);

return combineLatest(
Object.fromEntries(
Object.entries(mightals).map(
([k,v]) => [
k,
v.pipe(
startWith({ score: 0, entries: [] })
)
]
)
)
).pipe(
debounceTime(0)
);

}

export default webMightals;

0 comments on commit bfb3a21

Please sign in to comment.