Electron: Why does BrowserView has better performance then Webview? - webview

I've read about both Webview and BrowserView, They seem to do the same thing: Embed additional web content into application. I know that Electron's webview tag is based on Chromium's webview and this API is part of the deprecated Chrome Apps platform. Even Electron suggest to not use Webview and consider alternatives (iframe, BrowserView).
But what changes made BrowserView superior? I know that unlike the Webview, the BrowserView does not use another renderer process, is that why BrowserView has better performance? What are the other indicators? How is BrowserView different from Webview internally?

This isn't by any means a complete answer, but BrowserView was created because of various issues encountered with webview.
Here's a blog post by the people that created it:
a new way to embed web apps with fewer bugs and improved performance
webviews seemed to work well at first, but over time we ran into an ever growing list of issues. There were bugs in fundamental features like drag-and-drop and general performance was simply not on par with Chrome.
Electron's webview documentation says:
Electron's webview tag is based on Chromium's webview, which is undergoing dramatic architectural changes. This impacts the stability of webviews, including rendering, navigation, and event routing.
There were a number of webview bugs back in the day, though these particular ones appear to be fixed.
Here's an issue about the fate of BrowserView where a maintainer says:
<webview> still has a number of bugs. There are also architectural issues like slow auto-resizing that are unlikely to be fixed in Chromium any time soon
Here are a number of webview bugs (though you can certainly find bugs with BrowserView as well)
Also, you say:
the BrowserView does not use another renderer process
I believe I saw a reference to that somewhere as well, but I don't think that's true.
The moment you navigate the BrowserView to a page, a new renderer process is created for it.
Update: Oh, I think what's meant here is that the webview == 1 process and a BrowserView == 1 process, but you create the webview inside of another Renderer process, whereas you create the BrowserView inside of the main process. So there will be an extra process with webview.

Related

Why is this page loading so slowly as an iframe, but normal when visited directly?

