Dump render tree in real time

1,022 views
Skip to first unread message

jip.d...@gmail.com

unread,
Apr 8, 2016, 11:39:06 AM4/8/16
to blink-dev
Hi all,

I would like to inspect the Render Tree in real time while browsing with Google Chrome.
In this list (http://peter.sh/experiments/chromium-command-line-switches/#run-layout-test) I found the command line switch --run-layout-test which request the render trees of pages to be dumped as text once they have finished loading.

When I run Chrome like this: "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --run-layout-test" Chrome will start up but I don't see render trees dumped to the Terminal. Where are the render trees dumped to? Can this switch be used on the release version of Google Chrome? At the moment it doesn't seem to do anything.

I'm using the latest versions of Google Chrome on Mac OS x 10.10.

Looking forward to your replies.

Thanks in advance.
Jip

Jochen Eisinger

unread,
Apr 8, 2016, 11:49:36 AM4/8/16
to jip.d...@gmail.com, blink-dev

The layout test infrastructure is only compiled into our test shell called "Content Shell" on Mac, it's not possible to use it from chrome.

Also note that layout tests are run headless.

Christian Biesinger

unread,
Apr 8, 2016, 11:54:56 AM4/8/16
to jip.d...@gmail.com, blink-dev
Hi Jip,

there's no way to see the render trees (now called layout trees) in
real time. That switch, which is a switch for content shell, will just
make it load the page you give on the command line, dump the tree, and
exit.

-Christian

jip.d...@gmail.com

unread,
Apr 8, 2016, 1:10:52 PM4/8/16
to blink-dev, jip.d...@gmail.com
Thanks for your quick reply. What about other platforms (Linux, Windows)? Is the layout test infrastructure built into those versions of Chrome? At least I can stop trying this on my Mac now :)

"Content Shell" runs headless but layout is dependent on viewport size. How does that work?

Christian Biesinger

unread,
Apr 8, 2016, 1:15:34 PM4/8/16
to jip.d...@gmail.com, blink-dev
Content shell uses a fixed viewport of 800x600.

No difference between platforms.

-Christian

jip.d...@gmail.com

unread,
Apr 8, 2016, 1:26:21 PM4/8/16
to blink-dev, jip.d...@gmail.com
Allright, thanks again.

What if I build Chromium from source? Can I simply dump the Layout Tree by adding 1 line of code? It's probably not that simple but as I'm mainly a JavaScript developer and the and the browser does create the layout tree in real time... I have the feeling that a console.log() equivalent statement should be able to output the Layout Tree.

Christian Biesinger

unread,
Apr 8, 2016, 2:07:10 PM4/8/16
to Jip de Beer, blink-dev
Yeah, it should be pretty straightforward. Call one of these two
functions whenever you want:
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/layout/LayoutTreeAsText.h&q=LayoutTreeAsTe&sq=package:chromium&l=60

But I'm kind of curious why you're interested in this. Usually layout
trees are more interesting when debugging a specific web page?

-Christian

jip.d...@gmail.com

unread,
Apr 8, 2016, 2:41:05 PM4/8/16
to blink-dev, jip.d...@gmail.com
Hi Christian,

Thanks. I should look into that. LayoutTreeAsText seems to be what I want. Which two functions do you mean? And do you have a suggestion where I can add a call to those functions to enable real time dumping? I will happily build from source but I've got no clue where to add the code.

By the way, is my question unrelated to blink? Since you link to WebKit documentation.

I just found out that Safari has a button to show the Render Tree in a list. Though not in real time. Should check out if it's accessible from the command line.

And this topic: https://groups.google.com/a/chromium.org/forum/#!topic/layout-dev/bw0u6E2tt18 seems to discuss on how to implement similar functionality in Google Chrome. I hope it will be built in one day.

Yes I can imagine the Render Tree or Layout Tree (same thing right?) to be interesting for debugging web page layout. The nice thing I imagine with real-time access to this information is that it's easier to debug page layout that rely on user interaction (like lots of JS).

The reason I'm interested in this information is because I'm an aspiring artist as well as a developer and I'd like to make visualizations based on the information in the Layout Tree.

Christian Biesinger

unread,
Apr 8, 2016, 3:17:58 PM4/8/16
to Jip de Beer, blink-dev
These two functions:

CORE_EXPORT String externalRepresentation(LocalFrame*,
LayoutAsTextBehavior = LayoutAsTextBehaviorNormal);
CORE_EXPORT String externalRepresentation(Element*,
LayoutAsTextBehavior = LayoutAsTextBehaviorNormal);

Actually, I did link to blink; for historical reasons the directory is
still called WebKit.

Not sure what the best place to put it is, I'm not as familiar with
those parts of blink. Maybe here:
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/dom/Document.cpp&sq=package:chromium&type=cs&l=4863&rcl=1460114157

Yeah, render tree is an old name for the layout tree. So I just saw
that you want this to update with user interaction. That makes this
thing harder... when do you want this to be printed? If you want this
after every update to the layout tree you can do it in something like
this:
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/frame/FrameView.cpp&q=FrameView&sq=package:chromium&l=877
But that will happen *a lot*.

Hope this helps...
-Christian

Stefan Zager

unread,
Apr 8, 2016, 3:19:37 PM4/8/16
to jip.d...@gmail.com, blink-dev
The hard part of what you want to do is adding the code to trigger a dump from the browser.  That will require some non-trivial plumbing including IPC stuff.

But the simplest, most hacktastic way would be to add a signal handler somewhere in the blink code.  For reference:


That code lets you pause the renderer process during startup for the purpose of attaching a debugger.  Once the debugger is attached, you send it a signal to proceed like this:

$ kill -s SIGUSR1 <renderer pid>

For what you want to do, I suggest adding the signal handler somewhere in the blink code, maybe in src/third_party/WebKit/Source/core/frame/FrameView.cpp.  It would look something like this:

static void DumpLayoutTreeHandler(void *arg)
{
  FrameView* frameView = reinterpret_cast<FrameView*>(arg);
  TextStream ts;
  LayoutTreeAsText::writeLayers(ts, frameView->layoutView()->layer());
  fprintf(stderr, ts.release().asciiDebug());
}

FrameView* FrameView::create(...)
{
  FrameView* view = new FrameView(frame);
  ...

  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = DumpLayoutTreeHandler;
  sigaction(SIGUSR1, &sa, view);
}


This needs a debugging build to work, but you could also do it in a release build by pulling in the definition of String::asciiDebug.

Good luck!

Stefan Zager

unread,
Apr 8, 2016, 3:20:41 PM4/8/16
to Stefan Zager, jip.d...@gmail.com, blink-dev
Almost forgot: with that change, you should be able to trigger a layout tree dump to the terminal at any time by:

$ kill -s SIGUSR1 <renderer pid>

jip.d...@gmail.com

unread,
Apr 8, 2016, 3:39:27 PM4/8/16
to blink-dev, sza...@chromium.org, jip.d...@gmail.com
Thanks a lot! Yes, I want it to update a lot. The more responsive the better. I assume it won't update more than 60 times per second.

This gives me a lot of information to experiment with. I'm totally fine with a hacktastic solution for the moment! Obviously I'd like it even more if it was built right into Google Chrome.

I should start downloading the source, setting up build environment and reading tutorials. Then I can try to implement your suggestions.

In the command:
$ kill -s SIGUSR1 <renderer pid>
How do I get the <renderer pid>?

When I start Google Chrome with 1 open tab this is what I see in Activity Monitor:


Do you mean the PID of the Google Chrome process? Or does the renderer have a different PID?

Christian Biesinger

unread,
Apr 8, 2016, 4:15:09 PM4/8/16
to Jip de Beer, blink-dev, Stefan Zager
Well it won't usually be more than 60 times/second (often less, but depends on the website and whether it's trying to animate something), but JavaScript code can and does force layouts at higher frequencies. But if you follow Stefan's suggestion then this isn't an issue.

The renderer process id is one of the Helper processes. You can use Chrome's task manager to find it. https://productforums.google.com/forum/#!topic/chrome/xz-9TlEwwCc

-Christian

Stefan Zager

unread,
Apr 8, 2016, 4:37:35 PM4/8/16
to jip.d...@gmail.com, blink-dev, sza...@chromium.org
On Fri, Apr 8, 2016 at 12:39 PM <jip.d...@gmail.com> wrote:

In the command:
$ kill -s SIGUSR1 <renderer pid>
How do I get the <renderer pid>?

When I start Google Chrome with 1 open tab this is what I see in Activity Monitor:


Do you mean the PID of the Google Chrome process? Or does the renderer have a different PID?

Instead of the Activity Monitor, try using Chrome's TaskMangager:


The PID you want is "Tab".

Also, someone reminded me that you can get a layout tree dump using chrome tracing with blink.debug.layout enabled, but it has a lot less information in it, and if you want to get a lot of tree dumps, you'll blow out the tracing buffer capacity pretty quickly.

Levi Weintraub

unread,
Apr 8, 2016, 4:56:45 PM4/8/16
to Stefan Zager, jip.d...@gmail.com, blink-dev
One more way of snagging this info would be to add a JavaScript API to do it. You can just add a definition to one of the JS idl files like Document.idl:

DOMString dumpLayoutTree;

then wire it up in Document.

Then you could make a super-simple extension that runs and records the dumps for all your tabs :)

jip.d...@gmail.com

unread,
Apr 10, 2016, 10:26:58 AM4/10/16
to blink-dev, sza...@chromium.org, jip.d...@gmail.com
That sounds like a very nice approach! I really want to try that as well.
I actually prefer to have access to it via JavaScript and I was already planning on making an extension.

Today I tried building Chromium on my Mac but it fails at: ImportError: No module named CoreFoundation
It seems my Python environment is messed up and I'm unable to fix it (after several hours of trying...)
So I'll probably start with a fresh install of OS X sometime soon and try building again.

Thanks for all the info everybody. When I've successfully built Chromium I'll try your suggestions and post back here.

jip.d...@gmail.com

unread,
Apr 14, 2016, 12:06:14 PM4/14/16
to blink-dev, sza...@chromium.org, jip.d...@gmail.com
Hi,

Is the z-order (final result of applying z-index etc.) taken into account in the Layout Tree?
That's basically the reason I'm looking into this.

As I understood it, the Layout Tree is the DOM tree with CSS applied.
But on Firefox I noticed the Frame Tree isn't sorted by z-order and doesn't contain any information about z-order either.
I was wondering if the same applies to Chrome.

Basically I'm interested in real time dumping of the following info for all visible nodes (nodes that take up space in the document):
- z-order (so I can determine which elements are in front of other elements)
- position
- dimensions

Sami Kyostila

unread,
Apr 14, 2016, 12:20:56 PM4/14/16
to jip.d...@gmail.com, blink-dev, sza...@chromium.org
I'm not totally sure if it contains the information you want, but you might want to look into the LayerTree commands in DevTools.

- Sami

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Christian Biesinger

unread,
Apr 14, 2016, 12:26:51 PM4/14/16
to Jip de Beer, blink-dev, Stefan Zager
z-order is not directly part of the layout tree, no. I'm not sure what a good way to get that information is. I mean, the painting code obviously creates such data, I just don't know if it outputs that in a reusable form. You could always treewalk the layout tree and follow https://www.w3.org/TR/CSS2/zindex.html to find out what is occluded by what. (This is not a simple question)

-Christian

jip.d...@gmail.com

unread,
Apr 14, 2016, 12:35:13 PM4/14/16
to blink-dev, jip.d...@gmail.com, sza...@chromium.org
Thanks for replying again. I think I've done exactly as you suggested, save in JavaScript: https://github.com/Jip-Hop/visuallyOnTop.
With the visuallyOnTop JavaScript library I can walk the DOM tree and determine which DOM node is in front of others.
But downsides of this approach is that it's very slow and needs to be constantly maintained and tested to make sure it actually corresponds to the way the browser renders it.

