0

I'm trying to optimize a website in order to reach a better score in Google Lighthouse analysis. The score is significantly affected by the CLS(layout shifts). The significant impact comes from the hero section which is contributing to the CLS analysis by 0.642. The problem here is that I'm unable to detect what exactly is causing this layout shift in the hero section. I'm using Next.js along side with Styled Components the here's the code for the hero section below. I would be really grateful if someone helps me detect that layout shift.

import styled from "styled-components";
import Image from "next/image";

const Section = styled.section`
    position: relative;
    max-width: 100%;
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    overflow: hidden;
    background-color: blue;

    img {
        width: 100vw;
        height: 100vh;
        object-fit: cover;
    }



    @media(max-width: 990px) {
        min-height: 80vh;
        text-align: center;
    }

    @media(max-width: 600px) {
        min-height: 75vh;
    }

    video {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        pointer-events: none;    
    }
`

const Video = styled.video`
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    pointer-events: none;
`

const Container = styled.span`
    padding-inline: 4rem;
    z-index: 1;

    h1 {
        color: #fff;
        font-size: ${({ language }) => language === "English" ? "2.5rem" : "2.7rem"};
        line-height: 3.5rem;
        margin-bottom: 0.3rem;
    }

    div {
        height: 0.15rem;
        background-color: #F26630;
    }

    h3 {
        color: #fff;
        font-size: ${({ language }) => language === "English" ? "1.1rem" : "1.5rem"};
        margin: ${({ language }) => language === "العربية" ? "0.7rem 0rem" : ""};
        font-weight: normal;
    }

    button {
        font-size: ${({ language }) => language === "English" ? "1.4rem" : "1.7rem"};
        font-weight: 500;
        padding: ${({ language }) => language === "English" ? "0.6rem" : "0.4rem 2rem"};
        background-color: transparent;
        color: #fff;
        border: 2px solid #F26630;
        cursor: pointer;
        transition: background-color 500ms ease;

        &:hover {
            background-color: #F26630;
        }
    }


    // 10 inch
    @media(min-width: 1024px) {
        text-align: center;
        h1 {
            font-size: ${({ language }) => language === "English" ? "2rem" : "2.2rem"};
        }

        h3 {
            font-size: ${({ language }) => language === "English" ? "0.9rem" : "1.3rem"};
        }

        button {
            font-size: ${({ language }) => language === "English" ? "0.9rem" : "1.2rem"};
            padding: ${({ language }) => language === "English" ? "0.4rem" : "0.3rem 0.8rem"};
        }
    }

    // 19 inch
    @media(min-width: 1440px) {
        padding-inline: 6rem;

        h1 {
            font-size: 2.6rem;
            line-height: 3.5rem;
        }

        h3 {
            font-size: 1.1rem;
        }

        button {
            font-size: 1rem;
        }
    }

    // 22 inch
    @media(min-width: 1680px) {

        h1 {
            font-size: 3.2rem;
            line-height: 4.8rem;
        }

        h3 {
            font-size: 1.3rem;
        }

        button {
            font-size: 1.3rem;
        }
    }

    @media(max-width: 990px) {
        padding-top: 4rem;

        h1 {
            font-size: 2.1rem;
            line-height: 3rem;
        }

        h3 {
            font-size: 1rem;
        }

        button {
            font-size: 1.1rem;
        }
    }

    @media(max-width: 600px) {
        h1 {
            font-size: 1.2rem;
            line-height: 1.8rem;
        }

        h3 {
            font-size: 0.5rem;
        }

        button {
            font-size: 0.8rem;
            padding: 0.3rem;
        }
    }
`

const Hero = ({ language, onLinkClick }) => {
    return (
        <Section language={language} id="hero-section">
            <Image layout="fill" src="https://res.cloudinary.com/dqmqc0uaa/image/upload/c_scale,h_1057,w_1280/v1672178208/uploads/bg-masthead_1_1_yvvplw.png" alt="Image for mount Sinai" />
            <Container language={language}>
                <h1> {language === "English" ? "Your Favorite Agency for" : "الاختيار الافضل للسياحة داخل مصر"}
                    <br></br>
                    {language === "English" ? "Traveling Around Egypt" : "وقضاء عطلة مميزة بافضل سعر"}
                </h1>

                <div />

                <h3 className="text-white">
                    {
                        language === "English"
                            ? "It is a long established fact that a reader will be distracted by the"
                            : "اذا كنت من محبي السفر والاستكشاف وترغب في الاستمتاع بعطلة "
                    }
                    <br></br>
                    {
                        language === "English"
                            ? "reader will be distracted by the."
                            : "نهاية الاسبوع ، فانت في المكان الصحيح"
                    }

                </h3>
                {/* <button goto='trips-section' onClick={(e) => onLinkClick(e)}> */}
                <button onClick={() => {
                    window.scrollTo({ top: document.getElementById('hero-section').offsetHeight - 10 });
                }}>
                    {language === "English" ? "Find Out More" : "اعرف اكثر"}
                </button>
            </Container>
        </Section>
    )
}

export default Hero
  • Use a step-by-step approach, starting without the component at all. Often, fonts contribute to CLS. The strategies to avoid CLS are many. First, identify the source. – Stefan Dec 31 '22 at 14:44
  • Thank you, I kinda did so. I managed to increase the performance, but I circumvented the main issue I didn't really solve it. – Kareem Abbas Jan 01 '23 at 15:23
  • Just curious. What did cause the CLS? Pictures, Videos, Fonts? Did You work through this? https://web.dev/cls/ – Stefan Jan 01 '23 at 19:40
  • First of all, I'm really sorry for the late response. It was a mix between the Pictures, fonts, and elements, but pictures had the significant impact and the interesting thing is that it wasn't because of the hero image specifically, but because of dynamic rendering. The home page has many dynamic rendered section and dynamic rendered element within those sections. Although the hero image was the main reason, the dynamically rendered rendered sections and element are, technically, the main reason. I managed to circumvent by utilizing Next.js dynamic imports. – Kareem Abbas Jan 05 '23 at 17:43
  • 1
    and dynamically rendering those sections based on the scrollY ratio. Also I did some image optimization and eventually manage to score around 93 in the overall performance and decreased the CLS to 0.23. I have to say that I don't really think what I did is the best practice, but it works for now, temporarily. I'm planning to apply better optimization soon. And yeah I worked through this post https://web.dev/cls/ @stefan – Kareem Abbas Jan 05 '23 at 17:49

0 Answers0