Skip to content

Instantly share code, notes, and snippets.

View noamr's full-sized avatar

Noam Rosenthal noamr

View GitHub Profile
@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 22, 2023 10:38
View Transition Types example

VT Use case for types

Music App

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

  • Home
  • Playlist
  • What's new
  • Song
@noamr
noamr / whynp.js
Last active February 7, 2024 08:55
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;
@noamr
noamr / pending-beacon.js
Last active May 16, 2023 17:58
PendingBeacon on top of fetchLater
class UserlandPendingBeacon {
#abortController = null;
// Let's imagine it's a list of plain objects.
#pendingEntries = [];
// URL, headers, defer options etc
#requestInit;
constructor(requestInit) {
@noamr
noamr / script-parsing.js
Last active August 23, 2023 16:34
A polyfill for script element loading (for illustration purposes)
function parseHTML(getNextElement) {
let doneParsing = null;
const whenDoneParsing = new Promise(resolve => { doneParsing = resolve; });
while (const element = getNextElement()) {
if (element.tagName !== "SCRIPT") {
// parse everything else...
continue;
}