Skip to content

Commit d36f6ea

Browse files
committed
improve render performance (#265)
1 parent 838da65 commit d36f6ea

File tree

4 files changed

+50
-29
lines changed

4 files changed

+50
-29
lines changed

src/components/ConversationCard/index.jsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { memo, useEffect, useRef, useState } from 'react'
1+
import { memo, useEffect, useMemo, useRef, useState } from 'react'
22
import PropTypes from 'prop-types'
33
import Browser from 'webextension-polyfill'
44
import InputBox from '../InputBox'
@@ -292,6 +292,8 @@ function ConversationCard(props) {
292292
}
293293
}
294294

295+
const retryFn = useMemo(() => getRetryFn(session), [session])
296+
295297
return (
296298
<div className="gpt-inner">
297299
<div
@@ -500,8 +502,9 @@ function ConversationCard(props) {
500502
content={data.content}
501503
key={idx}
502504
type={data.type}
503-
session={session}
504-
onRetry={idx === conversationItemData.length - 1 ? getRetryFn(session) : null}
505+
descName={data.type === 'answer' && session.aiName}
506+
modelName={data.type === 'answer' && session.modelName}
507+
onRetry={idx === conversationItemData.length - 1 ? retryFn : null}
505508
/>
506509
))}
507510
</div>
@@ -533,7 +536,7 @@ function ConversationCard(props) {
533536

534537
ConversationCard.propTypes = {
535538
session: PropTypes.object.isRequired,
536-
question: PropTypes.string.isRequired,
539+
question: PropTypes.string,
537540
onUpdate: PropTypes.func,
538541
draggable: PropTypes.bool,
539542
closeable: PropTypes.bool,

src/components/ConversationItem/index.jsx

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react'
1+
import { memo, useState } from 'react'
22
import { ChevronDownIcon, XCircleIcon, SyncIcon } from '@primer/octicons-react'
33
import CopyButton from '../CopyButton'
44
import ReadButton from '../ReadButton'
@@ -8,12 +8,30 @@ import { useTranslation } from 'react-i18next'
88
import { isUsingCustomModel } from '../../config/index.mjs'
99
import { useConfig } from '../../hooks/use-config.mjs'
1010

11-
// eslint-disable-next-line
12-
export function ConversationItem({ type, content, session, onRetry }) {
11+
function AnswerTitle({ descName, modelName }) {
1312
const { t } = useTranslation()
14-
const [collapsed, setCollapsed] = useState(false)
1513
const config = useConfig()
1614

15+
return (
16+
<p style="white-space: nowrap;">
17+
{descName && modelName
18+
? `${t(descName)}${
19+
isUsingCustomModel({ modelName }) ? ' (' + config.customModelName + ')' : ''
20+
}:`
21+
: t('Loading...')}
22+
</p>
23+
)
24+
}
25+
26+
AnswerTitle.propTypes = {
27+
descName: PropTypes.string,
28+
modelName: PropTypes.string,
29+
}
30+
31+
export function ConversationItem({ type, content, descName, modelName, onRetry }) {
32+
const { t } = useTranslation()
33+
const [collapsed, setCollapsed] = useState(false)
34+
1735
switch (type) {
1836
case 'question':
1937
return (
@@ -49,23 +67,17 @@ export function ConversationItem({ type, content, session, onRetry }) {
4967
return (
5068
<div className={type} dir="auto">
5169
<div className="gpt-header">
52-
<p style="white-space: nowrap;">
53-
{session && session.aiName
54-
? `${t(session.aiName)}${
55-
isUsingCustomModel(session) ? ' (' + config.customModelName + ')' : ''
56-
}:`
57-
: t('Loading...')}
58-
</p>
70+
<AnswerTitle descName={descName} modelName={modelName} />
5971
<div className="gpt-util-group">
6072
{onRetry && (
6173
<span title={t('Retry')} className="gpt-util-icon" onClick={onRetry}>
6274
<SyncIcon size={14} />
6375
</span>
6476
)}
65-
{session && (
77+
{modelName && (
6678
<CopyButton contentFn={() => content.replace(/\n<hr\/>$/, '')} size={14} />
6779
)}
68-
{session && <ReadButton contentFn={() => content} size={14} />}
80+
{modelName && <ReadButton contentFn={() => content} size={14} />}
6981
{!collapsed ? (
7082
<span
7183
title={t('Collapse')}
@@ -128,8 +140,9 @@ export function ConversationItem({ type, content, session, onRetry }) {
128140
ConversationItem.propTypes = {
129141
type: PropTypes.oneOf(['question', 'answer', 'error']).isRequired,
130142
content: PropTypes.string.isRequired,
131-
session: PropTypes.object.isRequired,
143+
descName: PropTypes.string,
144+
modelName: PropTypes.string,
132145
onRetry: PropTypes.func,
133146
}
134147

135-
export default ConversationItem
148+
export default memo(ConversationItem)

src/components/FloatingToolbar/index.jsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Browser from 'webextension-polyfill'
2-
import { cloneElement, useEffect, useState } from 'react'
2+
import { cloneElement, useCallback, useEffect, useState } from 'react'
33
import ConversationCard from '../ConversationCard'
44
import PropTypes from 'prop-types'
55
import { config as toolsConfig } from '../../content-script/selection-tools'
@@ -70,10 +70,18 @@ function FloatingToolbar(props) {
7070
updatePosition() // avoid jitter
7171
}
7272

73-
const onDock = () => {
73+
const onClose = useCallback(() => {
74+
props.container.remove()
75+
}, [])
76+
77+
const onDock = useCallback(() => {
7478
props.container.className = 'chatgptbox-toolbar-container-not-queryable'
7579
setCloseable(true)
76-
}
80+
}, [])
81+
82+
const onUpdate = useCallback(() => {
83+
updatePosition()
84+
}, [position])
7785

7886
if (config.alwaysPinWindow) onDock()
7987

@@ -95,14 +103,10 @@ function FloatingToolbar(props) {
95103
question={prompt}
96104
draggable={true}
97105
closeable={closeable}
98-
onClose={() => {
99-
props.container.remove()
100-
}}
106+
onClose={onClose}
101107
dockable={props.dockable}
102108
onDock={onDock}
103-
onUpdate={() => {
104-
updatePosition()
105-
}}
109+
onUpdate={onUpdate}
106110
/>
107111
</div>
108112
</div>

src/components/MarkdownRender/markdown.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import remarkGfm from 'remark-gfm'
88
import remarkBreaks from 'remark-breaks'
99
import { Pre } from './Pre'
1010
import { Hyperlink } from './Hyperlink'
11+
import { memo } from 'react'
1112

1213
export function MarkdownRender(props) {
1314
return (
@@ -41,4 +42,4 @@ MarkdownRender.propTypes = {
4142
...ReactMarkdown.propTypes,
4243
}
4344

44-
export default MarkdownRender
45+
export default memo(MarkdownRender)

0 commit comments

Comments
 (0)