tauri-apps / wry

Cross-platform WebView library in Rust for Tauri.
Apache License 2.0
3.5k stars 261 forks source link

wry's webkitgtk2 performance is noticeably slower than previous versions #1315

Open imgurbot12 opened 1 month ago

imgurbot12 commented 1 month ago

After upgrading one of my desktop apps from dioxus v0.4.3 to v0.5.1. I noticed a considerable increase in time to initial render on linux using webkitgtk2 which I believe can be attributed to something within wry.

To demonstrate this, I implemented the same script in wry's v0.28.0 tag which is what dioxus v0.4.3 uses and the latest version in wry's dev branch.

Here is the snippet from v0.28.0 which was modified and run from the "hello_world" example:

use wry::{
  application::{
    event::{Event, StartCause, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::WindowBuilder,
  },
  webview::WebViewBuilder,
};

fn main() -> wry::Result<()> {
  let mut now = std::time::Instant::now();
  let event_loop = EventLoop::new();
  let window = WindowBuilder::new()
    .with_title("Hello World")
    .build(&event_loop)
    .unwrap();
  let _webview = WebViewBuilder::new(window)?
    .with_url("http://localhost:8000")?
    // .with_incognito(true)
    .build()?;

  event_loop.run(move |event, _, control_flow| {
    *control_flow = ControlFlow::Wait;

    match event {
      Event::NewEvents(StartCause::Init) => {
        println!("Wry has started! {:?}", now.elapsed());
        now = std::time::Instant::now();
        std::thread::spawn(move || {
          std::thread::sleep(std::time::Duration::from_millis(1000));
          println!("Wry is stopping! {:?}", now.elapsed());
          std::process::exit(0);
        });
      }
      _ => {}
    }
  });
}

And here is the version for the dev branch which was modified and run from the "simple" example:

use tao::{
  event::{Event, StartCause, WindowEvent},
  event_loop::{ControlFlow, EventLoop},
  window::WindowBuilder,
};
use wry::WebViewBuilder;

fn main() -> wry::Result<()> {
  let mut now = std::time::Instant::now();
  let event_loop = EventLoop::new();
  let window = WindowBuilder::new()
    .with_title("Hello World")
    .build(&event_loop)
    .unwrap();

  let builder = {
    use tao::platform::unix::WindowExtUnix;
    use wry::WebViewBuilderExtUnix;
    let vbox = window.default_vbox().unwrap();
    WebViewBuilder::new_gtk(vbox)
  };

  let _webview = builder.with_url("http://localhost:8000").build()?;

  event_loop.run(move |event, _, control_flow| {
    *control_flow = ControlFlow::Wait;

    match event {
      Event::NewEvents(StartCause::Init) => {
        println!("Wry has started! {:?}", now.elapsed());
        now = std::time::Instant::now();
        std::thread::spawn(move || {
          std::thread::sleep(std::time::Duration::from_millis(1000));
          println!("Wry is stopping! {:?}", now.elapsed());
          std::process::exit(0);
        });
      }
      _ => {}
    }
  });
}

Both scripts were called by running the following command:

$ time cargo run --example <example> --release

You can see in the video posted that there is a consistent difference of about 0.5s or 500ms on startup between the old version which is faster vs the new version which matches my testing between the old and new version of my dioxus app.

Video is available here: https://imgur.com/a/2y6r7rs (github was being weird about the upload sorry.)

imgurbot12 commented 1 month ago

For the sake of clarity and fairness I should make a correction to my previous statement. The 500ms issue seems to be based on tests for wry v0.37.0 which is what dioxus v0.5.1 is using. After manually upgrading dioxus to the latest wry version: v0.41.0 and testing via dioxus, the issue is much improved.

However, there is still about a 100ms/150ms difference even with the latest version when running wry through dioxus which is more accurately reflected in the rough testing that I did in the video. Looking back at the time's in the video it's definitely not 500ms lol.

Using hyperfine to test wry directly with those same tests scripts produces similar repeatable results:

for version v0.41.0:

$ hyperfine ./target/release/examples/simple
Benchmark 1: ./target/release/examples/simple
  Time (mean ± σ):      1.165 s ±  0.006 s    [User: 0.118 s, System: 0.095 s]
  Range (min … max):    1.155 s …  1.178 s    10 runs

for version: v0.28.0

hyperfine ./target/release/examples/hello_world
Benchmark 1: ./target/release/examples/hello_world
  Time (mean ± σ):      1.160 s ±  0.007 s    [User: 0.113 s, System: 0.091 s]
  Range (min … max):    1.151 s …  1.172 s    10 runs

The ranges are much closer together on rapid use but you can see the highs and lows are far apart, with the longest cold startup on v0.41.0 being ~150ms slower than the fastest startup on v0.28.0, with an avg difference of 50ms.

This issue seems exasperated when running wry via dioxus for whatever reason as its much more repeatably 100ms slower regardless of circumstances.