That's why I was hoping to get this information at a lower level, directly from the browser. Like you say, the painting code does create this data. I'm just looking how to get my hands on it.

Any further suggestions? :)

Christian Biesinger

unread,
Apr 14, 2016, 1:42:40 PM4/14/16
to Jip de Beer, pain...@chromium.org, blink-dev, Stefan Zager
Why did you not say what you really wanted in your original email? :p

+paint-dev, maybe they can help you out.

-Christian

Stefan Zager

unread,
Apr 14, 2016, 2:07:38 PM4/14/16
to jip.d...@gmail.com, blink-dev, sza...@chromium.org
LayoutTreeAsText::writeLayers separates the dump into layers, which is what you want.  Layers are used to implement z-order, and I *think* the dump is in layer stacking order.

Christian Biesinger

unread,
Apr 14, 2016, 2:12:00 PM4/14/16
to Stefan Zager, Jip de Beer, blink-dev

But you can still have overlap within a layer and need to worry about paint order for those, right?

-Christian

Stefan Zager

unread,
Apr 14, 2016, 2:14:13 PM4/14/16
to Christian Biesinger, Stefan Zager, Jip de Beer, blink-dev
Yes, true.

jip.d...@gmail.com

unread,
Apr 14, 2016, 5:56:48 PM4/14/16
to blink-dev, jip.d...@gmail.com, pain...@chromium.org, sza...@chromium.org
Yes I should have said that in my original email. But I wanted to save you the trouble of reading everything I've tried so far. From what I've read I was just really convinced that I needed access to the render tree. I also thought this information could easily be dumped, but from your replies I get the feeling there is no real representation of this data in the browser.

However, I still have a bit of hope. Today I found this page: https://trac.webkit.org/wiki/Accelerated%20rendering%20and%20compositing which mentions the z-order tree. Perhaps this also exists in Chrome?

Another lead for me is the document.elementsFromPoint() method which returns all nodes at a specific coordinate in 'visual order'. The difference with what I'm trying to achieve is that I don't want the elements under a specific point but all visible document nodes (meaning they take up space, so also visibility:hidden; etc.) and I don't want to exclude elements with pointer-events:none;. It's similar because I'm interested in the visual order of the DOM nodes.

I looked into dumping layers as well, but as you mentioned that doesn't yet contain all the data I need.

Nat Duca

unread,
Apr 14, 2016, 6:15:06 PM4/14/16
to jip.d...@gmail.com, Ojan Vafai, blink-dev, paint-dev, Stefan Zager
This kinda sounds a bit like IntersectionObserver v2

--
You received this message because you are subscribed to the Google Groups "paint-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to paint-dev+unsubscribe@chromium.org.
To post to this group, send email to pain...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/paint-dev/8bcf73fb-3c2e-4429-bc44-abb79439de22%40chromium.org.

Stefan Zager

unread,
Apr 14, 2016, 6:32:23 PM4/14/16
to jip.d...@gmail.com, blink-dev, pain...@chromium.org, sza...@chromium.org
I think what you want is a dump of the display list from the paint system.  Any paint team people have advice?

jip.d...@gmail.com

unread,
Apr 15, 2016, 4:20:50 AM4/15/16
to blink-dev, jip.d...@gmail.com, pain...@chromium.org, sza...@chromium.org
But what about elements outside of the viewport? I'm interested in those too.

I came across Chromium development documentation about implementing Display List. The documents mention the implementation is similar to Firefox. With Firefox I've already experimented with dumping the Display List, which wasn't enough for me. The information I need is somewhere between the Layout Tree and painting.

IntersectionObserver v2 sounds interesting! Is it part of Chrome? I couldn't find much info about it.
Reply all
Reply to author
Forward
0 new messages