Executando verificação de segurança...
1

Concordo que o custo da boundary WASM/JS é o ponto mais ignorado quando alguém cita Leptos. As demos de benchmark sempre mostram código que mal toca o DOM, que é exatamente onde WASM brilha. Numa aplicação real com formulários, drag-and-drop, animações, o custo aparece.

A vantagem de carga cognitiva pra dev solo é real, mas acho que só justifica em projetos onde o backend Rust já existe. Adotar Rust só pelo frontend seria escolher a ferramenta mais trabalhosa disponível.

Tem uma coisa que me interessa: você acha que Leptos tem espaço como alternativa pra aplicações de alto desempenho muito específicas, tipo visualização de dados em tempo real, ou mesmo nesses casos o tradeoff não compensa?

Carregando publicação patrocinada...
3

Atualmente ele brilha em aplicações com necessidade de processamento do lado do cliente, WASM consegue usar melhor os recursos da maquina do que o V8, em uma aplicação web padrão o desempenho do leptos tende a ser igual a seus pares em JS pois no ganho que ele tem de performance parte é perdida no boundary WASM -> JS + DOM. Mas quanto mais processamento você fizer no lado do cliente mais a balança tende a pender pra rust, vamos supor que você quer carregar um arquivo parquet no lado do cliente e plotar gráficos com base nesses arquivos sem enviar nada para o servidor seria extremamente mais rápido e performático em WASM, mas em um fluxo normal como um blog só se justifica em qual o usuario prefere trabalhar pois no final vai ser o mesmo, como eu disse acima os bundles WASM geralmente são maiores que os js porem isso é valido considerando o mesmo uso porém até na sua pergunta anterior sobre UI libs já mostra quase ninguem faz uma aplicação com react puro, se vai trabalhar com graficos vai entrar um chartJS, vai entrar outras libs então no final acaba empatando.

EU como dev backend e que não gosta da sintaxe de js/ts prefiro utilizar leptos até mesmo em aplicações 100% front mesmo sem backend, mas tambem sei que sou um esquisito por fazer isso e que não é a melhor ferramenta pra isso, com certeza seria infinitamente mais rapido eu fazer um front em react e teria a mesma performance mas ainda assim eu escolho o fazer em rust.

Vou deixar até um exemplo aqui: https://coffee.lukakuuhaku.dev
Essa aplicação é 100% client side o backend é 4 linhas no nginx que respondem a chamada com o index.html o js base, o css e o wasm nada mais e nada menos, levei 3h pra fazer em react levaria 30 minutos mas ainda assim faria em rust de novo e de novo.

1

Faz sentido: o overhead do boundary WASM/JS equilibra o jogo em fluxos comuns, mas processamento intensivo client-side é onde WASM realmente se destaca. O exemplo do parquet é exatamente o tipo de caso que qualquer framework JS vai sofrer, sem volta. Mas fora esse nicho de processamento pesado, Leptos tem alguma vantagem real ou é basicamente preferência de sintaxe e conforto com Rust mesmo?

3

Fora o processamento pesado e a coerência de projeto a unica vantagem real é a segurança de tipos em Rust a type safety não é opcional nem negociável, você não consegue fazer um as any quando estiver com pressa. Em TypeScript isso é disciplina, e disciplina desaparece quando o prazo encurta. O compilador do Leptos é chato exatamente por isso. Inclusive as server functions dele eu acho muito superiores às server functions do React e do Next apesar da sintaxe até lembrar um pouco.

