Skip to content

Commit

Permalink
Update snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
mmocny committed Dec 3, 2023
1 parent f17ef51 commit 5e0ab97
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 38 deletions.
11 changes: 11 additions & 0 deletions sandbox/nextjs-test-suspense-transitions/src/app/client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use client';

import { useEffect } from "react";

export default function ClientComponent() {
useEffect(() => {
document.addEventListener('DOMContentLoaded', console.log);
}, []);

return <p>client</p>;
}
27 changes: 26 additions & 1 deletion sandbox/nextjs-test-suspense-transitions/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
import { Suspense, useEffect } from "react";
import ClientComponent from "./client";

function wait(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

async function DelayedText({ delay }: { delay: number }) {
await wait(delay);
return <p>delay</p>;
}



export default async function Home() {

export default function Home() {
return (
<main>
Hello
<ClientComponent></ClientComponent>
<Suspense>
<DelayedText delay={1000}></DelayedText>
</Suspense>
<Suspense>
<DelayedText delay={3000}></DelayedText>
</Suspense>
<Suspense>
<DelayedText delay={10000}></DelayedText>
</Suspense>
</main>
)
}
2 changes: 1 addition & 1 deletion sandbox/snippets/dist/measure-history-events.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sandbox/snippets/dist/speed-up-hard-navs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions sandbox/snippets/lib/once-per-pageload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import sha256 from "./str-to-hash";

// This is mostly useful for DevTools live expressions
export default function oncePerPageload(callback) {
const rv = sha256(callback.toString());
const id = `__init_${rv}`;
if (window[id]) return;
window[id] = true;
callback();
}
9 changes: 9 additions & 0 deletions sandbox/snippets/lib/pretty-time.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function prettyTime(ms = performance.now()) {
return ms.toLocaleString(undefined, { maximumFractionDigits: 2 });
}

// Useful to have timestamps comparable even across navigations
// TODO: Maybe just use Date.now() or Date.toLocaleString()?
export default function prettyWallTime() {
return prettyTime(performance.timeOrigin + performance.now());
}
6 changes: 6 additions & 0 deletions sandbox/snippets/lib/str-to-hash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Thanks: https://jameshfisher.com/2017/10/30/web-cryptography-api-hello-world/

export default async function sha256(str) {
const buf = await crypto.subtle.digest("SHA-256", new TextEncoder("utf-8").encode(str));
return Array.prototype.map.call(new Uint8Array(buf), x=>(('00'+x.toString(16)).slice(-2))).join('');
}
77 changes: 42 additions & 35 deletions sandbox/snippets/measure-history-events.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,57 @@
import oncePerPageload from "./lib/once-per-pageload.js";

function block(ms) {
const target = performance.now() + ms;
while (performance.now() < target);
}

function cleanTime(ms) {
return ms;
// return ms.toLocaleString(undefined, { maximumFractionDigits: 2 });
}
function log(name, { timeStamp, processingStart, processingEnd }) {
if (processingStart === processingEnd) processingEnd += 50;

// Note: console doesn't work from page lifecycle events.
function logEvent(event) {
const eventName = event.type;
// May want to add timeOrigin for logging. May want to store in localStorage.
console.log(name);

const start = performance.now();
console.log(eventName, "start", cleanTime(start + performance.timeOrigin));
// localStorage[eventName + ".start"] = cleanTime(start + performance.timeOrigin);
performance.measure('[mmocny]' + name + '.inputDelay', {
start: timeStamp,
end: processingStart,
});
performance.measure('[mmocny]' + name, {
start: processingStart,
end: processingEnd,
});
}

performance.measure(eventName + ".inputDelay", { start: event.timeStamp, end: start });

block(200);

const end = performance.now();
console.log(eventName, "end", cleanTime(end + performance.timeOrigin));
// localStorage[eventName + ".end"] = cleanTime(end + performance.timeOrigin);
// Note: console doesn't work from page lifecycle events.
function logEvent(event) {
const eventName = event.type;
const processingStart = performance.now();

// Minimal blockage just to visualize the event better
// block(5);
// const processingEnd = performance.now();
const processingEnd = processingStart;

log(eventName, {
timeStamp: event.timeStamp,
processingStart,
processingEnd,
})
}

performance.measure(eventName + ".processing", { start, end });
function addEvents(target, types, handler) {
types.forEach((type) => {
target.addEventListener(type, handler);
});
}

function oncePerPageLoad() {
if (window.init_cguhvbj) return;
window.init_cguhvbj = true;

document.addEventListener("click", logEvent);
document.addEventListener('visibilitychange', logEvent);

navigation.addEventListener('navigate', logEvent);

window.addEventListener("beforeunload", logEvent);
window.addEventListener('pagehide', logEvent);
window.addEventListener('pageshow', logEvent);
window.addEventListener("popstate", logEvent);
window.addEventListener("pushstate", logEvent);

// Inject this script once per page, even after a new navigation
console.log('Hard.timeOrigin', cleanTime(performance.timeOrigin));
performance.mark('Hard.timeOrigin', { startTime: 0 }); // Relative to timeOrigin
function main() {
addEvents(document, ["click", "visibilitychange"], logEvent);
addEvents(navigation, ["navigate"], logEvent);
addEvents(window, ["beforeunload", "pagehide", "pageshow", "popstate", "pushstate"], logEvent);

log('Hard.timeOrigin', { processingStart: 0 });
}

oncePerPageLoad();
oncePerPageload(main);
14 changes: 14 additions & 0 deletions sandbox/snippets/speed-up-hard-navs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import oncePerPageload from "./lib/once-per-pageload";

function main() {
document.addEventListener('click', (event) => {
// TODO: forms with submit as well?
const a = event.target.closest('a');
if (!a) return;

event.preventDefault();
location = a.href;
}, { capture: true });
}

oncePerPageload(main);
2 changes: 1 addition & 1 deletion sandbox/soft-nav-hard-navigation-tests/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async function createServer() {

app.use('*', async (req, res, next) => {
// Add some TTFB
await wait(500);
await wait(1000);

console.log(req.originalUrl);

Expand Down

0 comments on commit 5e0ab97

Please sign in to comment.