Much noise has been made about Evernote’s new Windows client. For version 4, they dropped WPF/.NET and released a C++ native application.
They were pretty damning with their reasoning:
Evernote 4 is a major departure from Evernote 3.5 in every way. While 3.5 added tons of great new features, there were some problems we simply couldn’t fix: the blurry fonts, slow startup times, large memory footprint, and poor support for certain graphics cards were all issues that the technology behind 3.5 (Windows .net and WPF) was incapable of resolving. As a result, we ended up chasing down platform bugs rather than adding the great features our users wanted.
So we decided to start over from scratch, with fast, native C++ that we knew we could rely on. As you’ll see, the results are amazing. This new version will set a foundation for rapid improvement.
Evernote 4 is designed to give you a great experience on any computer that you use, whether you’re on a netbook, a five year old Windows XP machine or a super fast top-of-the-line Windows 7 computer.
On our test hardware, Evernote 4 starts five times faster, and uses half the memory of Evernote 3.5.
You cannot make statements like “issues that the technology behind 3.5 … was incapable of resolving” without providing more information on the problems they faced and the solutions they tried. For all we know, their Windows client development team could have tripled in size to get the native version out the door.
Evernote 3.5 was a textbook example of reasons to immediately upgrade to .NET 4.0 if you are building WPF applications. Visual Studio’s UI layer is now in WPF, presumably after fixing all these issues.
“The text is blurry”
This is fixed in WPF 4.0, which can render text almost exactly as Windows does if developers request it. The standard behaviour is a DPI-independent accurate representation of the font on the screen (the same way OSX renders text and also the reason why text is “blurry” on Macs).
This is a one-line fix in .NET 4.0, just apply TextOptions.TextFormattingMode=”Display” to your root XAML element. Asian text will also now use bitmap fonts so customers on Japanese XP machines will now get consistent text rendering between your app and their vintage OS (of course Vista/Win7 should be using Meiryo).
“The download size is too large”
The runtime for .NET 3.5 is 65MB or so. .NET 4.0 has reduced this to a 28MB download. Ironically, the Evernote 4.0 installer is 40MB – most likely larger than bundling the .NET 4.0 runtime in the installer of 3.5. Users with .NET 4.0 already installed would have got an even smaller download as the installer would not download the runtime.
Evernote 4.0 appears to include Chromium (the Chrome web browser base), Foxit Reader’s PDF libraries, SQLLite and libxml which could be replaced with the built in Web Browser control, XPS rendering, SQLCE and built in XML libraries of .NET 4.0.
“It uses too much memory”
If your application has hundreds of threads and handles complex local operations, it will require memory. Evernote’s statement about version 4.0 using “half” the memory of the managed 3.5 version is pretty damning considering that the application is not very complicated.
While you may never be able to match the memory consumption of a “native” application in .NET, there are some things you need to know to improve your memory use:
- Use .NET 4.0 as it has background garbage collection
- Keep your visual tree small (no endless nested Grids in XAML)
- Virtualize your ItemControls! This might be the most important issue. You cannot bind a XAML WrapPanel to 1000 images without Virtualization and expect scrolling to be smooth or your memory consumption to be low.
- Use the ThreadPool and Background Workers instead of manually creating threads. ThreadPool-based tasks intelligently carry out the number of simultaneous tasks based on the number of processor cores you have. Allowing your code to create and infinite number of threads is a recipe for disaster as each thread needs its own stack space of at least 1MB. Ideally use .NET 4.0s new parallel programming and async functions.
- Read the correct memory numbers in Task Manager (Private Working Set).
“The application is slow to start up”
Managed applications do not have to start slowly. A new application from a VS template will start up instantly – it is when you start adding references to other libraries, interop hooks and modules (for composite apps) that startup time starts dropping. Perhaps the most important thing to do is use NGEN to generate a native version of your application at install time, instead of waiting for the JIT compilation when the user launches the application. The application will slow down when loading modules for the first time if they have not been pre-compiled. There is some great information on improving start up times on MSDN, as usual.
In general, try to show some part of your application immediately. A splash screen might be okay for application start up times of less than a few seconds, but there is no reason why the main window can not be displayed and relevent data start loading in the background. This is mainly a perception issue. If you only show your main window after loading all data that your application could possibly need ever, of course start up will appear to be slow.
Did Evernote even try .NET 4.0?
The .NET development community is waiting for some sort of postmortem from the Evernote team. Most of the above problems would have been solved by upgrading to .NET 4.0 and running some decent profilers on the executable.
Rewriting your application natively will no doubt use less memory and start up faster, but it will also look worse, take longer, be more expensive to develop and your UI will break when high DPI screens start to be used. Portability is not a reason: if you want an application to work on Windows/Mac/Linux/iOS/Android, you write a web application.
If you want an example of an amazing WPF 4.0 application designed for the Windows platform, check out MetroTwit.