-
-
Save sergeydt/b1f67bf70957ef8ad3778b18ced0eb32 to your computer and use it in GitHub Desktop.
Lazy Load of analytics (Next.js)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { loadedContext } from 'lib/state/loaded-context' | |
import { useLoaded } from 'lib/hooks/use-loaded' | |
import { AllAnalytics } from 'lib/helpers/analytics' | |
export default function MyApp({ Component, pageProps }) { | |
const isLoaded = useLoaded(); | |
return (<> | |
<loadedContext.Provider value={isLoaded}> | |
<Component {...pageProps} /> | |
{process.browser && <AllAnalytics/>} | |
</loadedContext.Provider> | |
</>); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useContext } from 'react' | |
import { loadedContext } from 'lib/state/loaded-context' | |
export const AllAnalytics = () => { | |
const isLoaded = useContext(loadedContext); | |
if (!isLoaded || process.env.NODE_ENV !== 'production') { | |
return null; | |
} | |
return <> | |
<AnalyticsGoogle/> | |
<AnalyticsYandex/> | |
</> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect } from "react"; | |
export const useLoaded = (delay = 5000) => { | |
const [isLoaded, setIsLoaded] = useState(false); | |
process.browser && useEffect(() => { | |
let timer = null; | |
const timerPromise = new Promise(resolve => { | |
timer = setTimeout(resolve, delay); | |
}); | |
const handlers = []; | |
const removeListeners = () => { | |
handlers.forEach(({eventName, resolve: cb}) => { | |
document.removeEventListener(eventName, cb); | |
}); | |
clearTimeout(timer); | |
handlers.splice(0, handlers.length); | |
} | |
const eventStrings = ['mousewheel', 'keypress']; | |
if (!('ontouchstart' in document)) { | |
eventStrings.push('mousemove'); | |
} | |
const eventPromises = eventStrings.map(eventName => { | |
return new Promise(resolve => { | |
handlers.push({eventName, resolve}); | |
return document.addEventListener(eventName, resolve); | |
}); | |
}); | |
Promise.race(eventPromises.concat(timerPromise)) | |
.then(() => { | |
removeListeners(); | |
setIsLoaded(true); | |
}) | |
return removeListeners; | |
}, [delay]); | |
return isLoaded; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment