|
1 | | -import React, { useState, useEffect, useRef } from "react"; |
| 1 | +import React, { useState, useEffect, useRef, useMemo } from "react"; |
2 | 2 | import { |
3 | 3 | Plus, |
4 | 4 | Trash2, |
@@ -149,9 +149,7 @@ const ChatMessage = React.memo( |
149 | 149 | : "bg-slate-900 border border-slate-800 text-slate-200", |
150 | 150 | )} |
151 | 151 | > |
152 | | - <ReactMarkdown |
153 | | - components={memoizedMarkdownComponents} |
154 | | - > |
| 152 | + <ReactMarkdown components={memoizedMarkdownComponents}> |
155 | 153 | {displayContent} |
156 | 154 | </ReactMarkdown> |
157 | 155 | </div> |
@@ -270,6 +268,21 @@ export function ChatbotApp() { |
270 | 268 | const lastParsedLengthRef = useRef(0); |
271 | 269 | const messagesEndRef = useRef<HTMLDivElement>(null); |
272 | 270 |
|
| 271 | + /** |
| 272 | + * ⚡ Bolt Performance Optimization: |
| 273 | + * Memoize filtered models (horde vs non-horde) so we don't recalculate |
| 274 | + * these arrays on every render (which happens frequently as the user types). |
| 275 | + */ |
| 276 | + const hordeModels = useMemo(() => { |
| 277 | + return models.filter((m) => m.provider === "horde"); |
| 278 | + }, [models]); |
| 279 | + |
| 280 | + const otherModels = useMemo(() => { |
| 281 | + return models.filter((m) => m.provider !== "horde"); |
| 282 | + }, [models]); |
| 283 | + |
| 284 | + const hasHordeModels = hordeModels.length > 0; |
| 285 | + |
273 | 286 | const fetchData = async () => { |
274 | 287 | if (!session?.user?.id) return; |
275 | 288 |
|
@@ -702,31 +715,27 @@ export function ChatbotApp() { |
702 | 715 | setSelection(m, p); |
703 | 716 | }} |
704 | 717 | > |
705 | | - {models.some((m) => m.provider === "horde") && ( |
| 718 | + {hasHordeModels && ( |
706 | 719 | <optgroup label="Default (AI Horde)"> |
707 | | - {models |
708 | | - .filter((m) => m.provider === "horde") |
709 | | - .map((m) => ( |
710 | | - <option |
711 | | - key={`${m.provider}:${m.model_id}`} |
712 | | - value={`${m.provider}:${m.model_id}`} |
713 | | - > |
714 | | - {formatModelLabel(m.provider, m.model_id)} |
715 | | - </option> |
716 | | - ))} |
717 | | - </optgroup> |
718 | | - )} |
719 | | - <optgroup label="Other Models"> |
720 | | - {models |
721 | | - .filter((m) => m.provider !== "horde") |
722 | | - .map((m) => ( |
| 720 | + {hordeModels.map((m) => ( |
723 | 721 | <option |
724 | 722 | key={`${m.provider}:${m.model_id}`} |
725 | 723 | value={`${m.provider}:${m.model_id}`} |
726 | 724 | > |
727 | 725 | {formatModelLabel(m.provider, m.model_id)} |
728 | 726 | </option> |
729 | 727 | ))} |
| 728 | + </optgroup> |
| 729 | + )} |
| 730 | + <optgroup label="Other Models"> |
| 731 | + {otherModels.map((m) => ( |
| 732 | + <option |
| 733 | + key={`${m.provider}:${m.model_id}`} |
| 734 | + value={`${m.provider}:${m.model_id}`} |
| 735 | + > |
| 736 | + {formatModelLabel(m.provider, m.model_id)} |
| 737 | + </option> |
| 738 | + ))} |
730 | 739 | </optgroup> |
731 | 740 | </select> |
732 | 741 | </div> |
|
0 commit comments