Skip to content

perf: add optimistic updates for comment and attachment mutations #65

@macwilling

Description

@macwilling

Problem

Two high-traffic interactions wait for a full server round-trip before reflecting changes in the UI:

  1. Comment creation (CommentThread.tsx) — after submitting, the new comment is invisible until revalidatePath completes server-side. The form resets but nothing appears.
  2. Comment delete (CommentThread.tsx) — the deleted comment stays visible until the page re-renders after the server action.
  3. Attachment delete (AttachmentsList.tsx) — deleted attachment stays in the grid until router.refresh() completes.

Fix

Comment creation — optimistic insert

Lift comments into local state in CommentThread and prepend a temporary comment immediately on submit:

const [localComments, setLocalComments] = useState(comments);

// On submit (before awaiting server action):
setLocalComments(prev => [{
  id: `temp-${Date.now()}`,
  body,
  author_role: currentUserRole,
  author_id: currentUserId,
  created_at: new Date().toISOString(),
}, ...prev]);

On server error, revert to the previous state.

Comment + attachment delete — optimistic removal

Use useOptimistic to filter the item out immediately:

const [optimisticAttachments, removeOptimistic] = useOptimistic(
  attachments,
  (state, idToRemove: string) => state.filter(a => a.id !== idToRemove)
);

startTransition(async () => {
  removeOptimistic(id); // instant
  await deleteAttachmentAction(id, taskId);
});

Acceptance criteria

  • New comment appears in thread immediately on submit, before server responds
  • Deleted comment disappears from thread immediately on delete confirm
  • Deleted attachment disappears from grid immediately on delete confirm
  • On server error, the optimistic state reverts and an inline error is shown
  • npm run build passes

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsize:MMedium effort

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions