Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Yield within the Scheduler API to break up long JavaScript tasks [🟥 awaiting full support] #2295

Open
chrisblakley opened this issue Sep 18, 2024 · 7 comments
Labels
Frontend (Script) Related to the client-side JavaScript. Plugin / Library / API For third-party resources such as WordPress plugins, external APIs, and other libraries.
Milestone

Comments

@chrisblakley
Copy link
Owner

chrisblakley commented Sep 18, 2024

https://developer.chrome.com/blog/introducing-scheduler-yield-origin-trial

As of Chrome 129, functions can yield back to the main thread by using await scheduler.yield();

Google recommends using it liberally throughout the codebase, but I want to start with just the biggest functionality first.

Edit: Now on CanIUse: https://caniuse.com/mdn-api_scheduler_yield

@chrisblakley chrisblakley added Plugin / Library / API For third-party resources such as WordPress plugins, external APIs, and other libraries. Frontend (Script) Related to the client-side JavaScript. labels Sep 18, 2024
@chrisblakley chrisblakley added this to the 13.0 Bubble milestone Sep 18, 2024
@chrisblakley
Copy link
Owner Author

chrisblakley commented Sep 18, 2024

Quick notes, the function that this is within must be an async function and if scheduler.yield is not a function the JavaScript will error. So this cannot be implemented until full browser support– because I don't want to add a bunch of these throughout Nebula and then have to remove them all later...

if ( "scheduler" in window && "yield" in scheduler ){
	await scheduler.yield();
}

@chrisblakley
Copy link
Owner Author

Great article on this: https://www.debugbear.com/blog/scheduler-yield

@chrisblakley chrisblakley changed the title Use Yield within the Scheduler API to break up long JavaScript tasks Use Yield within the Scheduler API to break up long JavaScript tasks [❌ awaiting support tracking] Sep 18, 2024
@chrisblakley
Copy link
Owner Author

Added comments throughout Nebula for where I intend to place these when available.

//@todo "Nebula" 0: Scheduler Yield here when fully supported

These are placed in functions that are already async as well as functions that are not. Would need to test if changing non-async functions into async (and enabling the yield) breaks any functionality.

@chrisblakley
Copy link
Owner Author

Could use this function in the meantime...

//A function for shimming scheduler.yield with no fallback:
function yieldToMain () {
	//Use scheduler.yield if it exists
	if ( 'scheduler' in window && 'yield' in scheduler ){
		return scheduler.yield();
	}
	
	return; //Fall back to nothing (no yielding)
}

// Example usage:
async function doWork(){
	// Do some work:
	// ...
	
	await yieldToMain();
	
	// Do some other work:
	// ...
}

@chrisblakley
Copy link
Owner Author

chrisblakley commented Sep 19, 2024

Ok I have grown on the idea of using a shim function in the meantime while we wait for browser support.

//Yield back to the main thread when supported by the browser. Otherwise, do nothing.
nebula.yield = function(){
	//Use scheduler.yield if it exists
	if ( 'scheduler' in window && 'yield' in scheduler ){
		return scheduler.yield();
	}

	return; //Fall back to nothing (no yielding)
};

Use it like this:

await nebula.yield();

This is now used in several places throughout Nebula and can also be used in the child theme.

Just remember that the function needs to be async which means that it returns a promise! Anything calling an async function must expect a promise (and not a specific value) returned. So they can either use .then() on the function or await it. Otherwise, avoid trying to yield in that function.

@chrisblakley
Copy link
Owner Author

I also wrote a nebula.each() function that can be awaited to avoid race conditions while preserving the flexibility and convenience of jQuery.each().

https://nebula.gearside.com/functions/each/

@chrisblakley
Copy link
Owner Author

@chrisblakley chrisblakley changed the title Use Yield within the Scheduler API to break up long JavaScript tasks [❌ awaiting support tracking] Use Yield within the Scheduler API to break up long JavaScript tasks [🟥 awaiting full support] Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Frontend (Script) Related to the client-side JavaScript. Plugin / Library / API For third-party resources such as WordPress plugins, external APIs, and other libraries.
Projects
None yet
Development

No branches or pull requests

1 participant