Building a Universal XAML Twitter stream: TextBlock vs RichTextBlock vs WebView


Header

This morning I was using my Windows Phone’s Twitter application and I was curious why the twitter stream was plain text, why did the developer choose to go with plain text for tweets … (notice in the picture below the @’s, #’s, url’s are all just plain text)

Windows Phone Tweet Stream

Windows Phone Tweet Stream

[notice : You’ll notice the coloured smileys, this is a feature of the OS where “coloured fonts” is supported :) ..  You’ll see below that even Windows OS supports coloured fonts too!]

So I decided to prototype 3 different approaches to rendering a “tweet”

  1. Xaml Textblock
  2. Xaml RichTextBlock
  3. Xaml WebView that renders tweets in HTML (within a xaml app)

Twitter Library to retrieve tweets

To make things easy I used the LinqToTwitter  library.

There is a brilliant library already written that works for Universal XAML apps, its called LinqToTwitter.

It’s simple to use it ..

1. Nuget in the library into your universal apps

linqtotwitter-small2

2. Create Authentication

linqtotwitter-auth

3. Retrieve Tweets

linqtotwitter-retrieve1

4. Massage tweets into a form the UI can use

linqtotwitter-collection

linqtotwitter-model2

linqtotwitter-retrieve2

Approach 1 : using a Textblock

The first approach I used was a Listbox that renders tweets in a Textblock. This Listbox is bound to the Tweet’s ObservableCollection defined above

approach-2-small

When the app renders the listbox it looks like this ..

using xaml textblocks to render tweets

using XAML Textblock’s to render tweets

What you’ll notice is the Textblock renders the raw tweets and all the @’s , #’s or url’s are NOT clickable/highlighted. This pretty much resembles Windows Phones Twitter app.

Performance of this approach, using a twitter stream of 100 tweets …

TextBlock-Memory-sml

On several runs using a Textblock to render tweets, it averaged around 38-41MB footprint

Approach 2: using a RichTextBlock

The second approach I  wanted to highlight the @’s, #’s and url’s . So I turned the Textblock into a RichTextBlock and implemented a binding helper to turn the raw text into Paragraph and Runs.

approach-3-sml

The binding logic for RichTextBlock looks like this, what’s important to point out is the “ParseForRichTextParagraph” method where the translation from raw twitter text to ‘paragraph’ occurs.

approach-3-binder-sml

And here is what the finished render looks like

using RichTextBlocks to render tweets

using XAML RichTextblock’s to render tweets

Performance of this approach, using a twitter stream of 100 tweets …

RicheTextBox-Memory-sml

On several runs using a RichTextBlock to render tweets, it averaged around 44-46MB footprint

Approach 3: using a WebView

The 3rd approach I wanted to take a completely different approach of rendering the completely dynamic content of tweets with HTML .

I have always believed that the perfect UI framework would let you mix xaml/html/DirectX together. The closest we can get to that today is hosting a webview in a xaml app🙂

So like my examples above, ill replace the Listbox with a WebView.

approach-4-sml

And I have a BindingHelper that turns the Tweets collection into HTML. Also I hooked to the Tag property so that I could bind to something.

approach-4-binding-sml

Here is what a WebView rendering a tweet stream in xaml looks like.

using a WebView to render the tweet stream

using a XAML WebView to render the tweet stream

[note: it appears the WebView does not support coloured fonts😦 ]

Performance of this approach, using a twitter stream of 100 tweets …

Webview-Memory-sml

On several runs using a WebView to render tweets, it averaged around 46-49MB footprint

Demo Code

You can download the sample code here

UniversalXaml

note: I wrote this sample on Windows 10 – 9926, VS 2015 CTP 5

Conclusion

  1. Listbox – Textblock :  38-41MB
  2. Listbox  – RichTextBlock :  44-46MB
  3. WebView – HTML/CSS/JS :  46-49MB

I can see why the Windows Phone Twitter app would want to go with a “Raw Tweet” stream (approach 1). Every megabyte of memory footprint saved is a big deal on mobile devices.

However I personally would of taken the approach 3 (using a WebView within the xaml app) as I truly believe something as dynamic in content as a twitter stream makes more sense rendered as HTML ..🙂

And the argument for turning the entire app into a WinJS app, sorry BUT I truly believe XAML apps are the way to go.  If you need HTML content, we have the WebView control for that🙂

