Kitten Tale

Isis - Browser Inside Browser

A month ago HP unveiled Isis Browser. The browser was originally built for their WebOS. But porting for Linux looks ongoing so we’ll be able to try it in near future.

Because the project chooses QtWebKit as its rendering engine, I think some Kitten may have an interest. Actually the browser is making some interesting design decision, which is worth covering here.

HTML as Browser UI

You must have heard about Gecko, the rendering engine of Firefox. Gecko invented an HTML-like XML vocabulary called XUL for building its whole UI. Not only Firefox but also most of Mozilla originated desktop products are built on top of XUL.

Gecko (including XUL) by itself is a platform for running desktop applications. This approach is totally different from WebKit-based browsers, which generally employ OS-native toolkits. For example, Safari is using Cocoa and Windows Chromium is using Win32. WebKit is just an HTML renderer for these browsers, even though that is a significant construct.

However, Isis browser — which is also based on WebKit — chooses another approach: Building its UI using HTML. It’s kinda like XUL, but without any custom-made markup vocabulary.

This approach explains why they claim that Isis is based on Enyo JavaScript framework. Isis uses Enyo as primary HTML-backed GUI library. You can see Isis Browser codebase containing no C++ code, but having a bunch of JavaScript instead.

BrowserAdaptor and BrowserServer

Then the question is how it gets stuff work. How can we navigate web sites inside HTML? Are they use <iframe>? It might be possible. But it won’t be sweet because WebKit doesn’t support any process isolation for <iframe>, which is one of the essential requirements of modern browsers.

And here an interesting idea arrives: Isis addresses this requirement by implementing a browser plugin, which renders HTML using WebKit!

They call it BrowserAdaptor. BrowserAdaptor is a plugin, which accepts NPAPI to run inside WebKit. But it can render HTML by itself, using (again) WebKit. With this plugin, Isis can render its UI in the topmost WebKit, while rendering navigating Web pages through WebKit inside BrowserAdaptor.


The plugin browser supports process isolation. This process-isolated renderer is called BrowserServer. It’s hosted in a separate git repo. BrowserAdaptor delegates page rendering to BrowserServer.

“Process isolated WebKit!” You kitten might get excited and ask, “So do they adopt WebKit2?” No. They don’t. They have their own IPC mechanism, their own serializer, code generator and their own lifecycle model.

Talking about lifecyle, BrowserServer is more like “real” server than WebProcess of WebKit2 or renderer of Chromium. It is designed for running as a linux daemon. It has a boot script for Upstart. Its diagnose message goes through syslog. Its resource is managed under cgroups. This design might make it hard to port Isis to non-Linux platforms. It could be a affordable price though, if it can fully utilize Linux kernel ability.

What clear is that Isis is taking a step into a frontier no other Kitten has explored, where the boundary between UI and page is blurring. Honestly I thought that such approach is possible only with platformish architecture like Gecko or WPF. But Isis demonstrates it being possible even for librarish WebKittens, if you hole the page somehow.


Coincidentally, B2G — a Gecko-based mobile platform developed by Mozilla — is following a similar path as Isis: They are building mobile applications using HTML. Their built-in applications include phonecall, address book and Web browser. Yes, B2G is building its Web browser on top of HTML! They don’t use XUL for some reason.

Then same question arises. That is, how do they achieve process isolation? Implementing Gecko plugin? Or they just give it up and use <iframe>?

Neither. They use <iframe> and they have process isolation. As a part of their Electrolysis effort, they’ve implemented process isolation mechanism for <browser> element in XUL. Basically, it’s <iframe> for XUL. But once you give @remote attribute to it, Gecko creates a dedicated process for the element to render its content. I can imagine that it was a tough work. But that is Mozilla. Their hardcore hackers managed to do it. Even though they are suspending the effort for reasons, they finished underlying plumbing.

And this time, they bring it to <iframe>. A discussion explains that each <iframe> with special @mozbrowser attribute is going to have dedicated process. The role of mozbrowser-ed iframe is almost same as Isis’s BrowserAdaptor plugin. But it comes with more Web-looking face.

Fullscreen Rescues

I’m wondering why these two mobile platforms adopt HTML as their GUI toolkit, regardless no desktop browser has done it. Is it really coincidence?

My humble guess is that’s because desktop applications need windows, chromes or frames, and lack of ability to control it from HTML prevented that choice. For each web page, its windows is given by the browser. And every modern browser does hard work to create unique looking, slick feeling frames. Only few browser adopt platform’s default frames.

Mobile is different. Basically every application runs fullscreen. That means it doesn’t need any cool frames, and that’s why tools like PhoneGap are welcomed. Isis and B2G are also in same party; They live in the fullscreen world where cutting-edge HTML shines.

Of course, there must have been more general lack of ability other than frame stuff. HTML didn’t have flexbox for example. So its overall improvement would’ve also helped to revert the dated decision.

