refactor: improve perf on the frontend

This commit is contained in:
swve 2025-03-16 15:23:02 +01:00
parent 5e7ae54215
commit 744e372f4e
8 changed files with 61 additions and 51 deletions

View file

@ -499,6 +499,7 @@ function ActivityChapterDropdown(props: {
<Link <Link
key={activity.id} key={activity.id}
href={getUriWithOrg(props.orgslug, '') + `/course/${cleanCourseUuid}/activity/${cleanActivityUuid}`} href={getUriWithOrg(props.orgslug, '') + `/course/${cleanCourseUuid}/activity/${cleanActivityUuid}`}
prefetch={false}
onClick={() => setIsOpen(false)} onClick={() => setIsOpen(false)}
> >
<div <div

View file

@ -11,25 +11,36 @@ type MetadataProps = {
searchParams: Promise<{ [key: string]: string | string[] | undefined }> searchParams: Promise<{ [key: string]: string | string[] | undefined }>
} }
type Session = {
tokens?: {
access_token?: string
}
}
// Add this function at the top level to avoid duplicate fetches
async function fetchCourseMetadata(courseuuid: string, access_token: string | null | undefined) {
return await getCourseMetadata(
courseuuid,
{ revalidate: 1800, tags: ['courses'] },
access_token || null
)
}
export async function generateMetadata(props: MetadataProps): Promise<Metadata> { export async function generateMetadata(props: MetadataProps): Promise<Metadata> {
const params = await props.params; const params = await props.params;
const session = await getServerSession(nextAuthOptions) const session = await getServerSession(nextAuthOptions as any) as Session
const access_token = session?.tokens?.access_token const access_token = session?.tokens?.access_token || null
// Get Org context information // Get Org context information
const org = await getOrganizationContextInfo(params.orgslug, { const org = await getOrganizationContextInfo(params.orgslug, {
revalidate: 1800, revalidate: 1800,
tags: ['organizations'], tags: ['organizations'],
}) })
const course_meta = await getCourseMetadata( const course_meta = await fetchCourseMetadata(params.courseuuid, access_token)
params.courseuuid,
{ revalidate: 0, tags: ['courses'] },
access_token ? access_token : null
)
const activity = await getActivityWithAuthHeader( const activity = await getActivityWithAuthHeader(
params.activityid, params.activityid,
{ revalidate: 0, tags: ['activities'] }, { revalidate: 1800, tags: ['activities'] },
access_token ? access_token : null access_token || null
) )
// SEO // SEO
@ -57,24 +68,22 @@ export async function generateMetadata(props: MetadataProps): Promise<Metadata>
} }
const ActivityPage = async (params: any) => { const ActivityPage = async (params: any) => {
const session = await getServerSession(nextAuthOptions) const session = await getServerSession(nextAuthOptions as any) as Session
const access_token = session?.tokens?.access_token const access_token = session?.tokens?.access_token || null
const activityid = (await params.params).activityid const activityid = (await params.params).activityid
const courseuuid = (await params.params).courseuuid const courseuuid = (await params.params).courseuuid
const orgslug = (await params.params).orgslug const orgslug = (await params.params).orgslug
const course_meta = await getCourseMetadata( const [course_meta, activity] = await Promise.all([
courseuuid, fetchCourseMetadata(courseuuid, access_token),
{ revalidate: 0, tags: ['courses'] }, getActivityWithAuthHeader(
access_token ? access_token : null
)
const activity = await getActivityWithAuthHeader(
activityid, activityid,
{ revalidate: 0, tags: ['activities'] }, { revalidate: 1800, tags: ['activities'] },
access_token ? access_token : null access_token || null
) )
])
return ( return (
<>
<ActivityClient <ActivityClient
activityid={activityid} activityid={activityid}
courseuuid={courseuuid} courseuuid={courseuuid}
@ -82,7 +91,6 @@ const ActivityPage = async (params: any) => {
activity={activity} activity={activity}
course={course_meta} course={course_meta}
/> />
</>
) )
} }

View file

@ -223,6 +223,7 @@ const CourseClient = (props: any) => {
)}` )}`
} }
rel="noopener noreferrer" rel="noopener noreferrer"
prefetch={false}
> >
<p>{activity.name}</p> <p>{activity.name}</p>
</Link> </Link>
@ -240,6 +241,7 @@ const CourseClient = (props: any) => {
)}` )}`
} }
rel="noopener noreferrer" rel="noopener noreferrer"
prefetch={false}
> >
<div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center"> <div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center">
<p>Page</p> <p>Page</p>
@ -260,6 +262,7 @@ const CourseClient = (props: any) => {
)}` )}`
} }
rel="noopener noreferrer" rel="noopener noreferrer"
prefetch={false}
> >
<div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center"> <div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center">
<p>Video</p> <p>Video</p>
@ -281,6 +284,7 @@ const CourseClient = (props: any) => {
)}` )}`
} }
rel="noopener noreferrer" rel="noopener noreferrer"
prefetch={false}
> >
<div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center"> <div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center">
<p>Document</p> <p>Document</p>
@ -302,6 +306,7 @@ const CourseClient = (props: any) => {
)}` )}`
} }
rel="noopener noreferrer" rel="noopener noreferrer"
prefetch={false}
> >
<div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center"> <div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center">
<p>Assignment</p> <p>Assignment</p>

View file

@ -24,7 +24,7 @@ export async function generateMetadata(props: MetadataProps): Promise<Metadata>
}) })
const course_meta = await getCourseMetadata( const course_meta = await getCourseMetadata(
params.courseuuid, params.courseuuid,
{ revalidate: 0, tags: ['courses'] }, { revalidate: 1800, tags: ['courses'] },
access_token ? access_token : null access_token ? access_token : null
) )
@ -66,24 +66,23 @@ export async function generateMetadata(props: MetadataProps): Promise<Metadata>
} }
const CoursePage = async (params: any) => { const CoursePage = async (params: any) => {
const courseuuid = (await params.params).courseuuid
const orgslug = (await params.params).orgslug
const session = await getServerSession(nextAuthOptions) const session = await getServerSession(nextAuthOptions)
const access_token = session?.tokens?.access_token const access_token = session?.tokens?.access_token
// Fetch course metadata once
const course_meta = await getCourseMetadata( const course_meta = await getCourseMetadata(
courseuuid, params.params.courseuuid,
{ revalidate: 0, tags: ['courses'] }, { revalidate: 1800, tags: ['courses'] },
access_token ? access_token : null access_token ? access_token : null
) )
return ( return (
<div>
<CourseClient <CourseClient
courseuuid={courseuuid} courseuuid={params.params.courseuuid}
orgslug={orgslug} orgslug={params.params.orgslug}
course={course_meta} course={course_meta}
access_token={access_token}
/> />
</div>
) )
} }

View file

@ -191,7 +191,6 @@ function ActivityElement(props: ActivitiyElementProps) {
'' ''
)}` )}`
} }
prefetch
className="p-1 px-2 sm:px-3 bg-linear-to-bl text-cyan-800 from-sky-400/50 to-cyan-200/80 border border-cyan-600/10 shadow-md rounded-md font-bold text-xs flex items-center space-x-1 transition-colors duration-200 hover:from-sky-500/50 hover:to-cyan-300/80" className="p-1 px-2 sm:px-3 bg-linear-to-bl text-cyan-800 from-sky-400/50 to-cyan-200/80 border border-cyan-600/10 shadow-md rounded-md font-bold text-xs flex items-center space-x-1 transition-colors duration-200 hover:from-sky-500/50 hover:to-cyan-300/80"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
@ -296,7 +295,6 @@ const ActivityElementOptions = ({ activity, isMobile }: { activity: any; isMobil
'' ''
)}/edit` )}/edit`
} }
prefetch
className={`hover:cursor-pointer p-1 ${isMobile ? 'px-2' : 'px-3'} bg-sky-700 rounded-md items-center`} className={`hover:cursor-pointer p-1 ${isMobile ? 'px-2' : 'px-3'} bg-sky-700 rounded-md items-center`}
target='_blank' target='_blank'
> >
@ -313,7 +311,6 @@ const ActivityElementOptions = ({ activity, isMobile }: { activity: any; isMobil
getUriWithOrg(org.slug, '') + getUriWithOrg(org.slug, '') +
`/dash/assignments/${assignmentUUID}` `/dash/assignments/${assignmentUUID}`
} }
prefetch
className={`hover:cursor-pointer p-1 ${isMobile ? 'px-2' : 'px-3'} bg-teal-700 rounded-md items-center`} className={`hover:cursor-pointer p-1 ${isMobile ? 'px-2' : 'px-3'} bg-teal-700 rounded-md items-center`}
> >
<div className="text-sky-100 font-bold text-xs flex items-center space-x-1"> <div className="text-sky-100 font-bold text-xs flex items-center space-x-1">

View file

@ -65,7 +65,7 @@ function ActivityIndicators(props: Props) {
key={activity.activity_uuid} key={activity.activity_uuid}
> >
<Link <Link
prefetch={true} prefetch={false}
href={ href={
getUriWithOrg(orgslug, '') + getUriWithOrg(orgslug, '') +
`/course/${courseid}/activity/${activity.activity_uuid.replace( `/course/${courseid}/activity/${activity.activity_uuid.replace(

View file

@ -111,11 +111,11 @@ export async function deleteActivity(activity_uuid: any, access_token: string) {
export async function getActivityWithAuthHeader( export async function getActivityWithAuthHeader(
activity_uuid: any, activity_uuid: any,
next: any, next: any,
access_token: string access_token: string | null | undefined
) { ) {
const result = await fetch( const result = await fetch(
`${getAPIUrl()}activities/activity_${activity_uuid}`, `${getAPIUrl()}activities/activity_${activity_uuid}`,
RequestBodyWithAuthHeader('GET', null, next, access_token) RequestBodyWithAuthHeader('GET', null, next, access_token || undefined)
) )
const res = await result.json() const res = await result.json()
return res return res

View file

@ -41,13 +41,13 @@ export async function searchOrgCourses(
} }
export async function getCourseMetadata( export async function getCourseMetadata(
course_uuid: any, course_uuid: string,
next: any, next: any,
access_token: string access_token: string | null | undefined
) { ) {
const result = await fetch( const result = await fetch(
`${getAPIUrl()}courses/course_${course_uuid}/meta`, `${getAPIUrl()}courses/course_${course_uuid}/meta`,
RequestBodyWithAuthHeader('GET', null, next, access_token) RequestBodyWithAuthHeader('GET', null, next, access_token || undefined)
) )
const res = await errorHandling(result) const res = await errorHandling(result)
return res return res