Skip to content

Commit 883e9e4

Browse files
authored
perf: optimize rendering (graphql#1529)
1 parent f8b9936 commit 883e9e4

File tree

3 files changed

+111
-128
lines changed

3 files changed

+111
-128
lines changed

gatsby-node.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,14 @@ export const createPages: GatsbyNode["createPages"] = async ({
220220

221221
// Create a page for each speaker
222222
speakers.forEach(speaker => {
223+
const speakerSessions: ScheduleSession[] =
224+
schedule.filter(session => session.speakers?.includes(speaker.name)) ||
225+
[]
226+
223227
createPage({
224228
path: `/conf/speakers/${speaker.username}`,
225229
component: path.resolve("./src/templates/speaker.tsx"),
226-
context: { speaker, schedule },
230+
context: { speaker, schedule: speakerSessions },
227231
})
228232

229233
if (!process.env.GATSBY_CLOUD && !process.env.GITHUB_ACTIONS) {

src/components/Conf/Schedule/ScheduleList.tsx

Lines changed: 102 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { format, parseISO, compareAsc } from "date-fns"
2-
import React, { FC, useEffect, useState } from "react"
2+
import React, { FC } from "react"
33
import { eventsColors } from "../../../utils/eventsColors"
44

55
function groupByKey<T>(arr: T[], getKey: (entity: T) => any) {
@@ -41,130 +41,121 @@ const ScheduleList: FC<Props> = ({
4141
filterSchedule,
4242
scheduleData,
4343
}) => {
44-
const [groupedSessionsByDay, setGroupedSessionsByDay] =
45-
useState<SessionsGroupByDay>([])
46-
const [hoveredSession, setHoveredSession] = useState<null | ScheduleSession>(
47-
null
48-
)
49-
const [isOpen, setIsOpen] = useState(false)
50-
const [hoveredSessionId, setHoveredSessionId] = useState<null | string>(null)
51-
52-
useEffect(() => {
53-
const filteredSortedSchedule = (
54-
filterSchedule ? filterSchedule(scheduleData) : scheduleData
55-
).sort((a, b) =>
56-
compareAsc(new Date(a.event_start), new Date(b.event_start))
57-
)
44+
const filteredSortedSchedule = (
45+
filterSchedule ? filterSchedule(scheduleData) : scheduleData
46+
).sort((a, b) => compareAsc(new Date(a.event_start), new Date(b.event_start)))
5847

59-
const groupedConcurrentSessions = groupByKey(
60-
filteredSortedSchedule,
61-
e => e.event_start
62-
)
48+
const groupedConcurrentSessions = groupByKey(
49+
filteredSortedSchedule,
50+
e => e.event_start
51+
)
6352

64-
const groupedSessionsByDay = groupByKey(
65-
groupedConcurrentSessions,
66-
// e[0] is the event date `yyyy/mm/dd hh:mm` and we split it by empty space to only get the day date excluding time.
67-
e => e[0].split(" ")[0]
68-
)
53+
const groupedSessionsByDay: SessionsGroupByDay = groupByKey(
54+
groupedConcurrentSessions,
55+
e => e[0].split(" ")[0]
56+
)
6957

70-
setGroupedSessionsByDay(groupedSessionsByDay)
71-
}, [])
58+
if (groupedSessionsByDay.length === 0) {
59+
return <p>Not available yet. Please check soon.</p>
60+
}
7261

73-
return groupedSessionsByDay.map(([date, concurrentSessionsGroup]) => (
74-
<div key={date} className="text-gray-800 text-sm">
75-
<h3 className="mt-10 mb-5">{format(parseISO(date), "EEEE, MMMM d")}</h3>
76-
{concurrentSessionsGroup.map(([sharedStartDate, sessions]) => (
77-
<div key={`concurrent sessions on ${sharedStartDate}`}>
78-
<div className="lg:flex-row flex flex-col mb-4">
79-
<div className="relative">
80-
<span className="lg:mr-7 mb-5 whitespace-nowrap text-gray-500 lg:mt-0 mt-3 inline-block lg:w-28 w-20">
81-
{format(parseISO(sharedStartDate), "hh:mmaaaa 'PDT'")}
82-
</span>
83-
<div className="lg:block hidden absolute right-3 top-0 h-full w-0.5 bg-gray-200" />
84-
</div>
85-
<div className="lg:flex-row flex flex-col gap-5 relative lg:items-start items-end w-full lg:pl-0 pl-[28px]">
86-
<div className="block lg:hidden absolute left-3 top-0 h-full w-0.5 bg-gray-200" />
62+
return (
63+
<>
64+
{groupedSessionsByDay.map(([date, concurrentSessionsGroup]) => (
65+
<div key={date} className="text-gray-800 text-sm">
66+
<h3 className="mt-10 mb-5">
67+
{format(parseISO(date), "EEEE, MMMM d")}
68+
</h3>
69+
{concurrentSessionsGroup.map(([sharedStartDate, sessions]) => (
70+
<div key={`concurrent sessions on ${sharedStartDate}`}>
71+
<div className="lg:flex-row flex flex-col mb-4">
72+
<div className="relative">
73+
<span className="lg:mr-7 mb-5 whitespace-nowrap text-gray-500 lg:mt-0 mt-3 inline-block lg:w-28 w-20">
74+
{format(parseISO(sharedStartDate), "hh:mmaaaa 'PDT'")}
75+
</span>
76+
<div className="lg:block hidden absolute right-3 top-0 h-full w-0.5 bg-gray-200" />
77+
</div>
78+
<div className="lg:flex-row flex flex-col gap-5 relative lg:items-start items-end w-full lg:pl-0 pl-[28px]">
79+
<div className="block lg:hidden absolute left-3 top-0 h-full w-0.5 bg-gray-200" />
8780

88-
{sessions.map(session => {
89-
const eventType = session.event_type.endsWith("s")
90-
? session.event_type.slice(0, -1)
91-
: session.event_type
81+
{sessions.map(session => {
82+
const eventType = session.event_type.endsWith("s")
83+
? session.event_type.slice(0, -1)
84+
: session.event_type
9285

93-
const speakers = session.speakers?.split(",") || []
94-
const eventTitle =
95-
speakers.length > 0
96-
? session.name.substring(
97-
0,
98-
session.name.indexOf(
99-
`${speakers[0].replace("ı", "i")}`
100-
) - 3
101-
)
102-
: session.name
86+
const speakers = session.speakers?.split(",") || []
87+
const eventTitle =
88+
speakers.length > 0
89+
? session.name.substring(
90+
0,
91+
session.name.indexOf(
92+
`${speakers[0].replace("ı", "i")}`
93+
) - 3
94+
)
95+
: session.name
10396

104-
const [borderColor] = getSessionColor(
105-
session.event_type.toLowerCase()
106-
)
97+
const [borderColor] = getSessionColor(
98+
session.event_type.toLowerCase()
99+
)
107100

108-
return session.event_type === "Breaks" ? (
109-
<div
110-
key={session.id}
111-
style={{
112-
borderLeft: `10px solid ${borderColor}`,
113-
borderRadius: "5px",
114-
backgroundColor: "white",
115-
}}
116-
className="shadow-[-5px_10px_30px_20px_#d0d3da33] font-normal flex items-center py-2 px-4 rounded-md w-full h-full text-black"
117-
>
118-
{showEventType ? eventType + " / " : ""}
119-
{eventTitle}
120-
</div>
121-
) : (
122-
<a
123-
id={`session-${session.id}`}
124-
data-tooltip-id="my-tooltip"
125-
href={`/conf/schedule/${session.id}?name=${session.name}`}
126-
key={session.id}
127-
style={{
128-
borderLeft: `10px solid ${borderColor}`,
129-
borderRadius: "5px",
130-
backgroundColor: "white",
131-
}}
132-
className="group no-underline hover:no-underline shadow-[-5px_10px_30px_20px_#d0d3da33] font-normal relative py-2 px-4 rounded-md w-full h-full text-black"
133-
onMouseEnter={() => {
134-
setHoveredSession(session)
135-
setHoveredSessionId(`session-${session.id}`)
136-
}}
137-
>
138-
<div className="flex flex-col justify-start h-full py-3 gap-y-2">
139-
{borderColor && (
140-
<span
141-
className="group-hover:no-underline flex py-1 px-3 mb-3 self-start justify-center items-center text-white border rounded-3xl"
142-
style={{
143-
backgroundColor: borderColor,
144-
}}
145-
>
146-
{eventType}
147-
</span>
148-
)}
149-
<div className="group-hover:underline flex flex-col justify-between h-full gap-y-2">
101+
return session.event_type === "Breaks" ? (
102+
<div
103+
key={session.id}
104+
style={{
105+
borderLeft: `10px solid ${borderColor}`,
106+
borderRadius: "5px",
107+
backgroundColor: "white",
108+
}}
109+
className="shadow-[-5px_10px_30px_20px_#d0d3da33] font-normal flex items-center py-2 px-4 rounded-md w-full h-full text-black"
110+
>
150111
{showEventType ? eventType + " / " : ""}
151112
{eventTitle}
152-
{speakers.length > 0 && (
153-
<span className="font-light">
154-
{speakers.join(", ")}
155-
</span>
156-
)}
157113
</div>
158-
</div>
159-
</a>
160-
)
161-
})}
114+
) : (
115+
<a
116+
id={`session-${session.id}`}
117+
data-tooltip-id="my-tooltip"
118+
href={`/conf/schedule/${session.id}?name=${session.name}`}
119+
key={session.id}
120+
style={{
121+
borderLeft: `10px solid ${borderColor}`,
122+
borderRadius: "5px",
123+
backgroundColor: "white",
124+
}}
125+
className="group no-underline hover:no-underline shadow-[-5px_10px_30px_20px_#d0d3da33] font-normal relative py-2 px-4 rounded-md w-full h-full text-black"
126+
>
127+
<div className="flex flex-col justify-start h-full py-3 gap-y-2">
128+
{borderColor && (
129+
<span
130+
className="group-hover:no-underline flex py-1 px-3 mb-3 self-start justify-center items-center text-white border rounded-3xl"
131+
style={{
132+
backgroundColor: borderColor,
133+
}}
134+
>
135+
{eventType}
136+
</span>
137+
)}
138+
<div className="group-hover:underline flex flex-col justify-between h-full gap-y-2">
139+
{showEventType ? eventType + " / " : ""}
140+
{eventTitle}
141+
{speakers.length > 0 && (
142+
<span className="font-light">
143+
{speakers.join(", ")}
144+
</span>
145+
)}
146+
</div>
147+
</div>
148+
</a>
149+
)
150+
})}
151+
</div>
152+
</div>
162153
</div>
163-
</div>
154+
))}
164155
</div>
165156
))}
166-
</div>
167-
))
157+
</>
158+
)
168159
}
169160

170161
export default ScheduleList

src/templates/speaker.tsx

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@ import { BackLink } from "../components/Conf/Schedule/BackLink"
2121
const SpeakersTemplate: FC<
2222
PageProps<{}, { speaker: SchedSpeaker; schedule: ScheduleSession[] }>
2323
> = ({ pageContext: { schedule, speaker } }) => {
24-
const speakersSessions = schedule.filter(session =>
25-
session.speakers?.includes(speaker?.name)
26-
)
27-
28-
console.log({ schedule, speakersSessions })
2924
return (
3025
<LayoutConf>
3126
<HeaderConf />
@@ -80,17 +75,10 @@ const SpeakersTemplate: FC<
8075
/>
8176
</div>
8277

83-
{speakersSessions.length > 0 ? (
84-
<div>
85-
<h1 className="!mb-0 pb-0">Sessions</h1>
86-
{speaker && (
87-
<ScheduleList
88-
showEventType
89-
scheduleData={speakersSessions}
90-
/>
91-
)}
92-
</div>
93-
) : null}
78+
<div>
79+
<h1 className="!mb-0 pb-0">Sessions</h1>
80+
<ScheduleList showEventType scheduleData={schedule} />
81+
</div>
9482
</div>
9583
</div>
9684
</section>

0 commit comments

Comments
 (0)