Browsers Only?

By the way, is the out-of-process <iframe> or plugin browser applicable only for building browsers? I don’t think so. Any web page which is mashing up widgets using <iframe> possibly could take advantage of it. It is true that <iframe> is adopted broadly. But that doesn’t mean there is no shortcoming of that. In reality, it’s slow, it drains memory and its isolation wall is fragile. This is because <iframe> shares many structure with its host page.

If it lives in a separate process, this situation will drastically change. Each host page will be no longer hurt by its rogue embedees anymore because their rendering will happen in separate processes. They don’t block its parent rendering. Memory will be easily reclaimed for each of them closed. You no longer need to worry about memory leaks nor crashes of child frames.

With out-of-process iframe, mashup ability of browsers will advance to the next level. I hope someday it gets standardized and becomes available not only for Web “browser” developers, but also (non-browser) Web developers. It will be tough job to implement it in WebKit. but wizard kittens will make it happen if people want.

P.S. My friends who loves Microsoft stack told me that it was called OLE in their world and it supported both out-of-process hosting and IPC. Well, there are always something worth learning from ancient literature. Agreed … and ordered.

Scrolling Meets Compositor

A few weeks ago, I noticed that some engineers from Apple landed a small module behind THREADED_SCROLLING flag. Thread? The name sounds interesting. So I took a quick look. And here is a rough finding from that: This is a machinery aiming to make scrolling as smooth as CSS animation, it looks.

To find how it works, we need some basic understanding about implementation of CSS animation and scrolling. Let me start from the former, then proceed to the later, which includes the today’s highlight.


WebKit allows CSS Animations to run smoothly. This is especially true for ones over CSS 3D Transforms. To make this happen, a WebKit feature called ACCELERATED_COMPOSITING was introduced at the beginning of 2009, which brought the power of GPU acceleration into WebKit.

Here is a basic idea behind the accelerated compositing: With accelerated compositing enabled, WebKit renders split the page into mutually exclusive parts called “layers”, then render each of them into an offscreen image separately, and “composite” it after all these images are rendered.


The point here is that each rendered image of the layer - it’s called a “backing store” in WebKit by the way - is located on the GPU side. Thus the composition of the set of backing stores into the final image can be done pretty quickly with little CPU load, thanks to the GPU speed.

Basically, a layer is corresponding to a subtree of of the page’s DOM. And the whole DOM tree is splitted into layer subtrees based on some CSS properties. For example, if there is a <div> which is styled to have 3d-transormation, the <div> will establish a new layer. And the <div>-rooted subtree will be painted into the backing store of that layer.

Since each layer has own backing store, we don’t need to repaint a layer even if others get modified and repainted. What we need is just re-composite these backing stores. This composition is orders of magnitude fater than repainting the whole page - GPU is a device desinged for these types of operations after all.

We also don’t need to repaint a layer if only its “transformation” is changed. The browser can handle such tranformations in the GPU side as a part of the composition process.

Backing stores, fast compositions and cost-free transformations; Thanks for these characteristics, WebKit can render 3D-ish CSS animations quite smoothly.

Core Animation for Better Slickness

Things go further if you are using Apple ports of WebKit. On Mac (or Apple Windows), the composition is implemented on top of Core Animation infrastructure. As the name implies, Core Animaton helps smooth animation like CSS 3D Transforms. And its implementation fits the backing store model of ACCELERATED_COMPOSITING. In reality, ACCELERATED_COMPOSITING was first desinged for Core Animations.

One great advantage of CA - WebKit calls it “CA” for short - is that it runs these animations in a different thread. So it can run smoothly even if the main thread is getting stuck by, for example, heavy JavaScript programs. Without threaded backends like this, animations for CSS transforms can stuck when big chunk of computations like layout or JS happen in the main thread.


This will especially work well for mobile devices. Because CPUs in mobile devices are relatively slow, and at the same time, they start to have another CPU core. CSS animation on mobile is one of the best place where CA-like system shines.

Chromium also has its own composition subsystem, which is called cc. But I don’t know much about that… Well, you can blame me ;-)

Scrolling - Slick or Quick?

Scrolling is another place where browsers can be slicker.

Don’t take me wrong. Browsers do scrolling well. But it’s more like quick than slick. Typical page scrollings happen by per-line, or per-page basis. If you hit “down” key, it scrolls the page about ten pixels. If you click scrollbar, it jumps over hundreds of pixels. (FYI, WebKit supports four types of scroll “granuality”: line, page, document and pixel. You can find them at ScrollTypes.h.) This large-step scrolling has been working well. But it may not be felt slick to skip dozen pixels per frame.

On Mac (again!), the situation is different. Safari (and Mac Chromium), does scrolling slickly intead of quickly; If you click the scroll bar, you’ll see an animated scroll. It scrolls down a page height using tens of frames. WebKit implements this slick scroll as ScrollAnimator class and the family. They live behind ENABLE(SMOOTH_SCROLLING) flag.