#[server(SaveFavorites, "/api")]
pub async fn save_favorites(
    favorite_cookie_type: String,
    favorite_color: String,
) -> Result<(), ServerFnError> {
    let pool = get_pool()?;

    let query = "
        INSERT INTO COOKIES 
        (favorite_cookie_type, favorite_color)
        VALUES ($1, $2)
    ";

    sqlx::query(query)
        .bind(favorite_cookie_type)
        .bind(favorite_color)
        .execute(&pool)
        .await
        .map_err(|e| 
            ServerFnError::ServerError(e.to_string())?;

    Ok(format!("Here, have some {favorite_color} {favorite_cookie_type} cookies!"))
}

#[component]
pub fn FavoritesForm() -> impl IntoView {
    let favorites = create_server_action::<SaveFavorites>();
    let value = favorites.value();
    view! { 
        <ActionForm action=favorites>
            <label>
                "Favorite type of cookie"
                <input
                    type="text"
                    name="favorite_cookie_type"
                />
            </label>
            <label>
                "Favorite color"
                <input
                    type="text"
                    name="favorite_color"
                />
            </label>
            <input type="submit"/>
        </ActionForm>
        <Show when=favorites.pending()>
            <div>"Loading..."</div>
        </Show>
        <Show when=move || value.with(Option::is_some)>
            <div>{value}</div>
        </Show>
    }
}

(codigo acima é um exemplo da propria documentação do leptos)

Mas isso é apenas coisa de detalhe que não dá nenhuma vantagem em runtime, se a aplicação for bem escrita isso não importa em nenhuma delas, então sim é simplesmente preferencia de sintaxe e conforto com Rust.

1

O ponto do as any é real e bom. TypeScript te dá uma rede de segurança que você mesmo pode cortar quando o prazo aperta. Com Rust o compilador não negocia, você resolve o problema ou não compila.

As server functions do Leptos são interessantes exatamente por isso: o contrato entre cliente e servidor é verificado em tempo de compilação, não em runtime. No Next você descobre o erro quando o usuário já recebeu um 500.

O custo é a curva de aprendizado e o ecossistema ainda enxuto. Para projetos pessoais ou times que já conhecem Rust, vale muito. Para um time misto contratando devs no mercado, ainda é uma aposta arriscada.

Você usa Leptos em produção ou ainda é exploração?

3

Em produção ainda não, no meu trabalho raramente tenho que mexer com frontend e quando preciso é coisa basica e eu geralmente faço paginas estáticas, mas tô começando a migrar projetos pessoais meu que eu fiz o front com react (cheio de gambiarra do pra falar que tem front) pra leptos, como por exemplo o painel de admin da minha api para whatsapp que é escrita em go e fiz o front em react, esse sim tá em produção e uso em diversos projetos meus e daqui umas 4 ou 5 semanas devo finalizar essa migração.

1

Leptos é uma escolha bem corajosa pra painel em produção. Tem bem menos material disponível comparado ao React e o modelo de reatividade é diferente do que a maioria está acostumada. Curioso pra saber: a migração tá sendo mais difícil pela falta de ecossistema ou pela mudança de paradigma do Rust em si? E o que te motivou a migrar o painel de admin especificamente, em vez de deixar como estava?

3

A parte mais dificil da migração está sendo por causa da gambiarra que é o codigo react que fiz, a maior parte dos componentes nem sei por que existem e a que eu sei tá tudo feito do pior jeito possivel, a migração foi motivada justamente pela dificuldade que é dar manutenção nesse painel então eu já teria que reescrever então optei por trocar a stack inteira logo e fazer em uma linguagem que eu trabalhe melhor.

1

Faz todo sentido trocar a stack quando a reescrita já é inevitável de qualquer jeito. React mal estruturado é das piores heranças, porque a liberdade da biblioteca vira armadilha: cada dev fez do seu jeito, sem convenção nenhuma. Qual stack você foi?

1

A stack original era go + chi + whatsmeow pro backend, postgres de db e redis para as sessões ativas e React puro mesmo pro front, front não é muito minha praia então ficou bem basicão mesmo sem muita firula não fiquei usando libs nem nada só ficou cheio de gambiarra. Agora o backend se mantém até pensei em migrar pra rust e usar axum + whatsapp-rust mas a lib do whatsapp rust é bem nova e foi feita pensando em usar um sqlite por sessão para o whatsapp e pro meu objetivo que é pra colocar centenas de sessões simultâneas eu iria ter que reescrever a implementação do db então decidi manter e usar leptos CSR consumindo a api. A vantagem é que se depois eu quiser fazer um app desktop e mobile pra gerenciar fica fácil que leptos compila bem de boa no tauri.