9 responses to “Building a Universal XAML Twitter stream: TextBlock vs RichTextBlock vs WebView

  1. Nice post. As for the last paragraph, well…
    Using a WebView in a XAML app is going to have *very* different performance and memory usage characteristics versus using a native HTML/JS app (or as you called it a “WinJS” app, regardless of whether you actually use that library).

    A few reasons for that are:
    1) You’re loading two UI frameworks, and the impact of this is significant (especially before XAML’s intense diet it’s going on for Win10).
    2) If you’re using C# + XAML (instead of C++), you’re now running two JITs and two very different GCs in your app. Very far from ideal.
    3) There’s an extra layer of COM/RPC marshaling between your main UI thread and the WebView (which on Phone 8.1 and Win10 PC runs on different thread), extra surfaces and DManip delegate threads, etc.
    4) You miss out on all the system-level optimizations that native JS apps benefit from. For instance, bytecode generation at install time, which can have a significant impact on startup time.
    5) Your HTML/JS doesn’t have direct access to WinRT, so can’t take advantage of features or optimizations (like those used by WinJS when it detects WinRT is available) that a real JS app could.

    I totally get wanting to mix DX with XAML or HTML, and native code with C# or JS. What I don’t really understand is why you’d want to mix XAML with HTML, especially when presently HTML/CSS can do so much more than XAML and with a lot less (and generally far more readable) code/markup. I think you want to pick one or the other, and then add in native and/or DX stuff for specific pieces you want to optimize or go really custom (or want to better obfuscate).

    I am curious what setup you were using for those memory usage measurements. Is this on a real device? (which one?) Or was this in the emulator? (which version, resolution, memory size, etc?) And how many tweets were you displaying?

    For reference, Tweetium (JS/HTML app with a tiny bit of C++), for the *entire* app with 20 tweets in the list idles at 49.4MB (process private bytes via VS memory diag tool). That’s with the app having prefetched the connect/messages scopes and other tweet data for the timeline, showing a bunch of embedded images, and just in general doing way more than your example. That’s running on my Lumia 520. On a larger device it’s a bit higher (larger surfaces, more stuff on the screen, etc), but I figured that was a good point of comparison.

    • Brilliant comment, thanks Brandon for sharing your insights .. Yes I do know there is cost in having 2 UI frameworks.

      I’ve encountered similar arguments on iOS using UIWebView as well as Cordova apps.

      I know its not ideal based on the reasons you meniton, but I also feel that its more an engineering problem that if the platform found important enough to solve it would.

      The reason I want to push for mixing Xaml and Html is similar to how Xbox One works with its’ multiple display planes..

      Modern graphics HW is now providing multiple swap chains (display planes) for rendering UI’s. For Xbox One its got 3 display planes 2 for a title/app and 1 for system .

      Why can’t i create 1 display plane in XAML (the HUD of your game or the Chrome of your app) and the 2nd Display plane the HTML or DX content.. Yes we would need to overcome the issues you mention, but thats pure engineering ..

      Why can’t I create the Twitter stream in HTML and the “Chrome” in XAML.

      I’m comfortable coding in both web technologies and xaml, but honestly I prefer Xaml for certain things. I’m more productive and can iterate faster using XAML.

      I’ve seen some very complex DX based game engines (SharpDx), with their own GC, Resource Management etc. mixed with XAML & .NetCore or .NET.

      I can’t see why we can’t aim to have a Trident/Chakra and XAML + .NETCore/.NET optimized experience . MS should work towards this, but I know this is probably where we’ll disagree🙂

  2. Oh, and it is a real shame about the lack of color emoji on WP 8.1. That affects both WebView and JS/HTML apps (and the browser). Big Windows doesn’t have that limitation, so you see different behavior in Tweetium on PC/tablet versus Phone. It should be fixed on Phone for Win10, but still very disappointing that it’s missing on WP 8.1.

  3. Nice article.
    To improve on TextBlock mode, you may also use TextBlock.Inlines collection to directly construct text in your own Binding adapter.

    In this case you combine flexibility of Runs with light weight of TextBlock, staying completely RichTextBlock free.

  4. Pingback: Building a Universal XAML Twitter stream: TextBlock vs RichTextBlock vs WebView

  5. Hello,

    When I built this into my own Twitter app I can’t deploy it on my phone, it keeps give me the error that the RichTextBindingHelper doesn’t exist. In the example it also gives me that error but I could still run it on Windows 8.

    How do I fix this?

    Thanks in advance,

    Han Swinkels

  6. Nice post, thanks for sharing !!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s