I have a set of iPads (3rd gen) running iOS 9.3.5. This is the highest they support. I am attempting to replace the functionality of a custom iOS app with an equivalent web application. The site is built in Angular 11, targeting es2015, and I've declared iOS > 9 in the browser support file. The majority of the site performs exactly as I would expect for such old devices. The linchpin of the whole thing is this third party form that needs to be filled out that is served up as an iframe, and it performs so, so horribly.
Here is the code of component HTML with the iframe (URL changed for privacy):
<div class="row header"><a class="restart" (click)='restart()'>Start Over</a><a routerLink='/welcome'><i class="fa fa-times close-x"></i></a></div>
<iframe src="https://notarealsite.com" (load)="waiverLoaded()"></iframe>
The waiverLoaded function is a simple boolean flip to detect the embedded page reloading upon completion so that I can route to a different component in my app. The performance is unchanged if the iframe is the only element on the page. Other pages that play nice when embedded do not suffer a performance drop like the waiver does, so I have to assume it's something in the code of the waiver page.
The original custom iOS app uses a webviewer to load the page, and it loads in 2 seconds or less. The same performance can be seen by visiting the page directly in Safari. In both instances the responsiveness of the dynamic form is reasonable given the age of the devices. When loading the page via an iframe the performance tanks. We're talking 30-45 seconds of loading, and sometimes up to a full second delay between tapping a button or field, and the form reacting.
I have attached the device to my computer and used the remote inspector in the MacOS Safari to view the timeline. The majority of the initial load time is the several 1-2 kb image files used by the form like the scroll bar and some icons. Usually one of these items ends up taking 20-25 seconds all for themselves. When interacting with the form there's an XML resource that appears in the timeline every field change or button press, and that is what takes around a second or two before the page is up to date again.
I'm not well versed in troubleshooting web application performance like this, and this is my first real Angular application that I've built, so I might be missing something painfully obvious. What can contribute to such a difference in performance between a page being visited directly, vs being placed in an iframe?
Some additional info:
The performance is the same between running locally via npm serve or built and deployed to my local server.
I have tried hosting it via HTTP and HTTPS in case it was some security hangup, as the form is only delivered via HTTPS. However I only have a self-signed cert at the moment.
I have seen no discernable difference in load times between the two methods on my other devices, including an iPad Air running iOS 12.5.2.
There is a warning in the console about jQuery support on iOS 9.3.5 being outdated, but it occurs in both scenarios.
Additional Troubleshooting
I've tried to look into some of the suggestions I've received. I've checked the timings and headers on the slow loading elements in Safari in the following configurations:
In the iframe on my app on the iPad.
Visited directly on the iPad.
In the iframe on my app on my MacBook Pro.
Visited directly on my MacBook Pro.
On my laptop the performance is nearly identical. Comparatively, on the iPad the actual load times of all the elements is within a millisecond or two of their times on my laptop. What ends up being notably different is the latency between request and response for the elements.
The latency when visiting directly is higher than on my laptop. When loading through the iframe all the timings increase fairly proportionally. A time of 750ms jumps to 4s. A time of 6s jumps to 30s.
Lastly, a real oddity to me, is the super high latency image for some reason results in a 302 to Cloudflare, but only on the iPad. It doesn't matter if it's through the iframe or direct. Both devices are using the same WiFi network. I can't think of a reason for the redirect to happen unless the destination site is handling the iPad differently somehow. Changing the UserAgent in Safari on my laptop to match the iPad doesn't result in the same redirect.
So I've confirmed that even outside of the iframe the site in question behaves differently on iOS 9.3.5 than on newer versions, and compared to my computers.
Please post your code for us to diagnose and help. In general there is more overhead for an IFrame my suspicion is the jQuery handler or cookie policy, to be sage I also listed other items to check.
It looks like you already checked the previous unsecured elements which was an issue. Both in the network graph and the calls, double check there are no dependencies or URL calls of the Iframe of unsecured elements then it wont display, it used make multiple round trips if Https had mixed content between secure and non-secure stuff, there's a ticket for A new TLS issue.
Once you fix that ensuring its hosted/called securely, clear the cache, cookies, data completely and reloading the page fixes the problem even on mobile browsers.
Redirects/Bouncing Your order of loading scripts/css, if there are dependent scripts and they are not cached it could be blocking, or if its redirecting back to HTTP this will also slow it down.
For IOS mobile apps only (doesn't apply here) - if you are using the 3rd gen, check the default for Cookie Security policy (HTTPCookieAcceptPolicy) for UIWebView has changed to NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
Animations Are slow in safari Iframes
You have the click event in your code, could be the issue
..."Turns out that any non-anchor element assigned a click handler in jQuery must either have an onClick attribute (can be empty like below):"...
Put the following element declaration cursor:pointer or tap event

Electron - simpler way of communicating between windows?

I need to build a web based interface for a quick personal project and I'd like to use electron.
It's essentially a kind of gaming Zoom app with lots of bells and whistles.
The problem is, I need to have a main window that will run in fullscreen, which I capture with OBS and broadcast to a popular streaming service.
I also need another window, what I refer to as the Control Panel, to control elements in the main window that I work with behind-the-scenes, for showing graphics, playing sound effects, controlling video settings etc.
If I were to code this app for a web browser, I would have absolutely no problem, as I can create the secondary window from my main window (window.open) and the 2 windows can easily refer to one another and their documents.
In electron however, windows are essentially contained boxes. Communication between 2 windows has to be channelled via ipc essentially as encoded commands and interpreted by the main process...
So to control loads of elements and entities from my control panel, I'd either have to implement a complex messaging system, which frankly seems MASSIVELY unnecessary, or to be hacky I could simply issue javascript commands as strings to the other window with BrowserWindow.webContents.executeJavaScript()... but yuck.
I could also contain all the logic-y stuff in the main process, but again, this still requires a messaging system that I don't have the time to implement.
I guess I want to know if there's a better way.
I'm just imagining a scenario win which a developer has written a web-app that uses multiple windows and lots of direct window-to-window communication, and now they need to migrate it to electron... how would they best go about it without re-writing a ton of code?
Found my answer, 'nativeWindowOpen':
main_window = new electron.BrowserWindow({
webPreferences: {
nativeWindowOpen: true
}
});
I can now use window.open() from my main window and refer directly back and forth.
So now I can do this:
control_panel = window.open("./control_panel.html", "Control Panel", "width=720,height=480")
console.log(control_panel.document)
And from the opened window:
console.log(window.opener.document)
And I can refer to variables and document elements.
I couldn't find anyone mentioning this useful 'nativeWindowOpen' option when I was scouring stackoverflow et al earlier, only found it by reading documentation.

jQuery Mobile freezes while scrolling

While scrolling my jQuery Mobile enabled site on a mobile device (at least iPhone 4 and 5), it almost always freezes for a few seconds, sometimes significantly longer. Usually it eventually just crashes and I have to kill Safari (or Chrome) from memory.
I'm having trouble identifying the cause. I know they state there are issues with transitions, and I tried adding .ui-page { -webkit-backface-visibility: hidden }, but it didn't help.
I'm guessing it might have to do with one or more scripts that are running. My scripts file essentially contains a set of scripts that run for both desktop and mobile, and two more sets that run exclusively for desktops and mobiles respectively. The common set is wrapped in a conditional ready function, $(document).ready for desktop and $(document).on('pageinit) for mobiles.
Also, based on the device, all the scripts are either loaded in the footer for desktops and the head for mobiles. However, the main scripts file is loaded in the footer for both. The scripts wouldn't work on mobiles otherwise.
Not sure if iOS preventing DOM manipulation on scroll is conflicting with something.
I would just link the site, but professional confidentiality and all that.
I'm not asking you to just guess what the cause may be, but I would really appreciate an outline of some fundamental principles of developing with jQuery Mobile to optimize performance.
According to the documentation (navigate to "scrollstart"), it is expected that DOM manipulation is frozen during scroll in iOS devices, even in iOS 7.

JavaFX embeded browser memory leak

I am using embedded browser in JavaFX. On my webpage, using Javascript, I dynamically create lots of checkboxes + some other components and remove them from the DOM afterwards. What is strange, after performing every "create/remove" cycle the memory usage is growing. Maybe it could be related to the click events attached to my elements? It seems like a memory leak, I have no idea how could I fix this. In regular browser like Chrome everything works fine.
I don't have much experience with finding memory leaks but I've been meaning to use Plumbr to test my JavaFX app for those - maybe you can use that?
You might have to sit there and keep clicking on stuff or script lots of interaction for Plumbr to notice the leak, since it seems to be focused on JSP apps which have a lot of simultaneous users.

External game with Loader doesn't work in Flash, Action Script 3

I'd like to load a 3rd party game into my own swf so I can take a picture of it. I'm using the standard flash.display.Loader class for the loading part.
Example of a 3rd party game: http://andkon.com/arcade/adventureaction/megaminer/megaminer.swf
Embedding it inside an html document seems to work fine, but not with the Loader.
So it obviously works in one case, there has to be a way to load it with ActionScript the same way a simple html <embed> does.
There are no error messages, Event.COMPLETE fires, but the game is stuck at the loading screen.
(Sidenotes: I have a working script that loads some games perfectly, but there are ones like this that won't load properly. I also have a a proxy set up in PHP to get around cross-origin permission errors)
It sounds to me like it's loading just fine (when you link directly to the game, it stays at the loading screen anyway, which suggests that's the right behavior).
So the problem isn't with the loading, it's to do with the wrapper you're loading it into. When you view it on whichever website is hosted, chances are you're looking at a wrapper swf which is loading that game into it - and as per the guidelines of the site hosting it, the wrapper swf will call a start function or something similar to kick it off. You'd need to see what needs to be called on the swf to start it.
You might be able to look on a site where it's being hosted and see if they publicly give out their guidelines for game devs, but I had a little glance around and it doesn't look like they do.
Or you could decompile the wrapper swf and see what function it's calling... Though I don't promise they'd be okay with you doing that.
So there's no wrapper swf... Perhaps the game is doing a check to see if its width and height match a predefined size before it begins?

Resources