Skip to content

[Bug] Page flickers when sending a prompt #248

@Astro-Han

Description

@Astro-Han

What happened?

Every time I send a prompt in PawWork, the page flickers briefly. The flicker appears to be caused by the composer region's ready state being toggled off and back on with a 140ms delay.

Steps to reproduce

  1. Open PawWork
  2. Navigate to a session
  3. Type a prompt and press Enter / click Send
  4. Observe the page flicker

What did you expect to happen?

The page should remain visually stable when sending a prompt, without any flicker or flash.

PawWork version

Current dev branch (latest)

OS version

macOS (observed on development machine)

Can you reproduce it again?

Yes, every time

Screenshots, recordings, or extra context

Root cause analysis

After code review, the flicker appears to come from SessionComposerRegion's ready state delay mechanism in packages/app/src/pages/session/composer/session-composer-region.tsx (lines 101-117):

createEffect(() => {
  route.sessionKey()
  const ready = props.ready
  const delay = 140

  clear()
  setStore("ready", false)  // Immediately sets ready = false
  if (!ready) return

  frame = requestAnimationFrame(() => {
    timer = window.setTimeout(() => {
      setStore("ready", true)  // 140ms later, sets back to true
    }, delay)
  })
})

The problem:

  • This effect runs when sessionKey or props.ready changes
  • It immediately sets store.ready = false every time
  • Then waits 140ms + RAF before restoring to true

This creates a brief "unready" state that likely causes the visual flicker.

Why might sending a prompt trigger this?

Although sessionKey and messagesReady() should remain stable when sending a message, other factors could cause props.ready to briefly change. The props.ready value is composed of:

ready={!store.deferRender && messagesReady()}

(from packages/app/src/pages/session.tsx line 1971)

Possible triggers:

  1. Any re-computation of sessionKey (even if value stays the same) could trigger deferRender logic
  2. SolidJS's effect tracking may capture transient state changes during async operations

Suggested investigation

  1. In browser DevTools, observe whether props.ready, store.deferRender, or messagesReady() change when sending a prompt
  2. Add logging to the effect in session-composer-region.tsx to track when it fires
  3. Check if deferRender is accidentally triggered during message submission

Potential fix directions

If confirmed, possible fixes:

  • Wrap the effect with on() to only run when values actually change (not just re-compute)
  • Only set store.ready = false when props.ready transitions from true to false
  • Evaluate whether the 140ms delay is necessary (it may be intended for smooth session switching transitions)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityappApplication behavior and product flowsbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions