WKWebView, an Electron alternative on macOS/iOS
holtwick.de
holtwick.de
* Adding new APIs was a huge pain in the ass, you had to write all of this ugly bridge code in Objective C, and the APIs ended up being super unnatural on the JS side. As a result, desktop integration wasn't done much since it felt like a "Black Magic" type thing. Writing new APIs in Electron is Just JavaScript, so you can make something much more natural.
* We could literally do fuck-all for people running old versions of macOS - you can't upgrade Safari on old machines, you just Get What You Get. For awhile, every YouTube video on older macOS versions had a pink shade to it. Users write in, "This is clearly wrong!" "Yep, but we can't fix it. Sorry."
* And big spoiler - WKWebView uses _basically_ the same amount of memory give-or-take a few MBs as Chromium. It's the content that sets the memory usage bar, not the host.
It really doesn’t. A “Hello, World” WKWebView is a couple of megabytes. The same in an Electron app is hundreds of megabytes.
Both are playing low-quality HTML5 video.
For any sites I could think of, the memory usage, thread count, CPU time, and idle wake ups were considerably smaller using WKWebView.
The disk usage was also crazy smaller, as is expected. ~122MB for nativefier vs ~14MB for WKWebView (and a lot of that is due to being written in Swift).
In the case of an Electron app disk space might not matter as much, but it's absolutely worth optimizing in 2018, at least because not everyone has high speed connections (e.g. in Germany, a lot of infrastructure is built around DSL, which obviously doesn't get great speeds).
3D models vs. app code.
You will be hard pressed to find any Electron app that exceeds 200 MB in disk space. Most are ~50 MB. Overall in 2018 that is not a big concern.
In gaming, high definition graphics are going to result in massively larger files. That’s not going to change anytime soon and no gaming company will prioritize a small download over better graphics.
Huh? Looking at my applications folder right now:
Atom 1.31: 822mb
Daedalus 0.8: 265mb
Mist 0.9.2: 186mb
Neon 0.0.7: 180mb
Patchwork: 185mb
Riot 0.11.4: 160mb
VS Code: 193mb
The electron framework alone is 117mb on MacOS. Honestly, how many copies of that do I need?
RDR2's size comes from media files (high-resolution textures, models, audio).
Pray-tell, what magic compression technique would you use to do better AND still support 4K textures?
How about downloading textures and movies on demand in the background when you enter new areas? It's not like all that stuff is required for the game to start.
Given that most people can't tell the difference between high grade mp3 and uncompressed it seems likely that this could be something like mp3.
Also, this is why the big console makers are investing in cloud-consoles.
Edit: I just checked, and even now that they've added multiplayer to the game (which didn't come on the physical disk), the patch for a new installation of RDR2 is 8 GB. Meanwhile, Fallout 76 is 50 GB and COD:BO4 is 65 GB.
If you want more future proof a 1TB ssd can be found for around $150.
On the practical side, why not do as gp suggests and use an external drive? You’ll likely need additional storage with any of the lower spec’d Macs anyway, electron or not.
but if you have dozens of these it becomes a struggle even for high end desktops
In order to be in your position your company had to simultaneously overpay AND underpay. How can you be so cost conscious that you say nah give them the tiny ssd it costs less while shelling out 2400+ per unit
actually I'd do the same with any netbook, but being limited additionally by the OS is even worse
either I get the proper tools or refuse to struggle
What exactly are proper tools? I'm designing a set of web-based tools to help their day to day operations. Lots of shell scripting and what not to just allow people to drag-n-drop and automagically get things to happen, consistently. Are you saying that the proper tool to write php/css/js/shell scripts/etc can only be found not on a Mac? I have found the world becomes a much easier place to live in if/when you can just accept what is on hand and get the job done. Could it be better? Possibly. Is this my favorite laptop? Nope. Can I do what I've been tasked with to get it done? Absolutely. I'm actually quite thankful that I'm not a one trick pony and I can use pretty much any OS put in front of me.
and seriously, using slow and noisy machine with poor multitasking and overall terrible UX WILL slow me down considerably, it's not worth it also for employer
and you know what? I've done it before already and been the happy guy in the office laughing at all the trouble people forced to use macs had
EDIT: ofc if I'd know beforehand that mac is the only option I simply wouldn't apply to that place, there's no reason to make your own work lower quality
The litany of Electron apps don't even come close to being an issue (I arguably have more than the average person, too, thanks to every stupid crypto wallet from the past few years).
tl;dr you're making a mountain out of a molehill.
They've have an app that doesn't suck for one. Which you know, would help conversions.
Its not hard to write a Mac app, and its even easier to maintain it. ESPECIALLY if you already have an iOS app.
There is no reason not to just make a decent Mac app. NONE.
I don’t think it sucks, most users don’t think it sucks. You represent a tiny, vocal minority.
This was the amount of work necessary for me to ditch running Slack in a Safari tab, and basically consists of being able to talk to people and send them attachments–the things I do 99% of the time. If I need something advanced like voice calling I’m more than happy to fire up actual Slack. Assuming libslack (or whatever it is called) handles the core protocol and communication layer, I don’t see why it would be difficult to write a bit of Cocoa code around it; I could even pull some of this straight from the iOS app.
> switching from electron to native won’t make people’s battery last hours longer
It does, though. Opening Slack on my computer reduces the battery life by around two hours; a well made native app will have a reduction that can be measured in minutes. Native apps are just better at idling and using fewer resources when they are in active use.
I can see why it might potentially be attractive in purely architectural terms, but I wonder if the “savings” meaningfully materialise in practice when so little pure native development occurs in C++ on iOS and Android.
Regardless, there’s still a complexity cost - unique native platform UI code is still unique native code, plus all the localisation, QA testing, etc, etc fun that will entail for an app the size of Slack.
I think Microsoft Office does this too, and I’m pretty pleased with the results, performance and UI wise. In my opinion, this is probably the best way to actually do decent cross-platform development. One of the projects that I am tangentially involved in is doing this, but swapping out C++ with Rust.
> I recall reading years ago Dropbox trying this
Last I heard, Dropbox has moved towards using Python for everything, which gives them kinda horrible performance IMO.
> I can see why it might potentially be attractive in purely architectural terms, but I wonder if the “savings” meaningfully materialise in practice when so little pure native development occurs in C++ on iOS and Android.
Generally, all the cross-platform, UI independent bits go into the framework, and then you write a thin UI layer on top of it using your platform’s native UI APIs. The benefit of using C++ is that you can call it easily from most languages.
> Regardless, there’s still a complexity cost - unique native platform UI code is still unique native code, plus all the localisation, QA testing, etc, etc fun that will entail for an app the size of Slack.
Ok, sure, but most of this work has already been done for their iOS app. I’m making a shot in the dark here, but I’d think that given access to their iOS project I could whip up something passable within a couple of months, if not less.
The opposite is the case. New components are typically written in Go on the backend, Rust in the sync engine and the respective native toolchains on mobile platforms.
I’ve lived through decades of promises of “write once run everywhere” development technologies but they have always come with significant drawbacks vs native applications. Performance, memory footprint, native look and feel, ability to take advantage of os specifics.
A lot of Slack's audience is captive - employees, contributors to open source projects that chose Slack as their social outlet, etc.
It’s really not an option. That and you have to rebuild everything for Win/Linux builds. Just makes no sense.
Also you can’t ship your own updated WKWebView.
Secondly, you lose control of your application runtime environment version - need a new WKWebView version to ship a feature? Time to tell your customers to upgrade the app and their OS.
I’d maybe consider this to cheaply ship a feature inside a Mac app, but this really isn’t an option for like 99% of dev teams considering Electron.
For the record, WebKit originated from KDE[1].
It would be faster and take much less RAM, specially when multiple Apps are open and they could use the shared library.
Also, now that Chromium is going to be part of Windows, the same would also be a good idea, I think.
Aren't those fairly discrete areas with fairly different levels of work? Doesn't most of what's on NPM run in WebKit / Gecko these days, anyway, since people commonly deploy client-side?
Like…Chrome?
They can't run on native frameworks. If native frameworks are updated old apps would break. If native frameworks aren't updated newer apps would break.
What you're asking was already tried with Adobe AIR and failed. Instead we need lighter alternatives to Node.js and Chromium.
why?
would not existing static analysis/dependency pruning take care of it if someone had the time?
I don't see what would be 'novel' here from a theoretical point of view..
still a good project possibly though
Also, I imagine there are many cases where static analysis would not be enough for the JS app.
eCos is prior work on OS side that made me always think of designing systems for easy stripping.
The bridge itself is API stable. evaluateJavaScript:completionHandler: isn't going anywhere.
So the question is whether it's okay to use a native web view while still bundling your own V8 + Node. That seems like an improvement to me!
Historically, this hasn't been the case. Apple loves to deprecate stuff (although, thankfully, they are a bit slower to remove it). Before WKWebView there was a "stable" WebView.
(not production-ready but it might be soon good enough for really quick GUI prototyping using subset of web technologies - javascript + react + flexbox + styles)
HMR & react-devtools are already supported.
1. It's cross platform
Don't have to deal with the fact that Safari is missing these 12 APIs or has different edge cases
2. It's stable after shipping Users get a new version only when you ship. If you use the native widget then users get a new (often broken) version on every update by a 3rd party (Apple/MS/Google). Example: chrome just deprecated autoplay. If that bubbled into apps your app just broke. Electron could do the same but if you're testing like a good dev that break wouldn't make it to users. You as a dev would find it locally, deal with it, and only after ship to users.
so, no personally I don't want a shared widget. that sounds like going back to DLL hell or worse, just broken stuff.As a matter of fact, Chromium's/Chrome's engine Blink was forked off from WebKit back in 2013. Current WebKit is Apple's not-quite-as-well-updated version of the engine in old Chrome.
On OSes with sane package managers (e.g. Linux distributions) native apps can share all dependencies, so there is no need to recompile/redistribute each application using affected library.
Sadly, there is no such thing on MacOS (excluding brew/port) and Windows (or even iOS/Android), and even native Linux applications are moving towards bundling all dependencies in a single package.
In principle that is doable. Not sure about 100% compatibility as only WebKit (particular version) is 100% compatible with WebKit (particular version here). Edge is gone in that fight. Mozilla is standing but is not 100% compatible.
None of the four bullet points actually address real issues. The security problem isn't that Google is bad at security (they're among the best really). The problem is that Javascript code is generally written with the expectation that it will run in a web browser's highly locked down security context. Performance is really the same issue: web apps are authored wastefully. For use cases where you visit a web page for a few minutes then leave that's fine, but when you then let that code run for hours with no sandbox you will inevitably hit perf issues.
Write native apps. If you can't afford that, just make a web page.
Unless you have a core feature that _can't_ be implemented in Electron for some reason (I guess you're writing a game or something similar?), or have some other mechanism for locking your users in, writing a native app in 2018 is just putting your employees livelihood at stake.
It's not cool or fair at all, sure, but hey, us Marxists were telling you this will always happen for over 150 years now, and y'all still acting surprised.
So the parent seems correct. Winamp stayed native an lost. Spotify embraced the rapid dev that using a browser host brings to app dev and won.
The degree to which people didn't want to pay for music was kind of obvious when people needed mp3 players sufficient storage that filling them legally would have required as much money as a down payment on a house.
If an Electron "application" is decent, people typically like the features or the online service to which it's tied but its Electron base is something that people more or less tolerate, depending on the degree it irks them. It's just a huge tradeoff, that's all. It reminds me of some Java or Python desktop applications, it's a similar kind of tradeoff.
Hopefully it'll pass just like the previous fads.
Which is why electron is so popular. I'm sure the whole "it's way easier to whip something together that kinda works" is correct in the short term. You whip something up and rely mostly on the hype and viral marketing to drive your app.
Disclaimer: Not an Electron fanboy, I don't even develop Electron apps. I do enjoy using a Linux dev laptop, however, and am not a hardcore vim/emacs guy.
Spotify and Pandora are for letting you play a service's music. Winamp and 17 bazillion players are for letting you play a collection of digital music you control.
I didn't write this wasn't true; I wrote this didn't matter.
Edit: to expand on this a bit: sure, most of the throwaway Electron applications won't have much life in them. But they'll suck the oxygen out of the room and kill everything else first, then fail. So if there was any livelihood staked on those superior native apps you made — well, those people are looking for jobs now. Hope all of them have it as easy as a young software developer.
I agree, and this is the other reason I dislike Electron apps. Not just because of the utter disregard for user's computing resources, but also because of the damage those apps do to their surrounding ecosystems. It's hard to compete against people who can secure money faster than you by cutting corners and dumping waste on everyone else.
It's yet another example of "worse is better" causing a setback in the industry.
Plus it gets rid of visual clutter like the tab bar and treats your app like an actual application rather than a simple website for viewing.
People using desktop toolsets never even have to think about that "problem" because it just doesn't exist when you're using the right tools.
There are three types of tools for every job..
* The right kind
* The wrong kind
* The wrong kind but we'll make it work
Electron hits squarely in the third category by hiding the browser and webserver and pretending it's a real desktop application.
As soon as you move to the desktop, you're competing with the desktop toolsets.
People comparing Electron to the browser is missing the entire point of what Electron is for, which is pretending to be a native application.
If you want to write software for a platform, write software for that platform. Don’t write software for some other platform, try to make it fit, and then declare it good.
Java apps on the desktop became more prevalent and usable when Java was bundled in. The Electron is not so different from what worked for Java.
Square peg, round hole. Electron just gives you a hammer to make it fit anyway :)
Thank you.
No trickery, no hidden browser windows, just normal native executables.
Java also solves the cross-platform issue, though it's GUIs tend to not look native (As opposed to Lazarus above, which is native).
If you're impressed by a webserver being able to interact with the OS for things like accessing files or databases, your mind will be absolutely BLOWN when you learn real native development.
Java does solve part of this but some people would rather use JavaScript than Java. Even if they know how to use both believe it or not.
However, if one of your platforms is the web browser, nothing is going to work better than a web view if you want a cross platform solution. Slack for example works almost exactly the same in my web browser as it does in electron. If you want a solution that works on Linux, MacOS, and Windows AS WELL as the web browser then the web view approach is pretty obvious.
Lastly the JavaScript web development experience is great with hot module relacement and Chrome’s developer tools. Not to mention the JavaScript open source community is amazingly strong and there is a lot of innovation going on. To simply dismiss all of this because of personal reasons is fine by me but I don’t agree with your view.
Making absolute statements about why people make certain choices or believing them can definitely lead to false conclusions. People don't only use cross platform toolkits because they do not want to do work. Sometimes it is the best solution given the features and constraints. I like to think of it as being pragmatic.
I don't think anyone is "impressed" by it. It is just useful. The point of electron is being able to write javascript applications that run on multiple platforms.
Using Lazarus (and Pascal) means you need to learn another language to write native applications from the one you use to write web applications.
I'm not taking a position here, I am just pointing out the pros and cons. I am neither a javascript nor pascal programmer so I have no dog in this fight.
Cross-platform: yes, if you ignore the fact that there are only 2 browsers left, both being buggy and incomplete (as they've been for many years) and with no other implementation in sight, or even remotely feasibly for small to medium-sized companies or teams. Also they're so bloated and isolated from the native environment that you might just as well install a Linux virtual machine and call it a cross-platform UI.
No, thanks. I'll wait for a better cross-plattform UI solution.
In reverse, I would argue, Hundreds of "Native UIs", most of them obsolete or dead, have shown to be incapable to express cross-platform, flexible layout capabilities of 1990s HTML/CSS combo.
The most recent, yearly updated mobile OSes appear to be cooler, however we'll see in 10 years how they will end up.
But most haven't. If you want the capabilities of the HTML versions unable to even center vertically or requiring invisible images to format tables, there are plenty of UI to choose from. Qt, Wx are extremely capable nowadays.
Why not have libchrome or a libelectron that moves more slowly than chrome six week release cycle (maybe do 6 months) then have apps build to it and share the library.
If Electron apps would specify requirements instead of bundling the whole runtime, you will have to wait for the runtime to be downloaded the first time the app runs. You will still end up with multiple versions of the same runtime running on your system.
No. It depends on the package manager. E.g: https://www.archlinux.org/packages/community/x86_64/electron...
A shared electron package used by a few different apps: see the "required by" column...
As electron gets more popular, this will be the standard in Linux distributions (at least historically thats how dependencies handled there), Windows has different standard (self contained everything) so there it is the normal way - everybody already used to it for decades...
If you absolutely need to do web primitives inside your app, well then, html engines used to come in a few megabytes and no external deps. If your webcode needs the entire Chromium monstrosity bundled in order to run, someone has been doing something entirely wrong.
Native is awesome when you have the money.
FreePascal + Lazarus.
And I say that as someone who was writing Pascal professionally ~5 years ago.
But sure, if you want to do Pascal on the web there are things like Smart Pascal.
You also don't take a webapp and separate server and just drop the two into a folder and run it as an Electron app without changing code
It's not only about GUI designer and fast cross-platform compiler.
I have libs/packages for everything I need, dunno about your needs.
Not sure about the community size but it's plenty big and plenty helpful, lots of cool new stuff going on.
Plenty of debuggers available and you can pause things and inspect stuff.
Lazarus has seen loads of updates the last few years, it's worth taking the time to set it up to fit your needs and learn the shortcuts.
What do you think the cross-platform browsers you're packaging in Elecron are written in?!
The cross-platform browsers are written in a whole lot of platform-specific code.
It uses sciter (https://sciter.com) which is sort of micro-electron if you wish. Distribution of the app is 2mb rather than 200mb.
We can only defeat that by having another awkward "OS" in a VM which browser/electron is.
By choosing to go the Electron way, you're imposing a huge computational penalty on your users, just to make your life easier. Now multiply the overhead by the number of users, and that's how much electricity your decision just cost globally. This also manifests in frustration, like due to decreased battery life on laptops. And with enough popular software written this way, this pushes users to replace their perfectly good computers earlier than necessary.
(The lats point applies to web bloat even more; I'm really annoyed when a non-tech person asks me for help, because their computer "works slow, it must have viruses", only for me to discover that the computer is perfectly fine, it's just their favorite pages went through another rewrite and are now each 5x more bloated than they used to be.)
That to me is the biggest issue. There's "cross platform" and there's "cross platform".
QT gets you the major desktop platforms, but not a ton more.
The web gets you desktops, mobile phones, tablets, game consoles, TVs, car infotainment systems, even my fucking watch!
Obviously you aren't going to handle all of those without some custom code for a few platforms, but when the web is a target platform for a project at all, it's often worlds easier to just spend the time on improving the mostly single codebase rather than try to do multiple codebases. And I genuinely believe that outside of larger companies, having the whole company dedicated and focused on improving one codebase is going to end up with a better user experience than splitting those same resources up over several codebases.
If your app is desktop-oriented only, then Qt is such a fantastic system to work with! But it's increasingly rare that software targets desktop only.
Also quick edit: A number of car dash UIs do actually run on Qt and Qt does support mobile but Qt does its own compositing instead of the OS.
It's not like browsers all got together and agreed on a standard API, literally every browser does things differently from the others.
Agreed. Seems like there is no alternative, though; what you said in your first paragraph definitely is not a comparable alternative except if you're handing out money my company could use to do what you suggest.
FPC + Lazarus, native executables, cross platform.
But it’s not like FPC/Lazarus is the only portable GUI solution — Qt, Fox, Swing, SWT, Gtk etc. also exist, and don’t require a fringe language (and I say that as someone who did Turbo/Borland Pascal and Delphi development for more than a decade). What Lazarus offers is a Delphi-type form builder tool, but that seems a lot less interesting in this day and age of heavily customized UIs that aren’t static grids of square components — in particular, we increasingly rely on responsive layouts and smooth animations between them.
Moreover, I’ve yet to see a FPC app (or any app for that matter that isn’t Electron or web) that doesn’t look like an old fashioned Windows-style GUI app. Do you have any examples?
Yes, there are many GUI toolkits, the LCL creates native applications while some others do not, but it's certainly not the only one.
It's the one I prefer so I use it as an example over QT, Swing, JavaFX, etc.
Lazarus form builder let's you create forms very quickly and easy, and OS themed design.
If you want other types of GUI designs you can do that too, though personally I prefer standard OS design.
As far as static grids and square components, I think you're looking at old stuff..
You can make things as squiggly as you like, and of course you can always use images and colors to design your GUI and let your imagination run wild, and it'll look entirely non-native.
Responsive design isn't that challenging either, use anchors and smart design.
I don't have any examples of desktop applications I've made, that look like web-apps, no, but I might make some after you giving me this idea, and I'll be doing it with FPC/Lazarus.
People gravitate to Electron not just because you can’t build cross-platform apps in it, but because the underlying UI tech is just the web. You can even do as Slack did, which is to offer the exact same app in the browser. You can’t do that with FPC/Lazarus. The latter is geared towards fairly static layouts, not the kinds of snappy, fluid, single-window apps that Electron is used to build. It’s just a very different world.
Nobody is doubting that you can build decent Windows-style apps with FPC/Lazarus, just as they’re not doubting that you can do it with Qt.
As for snappy, fluid, single-window apps that is 100% doable and up to the gui developer.
It's not hard to use groups and switch between views, and make things dynamically resize or move around.
Random searches in "dice.com"(pick any job site you want) for "Pascal" yields 5 positions. "Python" yields 8,950. "C++" yields 6008. Even "8086 assembly" yields 1,378 jobs. "Java" yields 17,000+. There is a trend here if you care to see it.
You are obviously passionate about Pascal. That's awesome. Keep using it, and squeeze it for everything its' worth. Please don't be disheartened when technology moves on without you though, often in directions that feel "wrong" to us. Electron feels wrong to me, but it doesn't matter. Technology is going to move where technology is going to move, and sometimes you have to get on board with choices you dislike to avoid being left behind entirely.
PS: I cut my teeth on Pascal in the early 90's, and wish it had become more popular as well.
I'm using Node.js right now along with AWS for example, not my favorite combo but it's an appropriate solution being used as a webserver.
I've posted about FPC because it's one of the right tools for the job and the one I prefer over C/C++, Java, etc. for desktop applications.
I don't mind spreading the word about FPC, but really what I'm trying to push for is that there are appropriate tools for desktop development such as C, C++, Python, Nim, Go, Object Pascal, and a bunch more. I just happen to like and push for one of those.
Especially with the "benefits" for Electron like cross-platform deployments, are things that other languages such as Java or Object Pascal, also does and does pretty dang well.
For a benign example: using Google search
For a less benign example: your browser/device/network being tracked for ads when using Google search
Google Home does not serve ads, either.
My original comment's grand-parent did not claim if Electron was a browser or a search-engine, or if it showed ads, just that it is not necessarily independent of Google services just because it's built from Chromium.
Video explanation/demonstration: https://youtu.be/SWEts0rlezA
If I want to write a Mac-only app, I can do that in Objective-C/Cocoa, and be quite happy.
For Linux, native means fighting with primitive C and X11 or Gtk, etc., which I can do but I loathe it.
For Windows, I have no idea, C# maybe? I'd rather eat broken glass than install Windows and find[ed.] out.
So if I'm doing cross-platform, my current working choices are Electron, Java, FreePascal/Lazarus, or Scheme.
Electron's easy to build all three platforms on, performance is OK despite the bloated example of Slack.
Java would need to bundle the JRE everywhere, and I've been largely Java-clean for 10 years.
Lazarus is semi-broken on Mac currently, only 32-bit like stone age tools, Cocoa port is unfinished. Maybe they'll get their shit together someday, I like it when it works.
Scheme native binaries are hard and experimental, but getting better.
Using a WKWebView on Mac, then writing a completely different wrapper on Linux & Windows, is unacceptable for my uses.
So my actual shipping code is Electron.
Maybe devs instead of being lazy suckers could start to worry about this aspect.
It is neither a hammer nor a nail, it just works for some specific purposes.
However on macOS it is missing one important feature (to me at least) that used to work with WebView:
You can't capture the image of the web browser window any more.
You used to be able to go something like:
NSBitmapImageRep *bitmapdata = [view bitmapImageRepForCachingDisplayInRect: bounds];
[webView cacheDisplayInRect: bounds toBitmapImageRep: bitmapdata];
Or: [NSView cacheDisplayInRect:(NSRect)rect toBitmapImageRep:(NSBitmapImageRep *)bitmapImageRep]
But that's a synchronous API, and since WkWebView runs in another process, it requires a remote procedure call, so Apple simply returns a blank image from that call now.https://stackoverflow.com/questions/31969950/wkwebview-cache...
I think the iOS way of capturing a screen snapshot from WkWebView still works, though, but I can't remember off the top of my head...
However, Apple added a new method to Safari, but last time I checked it was only in the beta Safari and not supported in the version installed on the operating system. (When you make a WkWebView it uses some specific framework that's not necessarily the latest beta version of Safari you've installed.)
//iOS func takeSnapshot(with snapshotConfiguration: WKSnapshotConfiguration?, completionHandler: @escaping (UIImage?, Error?) -> Void)
//macOS func takeSnapshot(with snapshotConfiguration: WKSnapshotConfiguration?, completionHandler: @escaping (NSImage?, Error?) -> Void)
But the problem with this method is that it takes a totally different rendering path ("this is a software painted snapshot"), so some stuff may look different, and WebGL stuff doesn't appear, and it's a whole lot slower than cacheDisplayInRect used to be).
https://stackoverflow.com/questions/46842384/wkwebkit-takesn...
This bug describes the problem and the issues and the less-than-ideal solution:
https://bugs.webkit.org/show_bug.cgi?id=161450
Summary: [Cocoa] No reliable way to get a snapshot of WKWebView
- no screenshots
- no printing
- no user stylesheets
- no cmd-F find
- no delegate method for hover-over-link
- no access to container NSScrollView (on macOS)
- harder to customize context menu (AFAICT)
- ignores URLProtocols (10.13 added a new way to implement custom protocols for WKWebViews with a completely different interface than NSURLProtocol/WebView)
I'm dreading the day when Apple is going to require me to 'upgrade' my WebView to WKWebView.
All I want to do is supply a byte stream containing HTML, and have it displayed in an NSView, with standard features. This doesn't seem like an obscure case, or a difficult problem. I don't understand why none of Apple's web views ever had simply a load(stream:NSInputStream) method. This was hard with WebView, and WKWebView made it a lot harder.
But breaking up the browser into different processes and communicating via messages and sharing textures in GPU memory between processes (IOSurface, GL_TEXTURE_EXTERNAL_OES, etc) is the inextricable direction of progress, what all the browsers are doing now, and why for example Firefox had to make so many old single-process XP-COM xulrunner plug-ins obsolete.
IOSurface:
https://developer.apple.com/documentation/iosurface?language...
https://shapeof.com/archives/2017/12/moving_to_metal_episode...
GL_TEXTURE_EXTERNAL_OES:
https://developer.android.com/reference/android/graphics/Sur...
I'm sure for some use cases it's "progress" but I'm really having trouble seeing it right now. It would be an improvement if I were writing a web browser but I don't understand why it had to make the simple case worse.
And so the results look cheap.
But as far as I understand it, there's a bit of a fatal problem going forward on iOS, last time I looked at it a year or so ago (I'd be thrilled if they've come up with a way to address this problem):
The iOS NativeScript bridge uses the old deprecated UIWebView and JavaScriptCore's Objective C integration stuff that lets you directly call back and forth between Objective C and JavaScript.
However, that Objective C bridging stuff is not supported on WkWebView, since it runs in a separate process, and has a different way of sending messages to the web browser, but not calling native code directly or passing pointers to objects or buffers in memory.
Why would you want to do that? To get direct access to an array of binary floating point numbers, or the pixels of a canvas or WebGL texture, instead of converting to and from JSON, or serializing images as data urls with base 64 encoded png files, for example. (Yech!)
You can send messages back and forth to WkWebKit, but that's vastly less performant than the direct calling UIWebKit JavaScriptCore bridging stuff, which operates in the same process and memory space.
And the NativeScript iOS integration layer is totally dependent (built on top of) on the way the JavaScriptCore bridging stuff works, and would have to be completely rewritten from scratch (and be much less efficient and require a lot more plumbing on both sides), in order to support that kind of out-of-process messaging to WkWebKit.
The great thing about NativeScript is that gives you has such an efficient high bandwidth interface to native code from JavaScript. But it just necessarily uses an old crappy JavaScript engine with no JIT.
One of the best thing about using WkWebKit is that the Just In Time compiler is enabled, so it's blazingly faster than running JavaScriptCore in the same process (which has it disabled, since non-Apple apps aren't allowed to write to code memory).
Of course it depends on how much of your application is written in JavaScript and would benefit from the JIT, and how much it depends on calling and sending data back and forth between native code and JavaScript. But the NativeScript way of doing things makes many assumptions that would make it very slow with RPC messaging instead of direct calling.
PhoneGap/Cordova is fine using WkWebKit because it uses a JSON messaging interface in the first place, not the more efficient higher bandwidth Objective C bridging stuff. It's JavaScript/Objective C bridge is much simpler than NativeScript, and people don't use it the same way that NativeScript is designed to be used.
NativeScript, as cool and amazing as it is, is deeply tied to old technology on iOS, JavaScriptCore and UIWebKit.