Note that the animated scrolling is a different gear from the accelerated compositing. These two don’t share same machinery for some reasons: First, scrolling makes previously-invisible regions visible - This is why people scroll the page. So browsers need to paint these regions. This prevents us from just compositing existing backing stores.

Second, the scrolling animation isn’t “declarative”. In other word, it cannot be described on top of CA’s animation model. It requires a custom-made code to compute the scrolled position.

First one is especially tough. What worse is, we might have to re-layout if the page has something like position: fixed. There are also pages which monitor scrolling to trigger JavaScript for something funny. All these stuff causes a pause and prevents smooth scrolling in a resonable frame rate. This is one of the reason why many non-Mac browsers choose quick, jumpy scrolling instead of slick one.

Scrolling on Touch Devices

This story has a blind side though. In fact, browsers for touch devices like Mobile Safari take an advantage of that.

When you use Mobile Sari, you’ll notice that their scrolling and zooming is extremely smooth. But at the same time, you’ll also notice that sometimes the page painting doesn’t catch up the scrolling (and the zooming). That is the trick: While scrolling, the browser skips some painting to gain the animation frame-rate. In theory, this behavior isn’t correct. An ideal browser shouldn’t show any blank region to the user. But in practice, this is a totally sensible trade-off.

WebKit itself doesn’t support this kind of scrolling-without-painting. Browsers do it by themselves. For example in iOS, I guess they do something like this: Grab the view, which ha CA backing store (called CALayer), pull it out, apply transformation to the backing store without letting WebKit know. Then once the CPU becomes less busy, they notify scrolling to it. WebKit won’t run during the animation thus doesn’t interrupt its slickness.

I don’t check how Android Browser works. But I can imagine it doing something similar.

Having read this, you may ask why WebKit doesn’t support this. Good question! That is exactly THREADED_SCROLLING is trying to do.

THREADED_SCROLLING and ScrollingCoordinator

Most of the THREADED_SCROLLING module is living under WebCore/page/scrolling. This piece of code is basically a scrolling complement for the CA animation model.

With THREADED_SCROLLING, WebKit pushes scrolling out to a background thread, which is named ScrollingThread.


This new machinery introduced an asynchronous scrolling model to make this work. In this model, an updated scroll-position, which is requested by some other WebCore object, isn’t applied immediately. Instead, asking a new position will trigger a scrolling animation, and the position applied after the animation is finished.

In FrameView.cpp, you can find FrameView::requestScrollPositionUpdate() where the asynchronous scrolling starts. It asks ScrollingCoordinator to run the scrolling animation. Then the coordinator schedules it on the dedicated thread. Once the animation is finished, the thread notifies back to the coordinator on the main thread, then it calls back FrameView::notifyScrollPositionChanged().

This new feature has one clear advantage over out-of-WebKit implementations: It can work with <iframe>. From a browser-side, it’s hard to access backing stores for each <iframe> because WebKit doesn’t expose such a detail. Actually its layer hierarchy isn’t so simple, It’s something WebKit should take care by itself.

What interesting is that no other objects except FrameView depends on stuff from the threaded scrolling shop. Also, no other newly-introduced objects other than ScrollingCoordinator touches FrameView. All of whom they communite with is CA’s backing stores - and a corresponting WebCore abstraction called GraphicsLayer. We could find some pattern for introducing new features from this minimized dependency.

Their rubber band scrolling animation is implemented in ScrollElasticityController under WebCore/platform/mac. It’s interesting to see that Mac port adopts Cocoa-like MVC pattern even for C++ world. If you take a look, you’ll find that ScrollAnimator I mentioned before is another “view” of the controller.

It looks I’ve stepped into too much now … Anyway, an enthusiasm to slickness like this is one of the most respectable characteristics of WebKit. It’s delightful to see such an improvement.

Hello WebKit

Kitten is for WebKitten. This place is for some randm folklore that I heared, saw or made at the WebKit land. Some will be technical, others won’t.

Here is how this comes here: I am a big fun of Evan Martin and his writings, especially his Chromium Notes. But he leaves the project and stopped writing it. This is sad for me. At the same time, an idea comes to my mind - Can I do something similar? The idea comes with two bad news though. Bad news part one is that I’m not familiar with Chromium. But fortunately, I know a few about WebKit that I can talk about. Bad news part two is that my writing is far behind Evan’s. Well, that is that. I can at least type some words in almost gramatically correct way. Let me just hope it somehow work.


This note is never compehensive nor authorative, This is just a personal note written by a noteless contributor. The author is relatively new to the project: I’ve been working on WebKit since the beginning of 2010. It’s shorter than a quater of the project history. There are many authorative and informative sources over the Web, which are written by more experienced people.

As always, the opinions expressed here are my own, and no other party (including my employeer) necessarily agrees with them.