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

Support Rc in html! attributes #1851

Closed
tv42 opened this issue May 17, 2021 · 1 comment · Fixed by #1994
Closed

Support Rc in html! attributes #1851

tv42 opened this issue May 17, 2021 · 1 comment · Fixed by #1994
Labels
A-yew Area: The main yew crate A-yew-macro Area: The yew-macro crate feature-accepted A feature request that has been accepted and needs implementing feature-request A feature request

Comments

@tv42
Copy link

tv42 commented May 17, 2021

Yew 0.17.4 silently cloned Strings passed in e.g. html!{<p foo=&self.a_String}. String::clone copies the contents of the string, which is wasteful.

v0.18.0 removes the silent clone, and while the easy fix would be to just move the clone up the stack to my Component::view, copying string contents on every view seems wasteful. That was the motivation for the change in the first place!

At first, it seems using Cow would help, but after some discussion I believe the current use of Cow<'static, str> still causes String content copies when the string has a lifetime less than 'static, e.g. strings originating from messages to Component::update.

It seems using Rc<str> or such would lead to string content copying happening only in Component::update (and typically, only for one variant of the Component::Message enum), so that would be a nice improvement.

It would be great if yew's vdom understood Rc<str> (and perhaps Arc also) and allowed using reference counts to enable cheap clones, instead of expensive string content copies.

Concretely:

struct Model {
    foo: Rc<str>
}
...
enum Msg {
    UpdateFoo { s: String },
...
    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        match msg {
            Msg::UpdateFoo { s } => {
                // make String into a str, but then pass a reference to Rc::from
                self.foo = Rc::from(&*s);
            }
...
    fn view(&self) -> Html {
        html! {
            <p foo=&self.foo>
            </p>

It should also be possible to push the Rc (or just str) up front all the way to the message source, to avoid even the copy in `Component::update``, but that shouldn't require anything from yew.

@tv42 tv42 added the bug label May 17, 2021
@siku2 siku2 added feature-request A feature request and removed bug labels May 17, 2021
@ranile
Copy link
Member

ranile commented Aug 9, 2021

A good solution would be have a custom type for this:

enum AttrValue {
    Borrowed(&'static str),
    Owned(String),
    ReferenceCounted(Rc<str>),
}

The VDom can then use this value.

@mc1098 mc1098 added A-yew Area: The main yew crate A-yew-macro Area: The yew-macro crate feature-accepted A feature request that has been accepted and needs implementing labels Sep 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-yew Area: The main yew crate A-yew-macro Area: The yew-macro crate feature-accepted A feature request that has been accepted and needs implementing feature-request A feature request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants