Make pages load fast on mobile

- Compress responses: page scripts and styles once (brotli or gzip, in
  memory) and cached immutable; pages and API JSON gzipped as they stream
- Service worker serves content-named assets cache-first
- Load the models modal's data when it opens (cached in localStorage)
  instead of shipping the model catalog in every conversation page
- Lazy-load the Tiptap composer and memoize thread messages
- Import lucide icons directly; twui 0.1.4 drops by-name icons from Button
- bun run start builds the pages minified before serving

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-20 13:41:45 +01:00
co-authored by Claude Opus 5.5
parent 3b355d68bc
commit c1a94fc9a5
36 changed files with 840 additions and 147 deletions
@@ -1,4 +1,4 @@
import { useContext } from "react";
import { memo, useContext } from "react";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import Row from "@moduletrace/twui/layout/Row";
@@ -31,8 +31,11 @@ type Props = {
* switch the bot to them. A quoted reply sits above it, its reactions
* below, and a row under it replies, reacts, reads it aloud and shows
* why it needs you. Its text can be selected and quoted.
*
* Memoized: a message only renders (and parses its markdown) again when
* it changes, not on every live step of the thread.
*/
export default function BotMessageLine({ message, bot_name, at }: Props) {
function BotMessageLine({ message, bot_name, at }: Props) {
const { onReact } = useContext(BotMessageActionsContext);
const can_speak = Boolean(message.id && message.text?.trim());
@@ -73,3 +76,5 @@ export default function BotMessageLine({ message, bot_name, at }: Props) {
</Stack>
);
}
export default memo(BotMessageLine);