József Kiss
József Kiss

Reputation: 125

Next.js app is lagging after initial scrolling

I'm rewriting my React app in Next.js. I have a navbar that transitions down after scrolling to a certain point. My problem is that when the page loads for the first time, the scrolling is laggy and the app freezes for a couple of milliseconds. After the first effect of the dropdown the navbar is working properly. I wonder what might cause this problem, which wasn't present when I was using React only. I figured out that my React-slick carousel interferes with it.

The navbar:

//hooks and imports

import styles from '../styles/Navbar.module.scss';
import React from "react";
import { useState } from "react";
import Container from "react-bootstrap/Container"
import Logo from "../public/images/logo4.png";
import { useMediaQuery } from 'react-responsive'
import { Navbar, Nav, Row, Col, Collapse, Offcanvas} from 'react- 
bootstrap';
import Link from "next/link"
import Image from 'next/image'
import styled from "styled-components";

const ImageWrap = styled.span`
margin-left: 1.5rem;
height: 100px; 
width: 100px;`;

const NavComponent = () => {

  const isDesktopOrLaptop = useMediaQuery({ query: '(min-width: 1224px)' })
  const isMobile = useMediaQuery({ query: '(max-width: 768px)' })

  const [open, setOpen] = useState(false);
  const [scroll, setScroll] = useState(0); //watch scroll position
  const [newNav, setNewNav] = useState (false) //switch to new css class
  
  React.useEffect(() => {
      window.addEventListener('scroll', scrollPos);
      return () => window.removeEventListener('scroll', scrollPos);
      }, []);
  
  React.useEffect(() => {
      window.addEventListener('scroll', newNavbar);
      return () => window.removeEventListener('scroll', newNavbar);
      }, []);

  const newNavbar = () => {
      if (window !== undefined) {
        let posHeight_2 = window.scrollY;
        posHeight_2 > 112 ? setNewNav(!newNav) : setNewNav(newNav)
      }
    };

  const scrollPos = () => {
    if (window !== undefined) {
      let posHeight = window.scrollY;
      posHeight > 112 ? setScroll(posHeight) : setScroll(0)
    }
  }; 
 
  const navClass = newNav ? "menu2_show" : "menu2"


  const [show, setShow] = useState(false);

  const handleClose = () => setShow(!show);
  const handleShow = () => setShow(!show);

//the main navbar: 

return (
    
<div> 

<Navbar bg="light" className={styles.menuTop} style={{overflowY:"hidden"}} >
      <Container fluid={+true}>
        <Row>
          <Nav className={styles.navContent}>
            <Nav.Item className={styles.listIcon} onClick={isMobile ? handleShow : () => 
             setOpen(!open)}>
              <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" className="bi bi-list" viewBox="0 0 16 16">
                <path fillRule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
              </svg>
            </Nav.Item>
          </Nav>
        </Row>
        <Row >
          <Nav className={styles.navContent}>
            <Navbar.Brand>
              <Link href="/">
                  <ImageWrap>
                    <Image src={Logo} width={110} height={100} alt="wut" />
                  </ImageWrap>
              </Link>
            </Navbar.Brand>
          </Nav>
        </Row>
        <Row>
          <Nav className={styles.navContent}>
            <Nav.Item className={styles.bagIcon}>
            <Link style={{color:'black'}} href="/cart">
                <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" className="bi bi-bag" viewBox="0 0 16 16">
                      <path d="M8 1a2.5 2.5 0 0 1 2.5 2.5V4h-5v-.5A2.5 2.5 0 0 1 8 1zm3.5 3v-.5a3.5 3.5 0 1 0-7 0V4H1v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-3.5zM2 5h12v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5z"/>
                </svg>
            </Link>
            </Nav.Item> 
          </Nav>
        </Row>
    </Container> 
  </Navbar>

//the dropdown navbar: 

<Navbar bg="light" fluid={+true}  className={navClass}>  
    <Container fluid={+true} >
      <Row>
          <Nav className={styles.navContent}>
            <Nav.Item className={styles.listIcon} onClick={isMobile ? handleShow : () => setOpen(!open)}>
              <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" className={`bi bi-list`} viewBox="0 0 16 16">
                <path fillRule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
              </svg>
            </Nav.Item>
          </Nav>
        </Row> 
        <Row >
          <Nav className={styles.navContent}>
            <Navbar.Brand>
              <ImageWrap>
                <Image src={Logo} width={110} height={100} alt="wut" />
              </ImageWrap>
            </Navbar.Brand>
          </Nav>
        </Row>
        <Row>
          <Nav className={styles.navContent}>
            <Nav.Item className={`${styles.bagIcon} ms-auto`}>
            <Link style={{color:'black'}} href="/cart">
                <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" className="bi bi-bag" viewBox="0 0 16 16">
                      <path d="M8 1a2.5 2.5 0 0 1 2.5 2.5V4h-5v-.5A2.5 2.5 0 0 1 8 1zm3.5 3v-.5a3.5 3.5 0 1 0-7 0V4H1v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-3.5zM2 5h12v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5z"/>
                </svg>
            </Link>
            </Nav.Item>
          </Nav>
        </Row>
    </Container>
  </Navbar>
    </div>
    )
}

// props given to the carousel 
 <Carousel array={imageArr} className={classes_4} sendDataToParent={() 
 => sendDataToParent}/>

//the carousel:
 
import React from "react"; 
import { useState } from "react";
import Slider from "react-slick";
import Link from "next/link"

function Carousel(props) {

    const [zoomed, setZoomed] = useState ('{}')
    const [fading_3, setFading_3] = useState(false)

    const [indexValue, setIndexValue] = useState({})

    React.useEffect(() => {
        setZoomed('backgroundSize:550')
      }, []);

    React.useEffect(() => {
        setFading_3(!fading_3)
       }, []); 


    const classes_4 = fading_3 ? 'zoomClass' : 'zoomClass hide'
    const [imageIndex, setImageIndex] = useState(0);

    React.useEffect(() => {
        setIndexValue(props.array[imageIndex])
       }, [imageIndex]);

    props.sendDataToParent(indexValue)

    const settings = {
    focusOnSelect: true,
    infinite: true, 
    lazyLoad: true,
    speed: 600,
    slidesToShow: 3,
    centerMode: true,
    centerPadding: 0,
    beforeChange: (current, next) => setImageIndex(next),
    };
    return (
    <div className="App">
        <Slider {...settings} className={classes_4}>
            {props.array.map((img, idx) => ( 
            <div key={img._id} className={[`${idx}` === `${imageIndex}` ? "slide activeSlide" : "slide"].join(' ')}>
                {idx === imageIndex ?
                    <Link href="/">
                        <img src={img.img} alt={img}  />
                    </Link> :
                    <img src={img.img} alt={img}  />
                }
            </div>
            ))}

        </Slider> 
    </div>
    );
}

export default Carousel;

Upvotes: 0

Views: 1543

Answers (1)

J&#243;zsef Kiss
J&#243;zsef Kiss

Reputation: 125

I have to use Next.js dynamic import and disable ssr.

Upvotes: 1

Related Questions