Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Individual item render order is reversed #3673

Open
1 of 3 tasks
Cationiz3r opened this issue Jun 19, 2024 · 1 comment
Open
1 of 3 tasks

Individual item render order is reversed #3673

Cationiz3r opened this issue Jun 19, 2024 · 1 comment
Labels

Comments

@Cationiz3r
Copy link

Problem

The numbers are arranged in the correct order (from 1 to 5) after being rendered, but the order in which each is rendered, reported by gloo_console::debug!, are reversed (from 5 to 1).

I currently maintain a file managing application that display files in a grid.
When a directory contains images, their thumbnails will be rendered as img elements, but in the aforementioned order.
Because the browser sees the last element first, it also downloads and displays image data from last to first.
Over a weak internet connection, this becomes really noticeable, which is undesirable.

Steps To Reproduce
Run the following code (with trunk).

use yew::prelude::*;

#[derive(Debug, PartialEq, Properties)]
struct Properties {
    pub num: i32,
}

#[function_component]
fn Number(props: &Properties) -> Html {
    let num = props.num;
    gloo_console::debug!(format!("Render: {}", num)); // DEBUG:
    html! { <div>{ props.num }</div> }
}

#[function_component]
fn App() -> Html {
    let numbers = 1..=5;
    numbers.map(|num| html! { <Number {num} /> }).collect()
}

fn main() { yew::Renderer::<App>::new().render(); }

Expected behavior
I expect the debug messages to appear in the same order as the numbers.

Screenshots
Taken from the browser web console (Ctrl+Shift+K).

240619_131725

Environment:

  • Yew version: yew = { version = "0.21.0", features = ["csr"] }
  • Rust version: cargo 1.81.0-nightly (a1f47ec3f 2024-06-15)
  • Target, if relevant: wasm32-unknown-unknown
  • Build tool, if relevant: trunk
  • OS, if relevent: Linux 6.9.4-hardened1-1-hardened
  • Browser and version, if relevant: Firefox 126.0.1

Questionnaire

  • I'm interested in fixing this myself but don't know where to start
  • I would like to fix and I have a solution
  • I don't have time to fix this right now, but maybe later
@Cationiz3r Cationiz3r added the bug label Jun 19, 2024
@WorldSEnder
Copy link
Member

Depending on the exact render-order of each item sounds like a not-so-good idea. I agree that it is unintuitive to see the specific components render in opposite order, but from a contract perspective, yew does so far not guarantee any order, they might also render "randomly" or not even in a consistent order. This has to do with the order in which we traverse the component tree and we might change it at any time, due to e.g. changing the format in which we render SSR and other details.

To give a potential solution to this problem: You might get away with add replacement images by first rendering a placeholder with inline data, such as (you can probably golf this a little and have better size constraints)

data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgMzUwIiB3aWR0aD0iNjAwIiBoZWlnaHQ9IjM1MCI+CiAgPHJlY3Qgd2lkdGg9IjYwMCIgaGVpZ2h0PSIzNTAiIGZpbGw9IiNjY2NjY2MiPjwvcmVjdD4KICA8dGV4dCB4PSI1MCUiIHk9IjUwJSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1mYW1pbHk9Im1vbm9zcGFjZSIgZm9udC1zaXplPSIyNnB4IiBmaWxsPSIjMzMzMzMzIj42MDB4MzUwPC90ZXh0PiAgIAo8L3N2Zz4=

and then, after you initially rendered in an use_effect, replace the src with your actual image src but trigger it only when your image is actually on screen or close to being relevant. This should already noticably improve your UX. I suspect that in your use case, these effects might again trigger in an undesirable order for items that are initially on screen. Perhaps you can slightly delay setting the src and fix the order by collecting into a buffer in the use_effect and wasm_bindgen_futures::spawn_local` the part that drains this buffer (in your desired order) and sets the src.

Again, this sounds like a work-around, but as a framework we try to not commit to a specific render order. While unintuitive, the problem is not super straight-forward to answer in any case once you try to argue for post/pre/in-order or depth-first/breadth-first creation of component hierarchies (keep in mind that the creation of the actual DOM and the calls to the view function which returns virtual DOM might also not happen in the same order. As such, your debug statement in the component's view function does not necessarily capture the order in which the <img> elements are created).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants