skip to Main Content

Problem:

I’m having a video on the start page that is quite slow to load if the network connection is bad. So I want to redirect the user if the page didn’t load after x seconds. I’m using Next JS / React.
"next": "^12.3.1"
"react": "^18.2.0"

What I’ve tried:

Using useEffect and setTimeout to measure the loading time.
The problem with the below is that it’s not considering the initial page load or refresh. It seems only to start counting when the component is initialized not when the user clicked on refresh. My "/" page is a server-side page and the component within is a client component in this case I’m not using the app router. With the below the redirect is firing after more than 35 seconds when I limit my network speed to "Fast 3G" within the browser.

  useEffect(() => {
    // On slow internet forward to work page after 6 seconds
    const timer = setTimeout(() => {
      console.log("6 seconds have passed!");
      // if (document.readyState === "complete") {
      //   console.log("document.readyState", document.readyState);
      //   console.log("site loaded");
      // } else {
      console.log("site not loaded");
      router.push("/work");
      // }
    }, 6000);
    return () => clearTimeout(timer);
  }, []);

What I’m looking for:

A way to redirect the user if the full page didn’t load after x second.

2

Answers


  1. You can try like this:

      const handleLoadStart = () => {
        performance.mark('video-loadstart');
      };
    
      const handleLoadedData = () => {
        performance.mark('video-loadeddata');
        performance.measure('video-loading-time', 'video-loadstart', 'video-loadeddata');
        const measure = performance.getEntriesByName('video-loading-time', 'measure')[0]
        const loadingTime = measure.duration;
        if (loadingTime > 6000) {
          router.push("/work");
        }
      };
    
      return (
        <div className="container">
          <video
            autoPlay
            playsInline
            muted
            src={src}
            onLoadStart={handleLoadStart}
            onLoadedData={handleLoadedData}
          />
        </div>
      );
    
    Login or Signup to reply.
  2. From what I understand you load the video server side so your client component has nothing to do with that and the effect will only fire when it mounts, so the place to handle that is the server.
    using nextjs 12 you can still redirect the user from inside getServerSideProps and getStaticProps, you need only to use a Promise so you can reject it after 6 seconds, there you can use setTimeout:

    export async function getServerSideProps() {
      const preGenerateDataPromis = new Promise((resolve, reject) => {
        // here you handle loading the video
        // then you create your `data` object to pass to the component
        resolve({ data: data });
        setTimeout(() => {
          reject(new Error('loading failed.'));
        }, 6000);
      });
    
      try {
        const result = await preGenerateDataPromis;
        return {
          props: {
            data: result.data,
          },
        };
      } catch (error) {
        return {
          redirect: {
            destination: '/example',
            permanent: false,
          },
        };
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search