Blazor, a framework for browser-based .NET apps using WebAssembly [video]
youtube.com
youtube.com
I hope MS really get behind this and see it through to a production ready version.
F# is also supported, and potentially any .NET language.
I mean, where is the graphql and Apollo like functionality in .net?
How do you make a pretty reactive frontend easier and faster with .net compared to vue/react/angular?
How big does the browserbased app get when it has to load .net libraries?
Maybe I’m just not seeing it, but I honestly think what laravel is doing with PHP on the backend and vue on the front end is the brilliant way of approaching web apps and I think what Microsoft is doing with web assembly is going to be a needlessly complicated mess that’s really, really unproductive in terms of time to market. And I think they are mainly doing it because Microsoft never made their own JS front end.
I’ve been following it for a while too, and I see a lot of the xamarin disaster in it.
https://github.com/octokit/octokit.graphql.net/
It only supports the GitHub GraphQL API right now, but everything is generated from the schema so it should be possible to make it support other APIs.
Then the assemblies will be cached and I understand they are working on getting them small. Silverlight wasn't that bad in term of load time.
If the website really deserves a SPA (creating a blog in a SPA is ridiculous), people expects the website to take a little time to load even with javascript, and it does. My online broker trading platform does, webmails do, etc.
For reactivity, I am not sure I get your point. With async/await it is going to be trivial, and .net on wasm will likely be faster than javascript.
I honestly don't see any benefit over plain Web APIs.
You don’t have to take my word for it though, try it yourself: https://graphql.org/swapi-graphql/
I have used them and I dont agree with this at all.
I suppose next you're going to say I haven't used them enough?
I work in the public sector, we integrate with more than 600 different IT systems. I’d say around 10% of them have the documentation they ought to.
With graphql, the API is the documentation.
On our own end, it’s improvee production and quality because it’s faster to build an API with it, that lives up to our standards for APIs. It’s also harder to fuck it up without realizing because it’s typed and forces schemes.
The last advantage is that it allows for an easy way to get the data you need from a general query, that might not be important in a lot of places, but when you build apps for workers who use them in a rural setting, it’s kind of nice to minimize the data they need to transmit to the bare essentials. You could do that with a rest api, but it would take a lot more time to implement.
The superiority of GraphQL is not as self-evident as you believe it is.
There are a ton of performance wins they can do later. Those have little value right now.
When I worked with .net guys (which happened quite often) 9 out of 10 had been like wow, I don't have to touch frontend, because MS will solve that for me "somehow", plus the frontend is messy and crap and javascript is a terrible language and C# rocks (but F# even rocks more) and I'm not going to learn all this sillyness (because I want to reuse my skills).
At least with new-angular they feel a bit better and they can praise typescript, because typescript is "just like C#". Let's just hope noone pulls an angular-one-to-two style rewrite/clusterfuck...
I will take any server side rendering framework, with some sprinkle of JavaScript, over any SPA framework.
A node_modules directory with several thousand packages just for a basic CRUD app, really?
However, I agree that server-side rendering is much simpler in all of the cases where desktop app-like experience isn't required.
Coding is fun, but providing a productive experience also requires doing lots of stuff that FOSS coders don't invest any resources into it.
WebForms/UpdatePanel was a half-baked solution to pick-up and drop-in .NET developers from WinForms to the web, while Blazor seems to do the same thing for server-side and client-side developers.
Microsoft eventually created MVC, which embraced the nature of the web (HTTP verbs, no viewstate, etc). I would urge developers to just dump into the deep end and use tech native to the browser. I know wasm is now native, but Blazor is running a VM in it that wasn't designed for it.
C# developers might find some comfort in TypeScript. Maybe Angular?
Now we must distinguish blazor and mono on wasm. Mono on wasm allows the .net runtime to run in webassembly. Blazor uses the mono runtime and creates a UI framework. I think the game changer is the .net runtime in wasm. Once it is production ready, I am sure we will see competing UI frameworks, some possibly even based on xaml.
Wasm (Web Assembly) is still early in development. It's looking like it will create a high performance & excellent VM to compile code to for the browser. This is great for any language. A lot of proposed features could give it all the same features you have in JavaScript. But those features are only proposed. Lin Clark gives a great intro on this podcast - https://pca.st/5rjS
Blazor is an experiment at utilizing Wasm to do JavaScript like things with C# in the browser. I've never heard anyone say use it for production yet. The YouTube video here is 1 of the best talks you'll see on it if you watch it. I was lucky enough to attend in person.
You can use Blazor without a server to create static sites & host them on servers like Netlify.
Performance & file size isn't something they've put much effort into at all yet on Blazor. Way to early & easier problems.
There are other experiments going on with .NET, Mono & Wasm . See Uno & Ooui.
Steve Sanderson did an experiment a few years ago to see if this was even possible based on some interesting research he found. It grew from that. They have put a really awesome team behind it. It's gained a great following & has a very active Gitter channel that the MS team (notably PM Dan Roth) talks in. They're also quick to respond on GitHub.
I am very excited about the possibilities this brings. Current frontend/backend solutions all seem to involve duplicating contracts in JavaScript. WebAssembly frameworks like Blazor will let us get back to programming in one language but keep the SPA-style experience for the UI.
GWT users cared less about how it was compiling, and at the end of the day, they were building webapps using Java and Eclipse IDE along with the rest of the ecosystem. Which is exactly the selling points being presented here.
For me this is history repeating itself.
Which is why they're shipping server side Blazor [0], which is all the stupid parts of Blazor with none of the benefits.
Don't get me wrong, the idea of running .Net in WASM is very appealing to me... but server side Blazor is a daft idea, and it's a mistake.
Here's the model:
- Your component view state is rendered on the server.
- A delta is sent to the front-end.
- The frontend updates the DOM in the browser.
- Any DOM event is sent to the server.
- repeat.
Seems ok?
However, the problems here to understand are:
1) Every UI interaction, from mouse focus, to mouse drag, to click to button down, is sent down the wire to the server to be processed. For high latency situations, this will feel terrible.
2) Every client shares the same server cluster. As such, it scales badly; your application may perform well with 10 users, but for 100 users, you have 10x as much server work happening. Not business logic... UI logic. Will it scale? No one knows, but the money is on 'no'. The server scale-out demands will scale with people viewing the website; effectively this means the UI will lag out under load when the server is busy, the exact opposite of modern SPA applications and apps that remain superficially responsive under server load, and compounding issues generated from (1).
3) As many of the examples show, server side Blazor shows how you can execute arbitrary code on the server as part of your components (eg. fetch DB records). However, no vague consideration has been given to the authentication model for this. In fact, the stated high level goal is that razor components will 'with one click' work seamlessly on both WASM-mono and razor-components; ie. They are are naive of user roles and permission groups on the server, and expect to interact with an arbitrary backend 'service' with its own permission roles. (But that isnt what the examples show).
These are not trivial problems, they are, unfortunately, insurmountable architectural issues with server-side Blazor.
...and the work around is a compromise. ie. You use javascript.
Which... kind of makes it rather pointless.
This is being shipped early for business reasons, not technical reasons.
They should just wait for the WASM target to be ready; this will be a disaster, in my opinion.
[0] - https://blogs.msdn.microsoft.com/webdev/2018/10/02/blazor-0-...
As someone who is trying to wrap his head around all this, did they go with server side Blazor because browsers do not support all required WASM features yet? What is even the point of server side rendering?
"Server-side Blazor" itself will be renamed[0] to Razor Components so as to disambiguate it with WASM-in-the-browser, which will still be called Blazor.
Razor Components seems to be a blend of different kinds of web programming models, as described by the parent poster:
- Traditional: POST + Redirect + GET
- Single Page App: Thick client in JS
- Razor Components: Traditional, but instead of POST+Redirect, it uses Web Sockets to asynchronously update state.
Razor Components are being shipped because it's building off well-known, mature technologies. OTOH, Blazor (WASM in browser) is still baking. For example, there is no tree-shaking to minimize the minimize the size of components needed to run your Blazor app. (IIRC, the average size of a basic nav app is ~2MB.)
[0]: https://blogs.msdn.microsoft.com/webdev/2018/10/02/blazor-0-...
Server side components directly call server code, unlike client components, which use an HttpService.
Compare for example https://dzone.com/articles/understanding-server-side-blazor, where:
> The Blazor app is hosted by an ASP.NET Core app, which also sets up the SignalR endpoint. Since the Blazor app is running on the server, the event handling logic can directly access the server resources and services.
Vs. the actual official samples, where an HttpService is used to access data from a controller: https://github.com/aspnet/samples/blob/master/samples/aspnet...
ie. Blazor server side components are indeed disconnected from users/permissions, by design... it just happens that they can also call arbitrary server side code, which is obviously a) not portable, and b) hugely unsafe.
There's an issue in the issue tracker for this, but basically, the tldr; is, no, you shouldn't call arbitrary server side code... but, you can, and so people are doing it.
... shakes head ...
(edit: Oh look, another great one, https://social.technet.microsoft.com/wiki/contents/articles/...
> We will invoke the methods of EmployeeDataAccessLayer class from our service. The service will be injected into our components and the components will call the service methods to access the database.
...)
There is added resource utilization from tracking session state on the server, but if done properly it could be as little as 1MB or so per active client connection.
With the rise of serverless and edge computing (think cloudflare workers), I wouldn't be surprised if patterns emerge to running this at the edge.
I agree I wouldn't put any high traffic apps on Server Side Blazor from the get-go. But for Enterprise apps with high complexity and a small user base, I think it would greatly streamline development.
Just curious, where did you pull this number out of? I've never seen a SignalR connection use that little memory for anything.
1MB is my estimate for the Virtual DOM and associated independent state for each client. I was not factoring in the SignalR per-connection memory footprint, I imagine that would already be pretty optimized?
That would make all sort of integrations between legacy systems with existing C# support libraries and newer lighter node.js projects work without jumping through crazy marshaling hoops.
Seems like a very interesting direction, embedding managed languages into JS.
WebForms/UpdatePanel was a half-baked solution to pick-up and drop-in .NET developers from WinForms to the web, while Blazor seems to do the same thing for server-side and client-side developers.
Every time a new version comes out theres a 500 page tome of all the new features added. Did we really need all those features? I would love it if I saw a new version of a language come out and it removes language features, wouldn't that be a change!
It still has all the annoyances of java (the first thing you see in any C# file is a laundry list of imports), I am not convinced the profiling tooling is better. I will preface this with I am still bitter about the initial .NET core rollout which was a crapshoot and had no parity whatsoever with .NET Framework.
> Did we really need all those features?
If you don't need them, don't use them. I've found the new features to be great. nameof, string interpolation, property initializers, exception filters, static imports, null propagator. And if you haven't used the language in awhile going back to 5.0 the async await features are fantastic. 7.1 introduced async Main which we've started using in console apps. I use all of these features every day.
> I would love it if I saw a new version of a language come out and it removes language features
Why, exactly?
2. I will propose that programming languages are like anything else created by humans - some parts great, some parts not that great. Furthermore some parts of a language are used more than other parts, it should be hoped that the parts least used in any particular language are parts of that language that are not that great. Given these things it might be reasonable that some time you saw a new version of a language in which they said Feature X really sort of didn't make sense and anyway hardly anyone ever used it so we are removing Feature X. Adjust code accordingly. (probably there should be deprecation stage of a year or so with warnings)
There are multiple levels of understanding, regionalisms and specialized technical terms that few get to use.
I like C# adding new features, and understand some try-and-see-what-sticks is unavoidable. But I don't understand them not deprecating the old versions. And still wonder if improving an earlier version would have been possible/better.
That's not really true, the list of features in each version is pretty tight and focused:
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csh...
But .NET is a framework that is written in C# and extensively used by C# and not a language.
But what is true is that there starts to be a lot of overlap and inconsistencies between multiple generations of the framework. You have object methods vs generics. You have async/callback methods vs async/await. You have ref/out returning methods vs valuetuple returning functions. etc. The language is starting to show its age even though the .net team has been adding to the syntax sparingly.
How come it was decent once but not anymore? As others said, you are probably exaggerating by saying new version comes with 500 page tome.
However it is a joy for me to program in C#. Super-consistent language. And my favorite feature "LINQ" really gets rid of loops and loops and maybe more nested loops. Interfaces, generics - all great features, decently implemented under the hood.
C#'s feature changes over the last few years have been marginal. They nibble at the edges while stuff like record classes--an actually and materially valuable thing that significantly improves the writing of immutable and functional code--have been punted for multiple versions now.
C# is Java now, in a way it wasn't when it was younger. It's afraid of change and in being afraid of change has slowed to a crawl. Such is probably the way of most programming languages and ecosystems. But it is a little sad for me to see.
Much better in my opinion to just stick with the fluent method chaining style of using LINQ methods.
It can be easily translated to other query languages (like SQL) or functional paradigms, and is much more advanced than some map/iterate operators on generic types (which languages like Go dont even have).
The LINQ query syntax (from x in list select x.a) is syntactic just sugar to easily write complex expressions that the compiler turns into the same standard list.Select(x => x.a) method calls.
-anonymous types -implicitly typed variables -object initializers -lambda expressions
It's interesting that all of these features are very widely used (except maybe for anonymous types) outside of LINQ, but LINQ was the driving force for adding them to the language.
Anonymous types were needed to do the equivalent of "select field1, field2" that are familiar to SQL programmers, or to have intermediate values in a chain of Select/Where/Select operators. Implicitly typed variables (var) were needed to refer to the above types. Object initializers are needed so you could create the anonymous types, and non-anynymous ones too without breaking the LINQ chain. Lambda expressions of course were needed. All of the above are used outside of LINQ.
This was done in 2007. Java got streams and lambda expressions in 2014. JavaScript got it in 2015.
The SQL like syntax - well it exists. I think many people don't realize it's there. Everyone uses the method/lambda syntax.
As is probably obvious from my reference to them, I believe that record types would be a contender for "most important new feature"--even moreso than async/await--after spending a lot of time with Kotlin and data classes, it is nearly impossible to go back. C# provides you with the choice of manually-updated boilerplate or mutable objects through your whole stack. That's what has generally kept me away from C# since exposure to first Scala, later Kotlin, and most recently TypeScript. And, while I now work at a C#-first company (not on the C# backend), I don't see a real reason to change that for me personally until they make writing correct code easier.
In many ways, TypeScript seems to me to be a wiser future than what C# is presenting, but that's a whole other kettle of fish.
It's not lambdas but expression trees that are the key feature that made LINQ possible. That is pretty unique feature among programming languages. So you might want to reevaluate your opinion about "table stakes features".
I view C#'s expression tree stuff as a neat experiment. It's cool. But it doesn't and shouldn't change one's programming life.
> But it doesn't and shouldn't change one's programming life.
What's an example of something that would?
Hermes Conrad is not aspirational, my guy.
And the power of ExpressionTrees that allows you to interpret code your own way. For example, substituting SharePoint CSOM library
.IsPropertyAvailable(string)
with IsPropertyAvailable<T>(this T clientObject, Expression<Func<T, object>> propertySelector) [0]
is neat. Instead of magic strings you now have compile-time checking. Now you write .IsPropertyAvailable(s => s.ServerRelativeUrl)
instead of .IsPropertyAvailable("ServerRelativeUrl")
As for SQL, it may sometimes be a blocker, yes. But EF Core, for example, provides a FromSql method to use for complex queries.[0]: https://github.com/SharePoint/PnP-Sites-Core/blob/206ee97d4b...
using System;
using System.Linq.Expressions;
class Program
{
static void Main(string[] args)
{
Expression<Func<int, int, int>> expr = (a, b) => a + b;
Console.WriteLine(expr);
Func<int, int, int> fun = expr.Compile();
Console.WriteLine(fun(1, 2));
}
}
When run, this outputs: (a, b) => (a + b)
3
When a Expression<T> variable is assigned to or a method taking an Expression<T> parameter, the C# code is not translated into MSIL (normal C# is compiled to MSIL). Rather it is translated into an AST. In my example I just compiled it to MSIL, however LINQ-to-SQL and Entity Framework translate the AST to SQL. This macro-like capability is the true power of LINQ. The rest is syntactic sugar (though very delicious sugar).If I were to try to critique LINQ, it would the normal ORM complaints. Sometimes you have to care about what is going on underneath in the C#-to-SQL translation. Your code may compile, but at runtime the generated SQL might have terrible performance.
Many changes have also made C# much more productive and expressive by letting you do more with less. Every language has imports but the strong typing and amazing tooling makes it a non-issue. Use VS or Rider and you can type out entire programs in a few minutes without ever worrying about imports.
C# might have minor drawbacks (ok single inheritance is a pain) but it works better than most languages in its class. The only thing that makes me feel inadequate is seeing some really advanced level Haskell code :o
The fact that Microsoft keeps doing things like core 1, the 2, xamarin and now this web assembly stuff made the business case for changing better though. Because staying up to date on c# has also become expensive.
Still, stuff like AD and ADFS, msSQL and windows servers are the backbone in a lot of enterprise, and C# integrates really easily in that environment. I still think node.js, powershell and SSIS does it better, but I can certainly see why c# is still a thing.
* Async/Await implementation is pretty much superior
* Real threading; great for task pools as well
* Task local storage; something the nodejs community is very interested in but thus far only lives in hacks on obscure run-time features
* Speed?
* Integers?; come on man
* Linq/Entity Framework(though these should mostly be possible to implement in TypeScript now)
If I had my druthers I'd be using F# though, TBH.
Threading and tasks add unnecessary complexity.
Speed? What speed, this web assembly example is more than 5mb of .net libraries. We make apps for people on less than 3g.
Entity is one of the worst, least productive and most error prone frameworks we’ve ever had in our stack. Especially code first.
Linq almost made us stick with C# forever.
I think that hits the nail on the head; I never got why anyone used that. We never did and we have been using c# for a long time (all over to Core now) and all the horror stories never applied to our work, I think, because we never touched entity.
There were certainly a couple gotcha's and quirks to get used to, particularly around initial modeling, but the unit of work pattern made possible with task local storage was spot on.
C# on the server running on .NET Core is one of the fastest web stacks, and the async and threading help greatly with that. You can keep everything synchronous if you want, but it's good to have the flexibility when needed.
How is EF unproductive? What options are better?
Whether we gain a little efficiency or not from core is relatively irrelevant if it takes longer to produce the solutions.
We’re not Netflix, our max load is 60.000 concurrent users, and that’s relatively rare.
What isn’t rare, is someone loading an app in a remote area, where the mobile coverage is terrible, and if it had to load .net libraries in that setting, they’d frankly never be able to do their jobs.
So the speed of .net core is irrelevant to us, and to most people really, I mean, Netflix runs on node.
If you don’t know why EF is terrible, I’d wager you’d never used it. We use LinqToSql in our C# apps. Why? Because it’s productive, and again, it may be slower than entity, but it’s slower in a way that really doesn’t matter to us.
I mean, the video highlights it so perfectly when the guy goes “look how fast it compiles”, as if that’s ever useful when your application takes much longer to load for the user.
I don't get the comparison on the client-side with webassembly though. This is an entire UI framework, and hasn't been fully designed and optimized yet, as stated. It's no different than using React and neither would be good options if optimizing for low-bandwidth remote areas.
I've used EF since it was first released, and we haven't encountered any major issues. We migrated from nhibernate a long time ago and fallback to Dapper occasionally for complex SQL and performance. What do use instead? Or is the argument to not use ORMs at all?
We’ve not really seen any real trouble moving to dynamic types, possibly because we utilize stuff like SOLID. When you’re not really using object oriented to its fullest, because it’s fullest adds complexity and complexity costs a lot of money and you’re already pretty fascist in your approach to how responsibility and changes are handled in your systems, dynamic types aren’t really a problem.
If I was building a huge system with a lot of complexity, I wouldn’t pick JavaScript, but I probably wouldn’t chose C# instead of JAVA either. And that’s not the way I would’ve viewed the world 5 years ago.
Anyway, I think people should use what works, I just think C# has lost its usefulness compared to other technologies and I really think web assembly is s terrible move for Microsoft.
But I’d love to be proven wrong.
JavaScript isn’t light either, if you look at the amount of stuff a major website loads.
C# the language is also not the same as the .NET runtime and framework, but Microsoft is the best organization in the world when it comes to backwards compatibility and the C# code you wrote a decade ago will still work flawlessly today.
I don't understand how you're switching to Node.js and shell scripts(?!) to take over all that functionality.
SSIS is better at moving data.
Powershell has come really far, it’s certainly not C#, but where it really excels is when it’s integrated into our Azure orchestra giving us faster error reporting and making us capable of addressing those errors quicker. It’s also a language that’s shared between developing and operations. So while C# is better technically, powershell is better organizational and that means it’s better.
Simply put C# has become an unnecessary burden, in our setup. I’m not sure I’d use node for huge projects, but our backends are mostly simple frameworks for manipulating relatively small amounts of data.
We’re not leaving .Net or Microsoft, our node server runs behind an IIS with IIS node. SSIS, powershell and Azure are obviously Microsoft. Our entire security model is based around AD and ADFS.
"I am still bitter about the initial .NET core rollout which was a crapshoot and had no parity whatsoever with .NET Framework."
Those two statements seem to be in direct contradiction with each other. Would you like iron-clad parity, or would you like to break compatibility in an effort to shed bloat?
But all that aside, C# is still decent, the only thing making it less shiny now is that we realized that OO is a promise that didn't deliver. I don't want to program another line without proper algebraic types for example - yet here we are.
Hell, it’s still not easy for people to deploy a .net core web api and run it in an IIS installed with basic settings. You can laugh at it, but that’s 80% of the damn workforce who doesn’t know how to do that.
I mean, the JS environment changes, but I haven’t had to pay for anyone getting reschooled since we swapped to JS.
That is exactly .NET Core
Seriously, I'm saddened to see all this overwhelming hype and "excitement" --- I am a developer myself, and just don't get it: I have used .NET apps before, and I could immediately tell it was such just from the speed (or lack thereof) and memory consumption --- the difference is obvious. It's the same with Java, which is not at all surprising. The absurd amount of object-oriented obfuscation I encountered in the few times I had to debug someone else's code in C# probably contributes to that too.
Taking over a second just to load an extremely simple app from localhost in the demo says all I need to know about this --- "no thanks". Please consider your users' experience...
1 second to load the whole app compared to the shitshow that is most SPA apps these days is a dream.
Scrolling in your browser is bad enough when JS/dom has to many allocations.
WebAssembly support for multithreading is in progress https://github.com/WebAssembly/design/issues/1073
Look, you want to poo-poo on WebAssembly, that's fine, but the folks who build these browsers don't seem to be concerned enough about having GC'd langs running on their platform. Who has more at stake - you or them?
Here is some of the JS for Blazor: https://github.com/aspnet/Blazor/tree/master/src/Microsoft.A...
Nobody is poo-poo'ing anything. It is what it is. .NET just isn't likely to be a good fit for the browser for high-scale applications where performance is critical.
I expect Rust to lead the way here.
I guess I don't understand what kind of 'high-scale applications where performance is critical' wouldn't be suitable for .NET but instead better suited to a systems programming language like Rust. If the bottleneck becomes the single-threaded JS interop, then what difference does it make which WASM language/runtime you choose as long as it's at least as fast as JS?
Rust will be delivered with no runtime (minimal deployed size), Blazor will need the entire mono runtime and BCL.
Will it ever be as small as a systems language like Rust or C? No - never. But the productivity gains that C# & the .NET framework provide are a worthwhile tradeoff for 99% applications.
The .NET team is actively working to optimize the payload to a manageable size.
You haven't specified what evidence you're basing this statement on:
> ".NET just isn't likely to be a good fit for the browser for high-scale applications where performance is critical."
Because Javascript is a good fit? Facebook sends down 500k+ of JS and how many of their billion+ customers complain about it?
But, I'd ask you to recheck your impressions every couple of years, especially if a technology seems to be gaining popularity as opposed to dying. Stubborn and irrational corporate loyalty and manufactured hype are not the only reasons a technology stays alive, quality does play a role sometimes.
.NET these days, especially with core, has a focus on power, performance, portability, and a sleek user experience. C# is a widely loved language that has a plethora of good stable tooling around it, and an intelligently evolving featureset that enables terse, expressive, functional-if-you-want-it coding. I think, like Kotlin, it's very well suited to writing "functional core, imperative shell" apps. You can also use it to write bloated J2EE-style lasagna-code, but no one's forcing you to do that.
As for Blazor itself, it's similar to React/Vue/etc., but in C#. Writing complex frontend apps is hard even with TS and the big frameworks, and I can't think of why a new entrant with a statically typed language (with types at runtime!) that's still web-native would be a bad thing. As for startup time, hopefully they'll improve that, but you wouldn't use Blazor for a simple app anyway.
My most recent experience with a .NET application was within a day, and my impression has not changed since the beginning. (Although hardware has gotten faster...) Essentially every time I've had to use an annoyingly sluggish app that looks like a native one, I later discovered it was written in .NET . Despite all the claims of performance I have not once encountered an app that reflected those. It's never been "wow, .NET is so fast now?" but always "why is this so slow? ...oh, it's .NET."
You can also use it to write bloated J2EE-style lasagna-code, but no one's forcing you to do that.
That's the same non-argument the Java folks give. In theory it's possible to do better, but the language and culture naturally tends toward overengineering monstrosities because it is so much easier to do so when the language makes complexity easy to create.
...which brings me to the point I'm trying to make: your users don't care what fancy language or framework or whatever else you used. They care about the speed and (implicitly, since it affects speed) resource usage of your application, and that's what they'll notice.