How to adjust redraw performance on window resize?

I’m learning iced and noticed that all app examples (and even the showcase apps) have resize glitches.

As Iced is partly redrawn on each event, it slightly affects performance.

But for me each resize makes the whole widget tree bounce and twitch.

Is there something we can do with it? MacBook M3, macOS 15

Example to reproduce:

use iced::widget::{button, column, container, row, text, text_input};
use iced::{Element, Length, Task};

fn main() -> iced::Result {
    iced::run("Notes", State::update, State::view)
}

#[derive(Default)]
struct State {
    input_value: String,
    notes: Vec<String>,
}

#[derive(Debug, Clone)]
enum Message {
    InputChanged(String),
    AddNote,
    DeleteNote(usize),
}

impl State {
    fn update(state: &mut Self, message: Message) -> Task<Message> {
        match message {
            Message::InputChanged(value) => {
                state.input_value = value;
                Task::none()
            }
            Message::AddNote => {
                if !state.input_value.is_empty() {
                    state.notes.push(state.input_value.clone());
                    state.input_value = String::new();
                }
                Task::none()
            }
            Message::DeleteNote(index) => {
                if index < state.notes.len() {
                    state.notes.remove(index);
                }
                Task::none()
            }
  Preformatted text      }
    }

    fn view(state: &Self) -> Element<Message> {
        // Input field and add button
        let input = text_input("Enter a note...", &state.input_value)
            .on_input(Message::InputChanged)
            .padding(10);

        let add_button = button(text("Add Note"))
            .on_press(Message::AddNote)
            .padding(10);

        let controls = row![input, add_button].spacing(10);

        // Notes list
        let mut notes_list = column![]
            .spacing(10)
            .width(Length::FillPortion(2));

        for (i, note) in state.notes.iter().enumerate() {
            let note_row = row![
                text(note),
                button(text("Delete"))
                    .on_press(Message::DeleteNote(i))
                    .padding(5)
            ]
            .spacing(10);

            notes_list = notes_list.push(note_row);
        }

        // If no notes, show a message
        if state.notes.is_empty() {
            notes_list = notes_list.push(text("No notes yet. Add one above!"));
        }

        // Main layout
        let content = column![
            controls,
            notes_list,
        ]
        .spacing(20)
        .padding(20);

        container(content)
            .width(Length::Fill)
            .height(Length::Fill)
            .into()
    }
}

Here’s the video of glitch: https://www.youtube.com/watch?v=ldqlLI4Whc4

I got the same issue on linux (wayland/x11). Although the glitch looks different. But I have never tested in release mode. Have you tried that?

I’ve run cargo run --release and the result it the same. Is seems that GUI engine just can’t handle such fast recalculations.

BTW, reference apps like Halloy work absolutely the same for me — same resize glitches and slow GUI recalculations.

FWIW, resizing from the top corners of the window doesn’t cause this behavior on Mac OS — at least based on my own perception.

Other than that I can confirm this “bug” occurs as described.

iced is perfectly capable of rendering at maximum framerate in an M3.

I can reproduce the issue with the barebones hello-triangle example in wgpu; so this is likely to be a synchronization problem between window, renderer, and compositor. Nothing directly related to iced.

1 Like