You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Double RAF is useful for ensuring that animations start before expensive rendering is done.// It helps provide smoother user experience by making animations feel reactive.// Normal rendering would block the animation from starting.// https://github.com/UseWebPlatform/awesome-web-platform/js-snippets.md#animation// ES6constdoubleRAF=cb=>requestAnimationFrame(()=>requestAnimationFrame(cb));// ES7constrequestAnimationFramePromise=()=>newPromise(resolve=>requestAnimationFrame(resolve));constdoubleRAF=async()=>{awaitrequestAnimationFramePromise();awaitrequestAnimationFramePromise();};// Examples// With double RAF as shown here the rendering function safely runs in the main thread// after the animation has already started.// ES6button.addEventListener('click',function(){element.classList.add('animating');doubleRAF(renderNextView);});// ES7element.classList.add('animating');awaitdoubleRAF();renderNextView();
// Don't run if the user is on 2G or if Save-Data is enabled.// https://github.com/UseWebPlatform/awesome-web-platform/js-snippets.md#networkif(conn=navigator.connection){if((conn.effectiveType||'').includes('2g')||conn.saveData)return;}
// Defer another network requests after initial frame is rendered to keep the page load performant.// https://github.com/UseWebPlatform/awesome-web-platform/js-snippets.md#optimizationconstdefer=fn=>{constraf=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;if(raf)raf(()=>window.setTimeout(fn,0));elsewindow.addEventListener('load',fn);}constdeferScript=scriptUrl=>{defer(()=>{constscript=document.createElement('script');script.async=true;script.src=scriptUrl;document.body.appendChild(script);});}constdeferStyles=noscriptId=>{defer(()=>{constaddStylesNode=document.getElementById(noscriptId);constreplacement=document.createElement('div');replacement.innerHTML=addStylesNode.textContent;document.body.appendChild(replacement);addStylesNode.parentElement.removeChild(addStylesNode);});}// ExamplesdeferScript('https://www.google-analytics.com/analytics.js');// Check that service workers are registered.if('serviceWorker'innavigator){defer(()=>navigator.serviceWorker.register('/sw.js'));}<noscriptid="deferred-styles"><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Roboto:500&subset=latin-ext"></noscript><script>
deferStyles('deferred-styles');
</script>
// Polyfill/shim for the requestIdleCallback and cancelIdleCallback API.// https://github.com/UseWebPlatform/awesome-web-platform/js-snippets.md#performancewindow.requestIdleCallback=window.requestIdleCallback||cb=>{conststart=Date.now();returnsetTimeout(()=>{cb({didTimeout: false,timeRemaining: ()=>Math.max(0,50-(Date.now()-start)),});},1);};window.cancelIdleCallback=window.cancelIdleCallback||id=>clearTimeout(id);
// Get anytime a single task blocks the main thread for more than 50ms.// https://github.com/UseWebPlatform/awesome-web-platform/js-snippets.md#performancefunctionsendLongTaskDataToGoogleAnalytics(entryList){// Assumes the availability of requestIdleCallback (or a shim).requestIdleCallback(()=>{for(constentryofentryList.getEntries()){ga('send','event',{eventCategory: 'Performance Metrics',eventAction: 'longtask',eventValue: Math.round(entry.duration),eventLabel: JSON.stringify(entry.attribution),});}});}// Create a PerformanceObserver and start observing Long Tasks.newPerformanceObserver(sendLongTaskDataToGoogleAnalytics).observe({entryTypes: ['longtask'],});
// Using requestIdleCallback for sending analytics data.// https://github.com/UseWebPlatform/awesome-web-platform/js-snippets.md#performanceconstprocessPendingAnalyticsEvents=deadline=>{// Reset the boolean so future rICs can be set.isRequestIdleCallbackScheduled=false;// If there is no deadline, just run as long as necessary.// This will be the case if requestIdleCallback doesn’t exist.if(typeofdeadline==='undefined')deadline={timeRemaining: ()=>Number.MAX_VALUE};// Go for as long as there is time remaining and work to do.while(deadline.timeRemaining()>0&&eventsToSend.length>0){varevt=eventsToSend.pop();ga('send','event',evt.category,evt.action,evt.label,evt.value);}// Check if there are more events still to send.if(eventsToSend.length>0)schedulePendingEvents();}constschedulePendingEvents=()=>{// Only schedule the rIC if one has not already been set.if(isRequestIdleCallbackScheduled)return;isRequestIdleCallbackScheduled=true;// Assumes the availability of requestIdleCallback (or a shim).// Wait at most two seconds before processing events.requestIdleCallback(processPendingAnalyticsEvents,{timeout: 2000});}leteventsToSend=[];letisRequestIdleCallbackScheduled=false;// ExamplefunctiononNavOpenClick(){// Animate the menu.menu.classList.add('open');// Store the event for later.eventsToSend.push({category: 'button',action: 'click',label: 'nav',value: 'open'});schedulePendingEvents();}