Skip to content

Instantly share code, notes, and snippets.

View noamr's full-sized avatar

Noam Rosenthal noamr

View GitHub Profile
@noamr
noamr / after-next-paint.js
Last active September 13, 2024 07:33
How to get a promise that resolves after the next paint
async function after_next_paint() {
const p = document.createElement("p");
p.innerText = "1"
p.style.transform = "rotateX(90deg)";
p.style.pointerEvents = "none";
p.style.position = "fixed";
p.style.left = "0";
p.style.top = "0";
p.setAttribute("elementtiming", "foo");
document.body.append(p);
const track = new PerformanceTrack();
// At some point
track.mark(name);
// At some other point
track.mark(name);
// Combines mark->mark as a single entry with duration
track.measure(name);
@noamr
noamr / paint-time-polifyll.js
Last active April 24, 2024 18:42
Paint timestamp
const next_frame = () => Promise(resolve => requestAnimationFrame(ts => resolve(ts));
async function get_img_presentation_time(img) {
// Wait until image is fully loaded
await new Promise(resolve => img.complete ? resolve() : img.addEventListener("load", resolve))
let frame_timestamp = await next_frame();
// Wait until we have the frame timestamp soonest after the image was decoded.
@noamr
noamr / fetch-later.js
Last active March 27, 2024 11:46
Use of `fetchLater` in an async way
const events = [];
let current_dequeue_end = 0;
function dequeue() {
// Ready to process, will send all current events.
current_dequeue_end = events.length;
fetchLater(makeURL(events)).then(({activated}) => {
if (activated) {
// Success, remove processed sub-array from the array and reset the index.
events.splice(0, current_deque_end);
current_dequeue_end = 0;
@noamr
noamr / vt-fallback-types.md
Created November 21, 2023 19:41
Fallback types

VT and types: fallbacks

The use-case: a page where elements transition to each other, but only if they're loaded. If the page is only partially loaded without those elements, the whole root elements transitions with a fade.

Old document:

@view-transition {
 navigation: auto;
@noamr
noamr / vt-playlist-types-example.md
Last active November 11, 2024 13:25
View Transition Types example

VT Use case for types

!!DEPRECATED!!

Music App

Going back to the original use case for types. We have a music app with 4 pages:

  • Home
  • Playlist
@noamr
noamr / whynp.js
Last active May 28, 2024 17:20
WhyNP: Analyze LoAFs & event timing entries to find cause of bad INP
(function() {
let pending_loaf_entries = [];
let pending_event_entries = [];
let timeout_handle = null;
const combined_map = new Map();
function print() {
const entries = [...combined_map.entries()].sort((a, b) => b.duration - a.duration);
console.log(entries.map(([loaf, event]) => {
let longest_script = null;
function hasPendingIncomingTransition() { }
function isRenderBlocked() { }
function continueIncomingTransition() { }
let hasSeenFold = false;
let lastFoldCheckTime = performance.now();
const FoldCheckThrolttle = 100;
function didSeeFold() {
if (hasSeenFold || !hasPendingIncomingTransition())
@noamr
noamr / whynp.js
Last active October 10, 2023 04:32
Diagnose INP issues by correlating event timing & long animation frames
(function init() {
function processAndFilterLoAFs(entries) {
function floorObject(o) {
return Object.fromEntries(Array.from(Object.entries(o)).map(([key, value]) => [key, typeof value === "number" ? Math.floor(value) :
value
]))
}
function processEntry(entry) {
const startTime = entry.startTime;