skip to Main Content

Recently I have developed an application on nextjs 14 and published this app to live server. After that, to improve my page performance i was testing my pages on PageSpeed Insights. And found our one of my section is getting red flag with "Largest Contentful Paint element" on a image. It is top section of my webpage (its a landing page). I have searched and applied lots of solution online, but couldn’t resolve this issue. Here is my full component:

return (
<>

  <main className='bg-black text-white'>
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
    />

    <section className='home-banner-wrapper'>
      <div className='basis-[45%] flex flex-col items-start'>
        {data?.top_title && (
          <h1 className='mb-5 text-[28px] lg:text-[52px] leading-[40px] lg:leading-[66px] font-extrabold'>
            {data.top_title}
          </h1>
        )}

        {data?.top_subtitle && (
          <p className='mb-[60px] text-xl font-light leading-8 lg:leading-9'>
            {data.top_subtitle}
          </p>
        )}

        {data?.cta_link && (
          <p className='flex m-0 justify-center items-center'>
          <Link
            href={data.cta_link}
            className='learn-more-btn'
          >
            Learn More
            <Image
              src='/images/arrow-circle-right.svg'
              width={24}
              height={25}
              alt="Arrow Icon"
              priority={true}
            />
          </Link>
          </p>
        )}
      </div>

      {data?.banner_image && (
        <div className='-mt-[120px] basis-[55%] flex items-stretch'>
          <Image
            src={data.banner_image}
            className='!w-[748px] lg:min-h-[500px]'
            width={748}
            height={500}
            alt="Top Banner"
            priority={true}
          />
        </div>
      )}
    </section>


    <section className='benefit-list-wrapper'>
      {data?.benefit_list
        && data.benefit_list.map((item, index) =>
      {
        return (
          <div key={index} className='flex-1'>
            <p className='benefit-list-item'>
              {item?.be_icon && (
                <Image
                  className='mb-0.5'
                  src={item.be_icon}
                  width={37}
                  height={38}
                  alt={""}
                />
              )} <span className='pl-1'>{item.be_title}</span>
            </p>
          </div>
        )
      })}
    </section>


    <section className='px-5 2xl:px-0 pt-[88px] mx-auto lg:w-auto'>
      {data?.functionality_title && (
        <h1 className='text-2xl lg:text-4xl !leading-50 text-center font-semibold'>
          {data.functionality_title}
        </h1>
      )}

      {data?.functionality_subtitle && (
        <>
          <div className='max-w-[290px] bg-secondary h-0.5 mx-auto lg:mt-5'></div>
          <p className='text-lg lg:text-[20px] leading-[32px] pt-5 lg:pt-[28px] text-center'>
            {data.functionality_subtitle}
          </p>
        </>
      )}

      <div className='max-w-[1320px] mx-auto flex flex-col justify-center lg:flex-row lg:justify-between mt-[80px] lg:mt-[50px] lg:pb-[70px]'>
        <div className='flex flex-col md:flex-row lg:flex-col md:justify-between gap-y-8 basis-[26%] lg:pt-5 lg:pr-[15px] items-center'>
          {data?.functionality_left
            && data.functionality_left.map((item, index) =>
          {
            return (
              <div
                className={'flex flex-col items-center min-w-[240px] lg:items-end min-h-[160px]' + (
                  index == 1 ? " lg:mr-[50px] mt-[7px]" : index == 2 ? " pt-2" : ""
                )}
                key={index}
              >
                {item?.icon && (
                  <Image
                    src={item.icon}
                    width={40}
                    height={60}
                    alt={item.title || ""}
                  />
                )}

                <h1 className='text-2xl lg:text-[28px] leading-[28px] font-semibold mt-2.5'>{item.title}</h1>
                <p className='text-[15px] leading-[28px] font-normal mt-2.5'>{item.subtitle}</p>
              </div>
            )
          })}
        </div>

        <div className='basis-[48%] flex my-10 lg:my-0 lg:items-center justify-center'>
          {data?.image && (
            <Image
              className='max-w-[unset] lg:-mt-[70px] w-[283px] h-[215px] lg:w-[515px] lg:h-[391px]'
              src={data.image}
              width={515}
              height={390}
              alt={data?.functionality_title || ""}
            />
          )}
        </div>

        <div className='md:flex md:flex-row md:justify-between flex flex-col lg:flex-col gap-y-9 basis-[26%] lg:pt-5 lg:pr-[15px]'>
          {data?.functionality_right
            && data.functionality_right.map((item, index) =>
          {
            return (
              <div
                className={'flex flex-col text-center lg:text-left items-center lg:items-start min-h-[164px]' + (
                  index == 1 ? " lg:ml-[20px]" : ""
                )}
                key={index}
              >
                {item?.icon && (
                  <Image
                    src={item.icon}
                    width={40}
                    height={60}
                    alt={item.title || ""}
                  />
                )}

                <h1 className={'text-2xl lg:text-[28px] leading-[28px] font-semibold mt-2.5' + (
                  index == 2 ? " w-[328px]" : ""
                )}>{item.title}</h1>
                <p className={'text-[15px] leading-[28px] font-normal mt-2.5' + (
                  index == 1 ? " w-[311px]" : ""
                )}>{item.subtitle}</p>
              </div>
            )
          })}
        </div>
      </div>
    </section>


    <section className='px-5 2xl:px-0 pt-[60px] pb-0 lg:pb-[70px] max-w-[1237px] mx-auto'>
      {data?.video_title && (
        <h1 className='text-2xl font-semibold lg:text-4xl text-center lg:!leading-50'>
          {data.video_title}
        </h1>
      )}

      <div className='max-w-[290px] bg-secondary h-0.5 mx-auto mt-5'></div>

      {data?.video_subtitle && (
        <p className='sm:text-xl text-[16px] pt-[30px] max-w-[903px] mx-auto text-center !leading-1.6'>
          {data.video_subtitle}
        </p>
      )}

      {data?.video_subtitle_last && (
        <p className='sm:text-xl text-[16px] pt-[30px] max-w-[903px] mx-auto text-center !leading-1.6'>
          {data.video_subtitle_last}
        </p>
      )}

      {data?.youtube_video_id && (
        <VideoPlayer
          divClass="pt-[73px] relative pb-[50%] mt-10 max-w-[1188px] mx-auto"
          videoId={data.youtube_video_id}
          videoTitle={data?.video_title || ""}
        />
      )}
    </section>


    <section className='px-5 2xl:px-0 pt-[40px] pb-0 lg:pb-[140px]'>
      {data?.why_title && (
        <h1 className='text-2xl font-semibold lg:text-4xl text-center !leading-50'>
          {data.why_title}
        </h1>
      )}

      {data?.why_subtitle && (
        <>
          <div className='max-w-[280px] bg-secondary h-0.5 mx-auto mt-5'></div>
          <p className='text-xl pt-[30px] max-w-[883px] mx-auto text-center text-[16px] leading-8'>
            {data.why_subtitle}
          </p>
        </>
      )}

      <div className='mt-[50px] grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-y-10 lg:gap-y-[65px] lg:gap-x-[117px] max-w-[1458px] mx-auto'>
        {data?.list
          && data.list.map((item, index) =>
        {
          return (
            <div className='text-center basis-1/3 p-5 max-w-[408px] mx-auto' key={index}>
              {item?.icon && (
                <Image
                  src={item.icon}
                  width={60}
                  height={60}
                  alt={item.title || ""}
                  className='mx-auto mb-[14px]'
                />
              )}

              {item.title && (
                <h1 className='text-2xl lg:text-[28px] mb-4 font-semibold'>{item.title}</h1>
              )}

              {item.subtitle && (
                <p className='text-sm lg:text-base font-normal leading-[26px]'>{item.subtitle}</p>
              )}
            </div>
          )
        })}
      </div>
    </section>


    <FaqList
      faqList={data?.faq_list || []}
      id="home-page-faq"
    />


    <JoinNow />
  </main>
</>

)

And here is the report from pagespeed insights

https://pagespeed.web.dev/analysis/https-nextsono-com/3pv1cjwgw5?form_factor=mobile

Can anyone help me out with this problem? I am getting same problem on other pages as well.

2

Answers


  1. To improve Image output:
    Use "Picture" tag

    <picture>
      <source media="(max-width:699px)" srcSet="https://res.cloudinary.com/di7j408eq/image/upload/v1685516535/outdoor-living-slider_1_nsnsnr.webp" type="image/webp" /> // for tab media size
      <source media="(max-width:640px)" srcSet="https://res.cloudinary.com/di7j408eq/image/upload/v1685516535/outdoor-living-slider_1_nsnsnr.webp" type="image/webp" /> // for mobile media size
      <Image
        src="https://res.cloudinary.com/di7j408eq/image/upload/v1685516535/outdoor-living-slider_1_nsnsnr.webp"
        width={500}
        height={500}
        alt="calgary landscaping"
        quality={100}
        priority="low"
        loading="lazy"
      />
    </picture>
    

    Keep priority="low" & loading="lazy".

    If the image is from the first fold then keep its priority="high" & loading="eager".

    Must use webp images and if you have SVG then add the package ‘react-svg’ and use it for better output.

    Also suggested is using the Next.js dynamic import if not yet used.
    Ref: https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#nextdynamic

    Ref: how can i fix largest contentful paint issue in next js image

    Login or Signup to reply.
  2. There might be some possible solutions you can try:

    1. The image dimensions you provided are quite large (748×500 pixels), which means the browser needs to download a significant amount of data to render it. You can opt for smaller-resolution images for the mobile device, which might help.

    2. While using srcset, downloading and using huge files causes significant performance hits, especially on mobile devices on mobile networks. Just be sure it is not something that’s causing problems here. Also, have a look at this issue which might give you more idea about this.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search