Skip to content

Instantly share code, notes, and snippets.

@0x15f
Last active September 20, 2024 15:04
Show Gist options
  • Save 0x15f/cb593ce741c2468184b848d05e3a7839 to your computer and use it in GitHub Desktop.
Save 0x15f/cb593ce741c2468184b848d05e3a7839 to your computer and use it in GitHub Desktop.
Batching updates with View Transition API

Usage

import { enqueueTransition } from './transition'


// fetch or something getting external content
const myHtmlString = '<section>...</section>'
const range = document.createRange();
const documentFragment = range.createContextualFragment(myHtmlString);

// can be ran multiple times in isolation, view transitions will be batched or ran in sequence
enqueueTransition(() => mySection.replaceWith(myHtmlString))
import debounce from 'lodash.debounce'
type TransitionCallback = () => Promise<void>
const transitionQueue: TransitionCallback[] = []
let isRunning = false
const runTransitions = async () => {
if (isRunning || transitionQueue.length === 0) return
isRunning = true
const batch = [...transitionQueue]
transitionQueue.length = 0
try {
if (document.startViewTransition) {
document.startViewTransition(() => Promise.all(batch.map((callback) => callback())).then(() => {}))
} else {
await Promise.all(batch.map((callback) => callback()))
}
} catch (error) {
console.error('Transition error:', error)
} finally {
isRunning = false
}
}
const debouncedRunTransitions = debounce(runTransitions, 10)
export const enqueueTransition = (callback: TransitionCallback) => {
transitionQueue.push(callback)
debouncedRunTransitions()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment