Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 23 additions & 26 deletions components/campaigns/AnnouncementHero.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';

import ArrowLeft from '../icons/ArrowLeft';
import ArrowRight from '../icons/ArrowRight';
import Container from '../layout/Container';
import Banner from './AnnouncementBanner';
import { banners } from './banners';
import { banners, shouldShowBanner } from './banners';

interface IAnnouncementHeroProps {
className?: string;
Expand All @@ -21,15 +21,15 @@ interface IAnnouncementHeroProps {
export default function AnnouncementHero({ className = '', small = false }: IAnnouncementHeroProps) {
const [activeIndex, setActiveIndex] = useState(0);

const len = banners.length;
const numberOfVisibleBanners = banners.filter((banner) => banner.show).length;
const visibleBanners = useMemo(() => banners.filter((banner) => shouldShowBanner(banner.cfpDeadline)), [banners]);
const numberOfVisibleBanners = visibleBanners.length;

const goToPrevious = () => {
setActiveIndex((prevIndex) => (prevIndex === 0 ? len - 1 : prevIndex - 1));
setActiveIndex((prevIndex) => (prevIndex === 0 ? numberOfVisibleBanners - 1 : prevIndex - 1));
};

const goToNext = () => {
setActiveIndex((prevIndex) => (prevIndex === len - 1 ? 0 : prevIndex + 1));
setActiveIndex((prevIndex) => (prevIndex === numberOfVisibleBanners - 1 ? 0 : prevIndex + 1));
};

const goToIndex = (index: number) => {
Expand Down Expand Up @@ -62,31 +62,28 @@ export default function AnnouncementHero({ className = '', small = false }: IAnn
)}
<div className='relative flex w-5/6 flex-col items-center justify-center gap-2'>
<div className='relative flex min-h-72 w-full items-center justify-center overflow-hidden lg:h-[17rem] lg:w-[38rem]'>
{banners.map(
(banner, index) =>
banner.show && (
<Banner
key={index}
title={banner.title}
dateLocation={banner.dateLocation}
cfaText={banner.cfaText}
eventName={banner.eventName}
cfpDeadline={banner.cfpDeadline}
link={banner.link}
city={banner.city}
activeBanner={index === activeIndex % len}
className={className}
small={small}
/>
)
)}
{visibleBanners.map((banner, index) => (
<Banner
key={index}
title={banner.title}
dateLocation={banner.dateLocation}
cfaText={banner.cfaText}
eventName={banner.eventName}
cfpDeadline={banner.cfpDeadline}
link={banner.link}
city={banner.city}
activeBanner={index === activeIndex % numberOfVisibleBanners}
className={className}
small={small}
/>
))}
Comment on lines +65 to +79
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider optimizing banner rendering performance.

While the implementation is functionally correct, the rendering of multiple banners might contribute to the low performance score (46) in the Lighthouse report. Consider these optimizations:

  1. Implement lazy loading for inactive banners
  2. Use CSS transforms for transitions instead of mounting/unmounting

Here's a suggested optimization:

 <div className='relative flex min-h-72 w-full items-center justify-center overflow-hidden lg:h-[17rem] lg:w-[38rem]'>
-  {visibleBanners.map((banner, index) => (
+  {visibleBanners.map((banner, index) => {
+    // Only render active banner and immediate neighbors
+    const isVisible = Math.abs(index - (activeIndex % numberOfVisibleBanners)) <= 1;
+    if (!isVisible) return null;
+    return (
       <Banner
         key={index}
         title={banner.title}
         dateLocation={banner.dateLocation}
         cfaText={banner.cfaText}
         eventName={banner.eventName}
         cfpDeadline={banner.cfpDeadline}
         link={banner.link}
         city={banner.city}
         activeBanner={index === activeIndex % numberOfVisibleBanners}
         className={className}
         small={small}
       />
-    ))}
+    );
+  })}

Committable suggestion was skipped due to low confidence.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create a new issue for this and let's not target this issue in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akshatnema, I've created a new issue to track this optimization: #3335.

🔗 Analysis chain
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Create a new GitHub issue as per @akshatnema's request

gh issue create \
  --title "Optimize banner rendering performance to improve Lighthouse score" \
  --body "In PR #3312 (https://github.com/asyncapi/website/pull/3312), optimizing the banner rendering performance was suggested to improve the Lighthouse performance score.

Reference comment: https://github.com/asyncapi/website/pull/3312#discussion_r1812653123

Requested by @akshatnema." \
  --assignee "akshatnema"

Length of output: 452

</div>
<div className='m-auto flex justify-center'>
{banners.map((banner, index) => (
{visibleBanners.map((banner, index) => (
<div
key={index}
className={`mx-1 size-2 cursor-pointer rounded-full ${
activeIndex % len === index ? 'bg-primary-500' : 'bg-gray-300'
activeIndex % numberOfVisibleBanners === index ? 'bg-primary-500' : 'bg-gray-300'
}`}
onClick={() => goToIndex(index)}
/>
Expand Down
20 changes: 8 additions & 12 deletions components/campaigns/banners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @returns Whether the banner should be shown
* @description Check if the current date is after the deadline
*/
function shouldShowBanner(cfpDeadline: string) {
export function shouldShowBanner(cfpDeadline: string) {
const currentDate = new Date(); // G et the current date
const deadline = new Date(cfpDeadline); // Convert the cfpDeadline string to a Date object

Expand All @@ -15,18 +15,14 @@ function shouldShowBanner(cfpDeadline: string) {
return true;
}

const cfpDeadlineParis = '2024-10-12T06:00:00Z';
const showBannerParis = shouldShowBanner(cfpDeadlineParis);

export const banners = [
{
title: "AsyncAPI Conf on Tour'24",
city: 'Paris',
dateLocation: '3rd - 5th of December, 2024 | France, Paris',
cfaText: 'Apply To Speak',
eventName: 'the end of Call for Speakers',
cfpDeadline: cfpDeadlineParis,
link: 'https://conference.asyncapi.com/venue/Paris',
show: showBannerParis
title: "AsyncAPI Online Conference'24",
city: 'YouTube',
dateLocation: '30th of October, 2024 | YouTube & LinkedIn',
cfaText: 'Join us Live',
eventName: 'the AsyncAPI Online Conference',
cfpDeadline: '2024-10-30T06:00:00Z',
link: 'https://www.youtube.com/live/F9wHxd-v2f0?si=kPCqgUzqAKC0FaqJ'
}
];