Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-14 Thread Steven Young
If anyone needs a test page, you can log in as my test user
styoung.tra...@gmail.com (pwd:browsertest). Then go to
https://www.facebook.com/styoung.


 you could maintain a separate document for measuring items, so you could 
 measure without reflowing the main document.

We are actually already doing that. Kelly Norton suggested offline to
me that the problem could be layout thrash caused by us doing
interleaved dom reads/writes (one for each story) as opposed to a
series of reads followed by a series of writes. That sounds right to
me.

 (2) 50% of time spent painting images... This is a simple speed vs quality 
 tradeoff. If you down-sampled the images on the server, they'd download and 
 paint much faster.

Thanks. Downsampling sounds like a straightforward solution. We can
show the higher quality image if they open the photo.

Btw, what tool are you using that tells you what item is being
repainted when the cpu is pegged?
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-14 Thread Maciej Stachowiak

On Feb 14, 2012, at 10:25 AM, Steven Young wrote:

 
 
 (2) 50% of time spent painting images... This is a simple speed vs quality 
 tradeoff. If you down-sampled the images on the server, they'd download 
 and paint much faster.
 
 Thanks. Downsampling sounds like a straightforward solution. We can
 show the higher quality image if they open the photo.

The significant time spent painting images could simply be a sign that too much 
of the page is being repainted when scrolling, which could be a side effect of 
unnecessary re-layouts. So this could just another symptom of the layout 
thrash problem. Thus, I would suggest fixing the other issues and retesting 
before you move to downsample images.

 
 Btw, what tool are you using that tells you what item is being
 repainted when the cpu is pegged?

I would guess that Geoff is using the Instruments tool on Mac OS X, but it 
likely takes some expert knowledge to interpret the profile. You can tell by 
looking at the profile what kind of things are getting painted, but not 
necessarily the specific item.

REgards,
Maciej


___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-14 Thread Geoffrey Garen
 If anyone needs a test page, you can log in as my test user
 styoung.tra...@gmail.com (pwd:browsertest). Then go to
 https://www.facebook.com/styoung.

Nice!

I took a trace of this timeline and saw similar results as before (lots of time 
computing .offsetHeight and .scrollLeft), but with less time spent in image 
drawing. (Perhaps I have higher resolution photos in my timeline.)

 Btw, what tool are you using that tells you what item is being
 repainted when the cpu is pegged?


Mac OS X ships with a performance analysis tool called Instruments.

Documentation overview:

https://developer.apple.com/library/wwdc/ios/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40004652

Recent WWDC presentation:

https://developer.apple.com/wwdc/schedule/details.php?id=310

Instruments analysis doesn't work very well with the current shipping version 
of WebKit, but it works great with WebKit nightly builds (nightly.webkit.org).

Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-13 Thread Ryosuke Niwa
It's hard for me to advice you on how to optimize your website but will you
be interested in creating a reduced test cases where WebKit is slow?

I'm sure we can (at least try to) resolve your pain points if you can
create benchmarks licensed under BSD/LGPL or WebKit performance tests (see
http://trac.webkit.org/wiki/Writing%20Performance%20Tests).

Best regards,
Ryosuke Niwa
Software Engineer
Google Inc.

On Sat, Feb 11, 2012 at 10:02 PM, Steven Young styoung.bi...@gmail.comwrote:

 [cross posting from mozilla's dev lists]

 I'm on the Timeline team at Facebook, which is going to be the new
 format for everyone's profiles real soon now.
 https://www.facebook.com/about/timeline We'd like to improve its
 browser performance, so I'd appreciate any suggestions for things we
 should change to speed it up. In particular, we'd like to make
 scrolling down through new content smoother. There are often brief
 (e.g. 300 ms) browser lockups, and other times there just seems to be
 a general feeling of heaviness.

 I'm going to list some of the specific issues we've identified, which
 we are debating how best to fix, but I'm also very interested to hear
 whatever anyone else thinks are the biggest perf bottlenecks.

 A few problems:

 (1) HTML / DOM size and CSS

 Our HTML is huge. About half of it is coming from the light blue
 like/comment widgets at the bottom of most stories. Within those
 widgets, a major portion of it is always the same. (Some of that is
 only needed once the user clicks into the widget, but we don't want
 another server round trip to fetch it.)  We also have a lot of CSS
 rules, and applying all that CSS to all those DOM nodes gets
 expensive. Experimentally, removing all like/comment widgets from the
 page does give noticeably smoother scrolling, although it doesn't
 completely fix the problem.

 Related: We've also noticed that if you scroll very far down a
 content-rich timeline, and then open and close the inline photo
 viewer, this causes a noticeable lag, as it re-renders all existing
 content on the page. To fix this, we investigated dynamically removing
 offscreen content from the DOM and replacing  it with empty divs of
 the same height, but we decided it wasn't worth the code complexity
 and fragility.

 (2) Repaints

 There are several fixed elements on the page like the blue bar at the
 top, the side bar, and our date navigator with the months/years.
 Chrome's --show-paint-rects flag showed that under most circumstances
 these fixed-position elements forced full-screen repaints instead of
 incremental repaints. The rules for what triggers a repaint vary from
 browser to browser, but we would ideally like to fix this everywhere.
 The cost of full page repaints also sometimes varies dramatically even
 comparing Chrome on two fairly newish Mac laptops.

 (3) Javascript for loading content as you scroll down

 We dynamically load timeline sections (e.g. a set of stories from
 2009) using our BigPipe system
 (https://www.facebook.com/note.php?note_id=389414033919) in an iframe.
 In a nutshell, the HTTP response to the iframe is sent with chunked
 encoding, a script tag at a time. Each script tag contains some code
 and and HTML content that is passed up to the parent window, which
 requests the CSS and JS associated with that HTML content. Once the
 CSS is downloaded, the HTML (timeline story markup) is inserted into
 an offscreen DOM element. Then, once the JS is loaded, we do some
 fairly complicated work before we actually display the content.

 First, we lay out the timeline stories in an offscreen element
 (position:absolute; left:-px) before inserting them into the
 viewable page. We then have JS which checks the heights of all the
 stories on in the offscreen element so it can swap stories back and
 forth between the two columns, to keep things sorted by time going
 down the page. To do this,  we query and cache the stories' offsetTop
 values all at once where possible. Probably, we could eliminate all
 this height-checking and column balancing if we implemented a machine
 learning algorithm to predict the height of each unit in advance, on
 the server side.

 Next, in an attempt to reduce user-percieved browser freezing while
 scrolling, our JS does not add new content in to the bottom of the
 main column as soon as it comes back from the server. Instead, we
 queue it up until the user stops scrolling and add it in then. We use
 document fragments where possible to insert elements. Web Inspector's
 profiler showed improvements when dynamically inserting many link
 rel=stylesheet tags in this fashion since we stopped thrashing
 between style recomputation and JS execution for each stylesheet,
 and instead just had one longer style recomputation segment.

 We throttle scroll/resize events so they fire every 150 ms

 All the while this is happening, we're potentially receiving more
 script tags in the iframe and doing the same thing for other pieces
 of content.


 We would 

Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-13 Thread Geoffrey Garen
Hi Steve.

Do you have a test account with a fixed content set that we can use for 
profiling?

It's hard to speculate about performance issues without profiling, and we might 
get confused if we all profile different content.

Thanks,
Geoff

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-13 Thread Geoffrey Garen
Profiling scrolling through my own timeline, and focusing on points where the 
CPU hit 100% or greater, I saw this:

(1) 50% of time spent in style calculation forced by accessing 
element.offsetHeight in JavaScript.

 We then have JS which checks the heights of all the
 stories on in the offscreen element so it can swap stories back and
 forth between the two columns, to keep things sorted by time going
 down the page.

One sometimes pernicious effect of accessing style-related properties while 
changing the DOM is that you force twice (or n times) the work to happen: 
first, style resolves to supply your property value; then, you change the DOM, 
and style resolves again to account for your change. Since style resolution is 
generally O(n), this can easily become O(n^2) behavior.

According to my measurements while scrolling my own timeline, you could make 
scrolling twice as buttery by removing these accesses to element.offsetHeight, 
or doing them on a zero-delay timer after all DOM changes.

(2) 50% of time spent painting images.

This is a simple speed vs quality tradeoff. If you down-sampled the images on 
the server, they'd download and paint much faster.

Geoff

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-13 Thread David Levin
Not sure what tools you have used but you may find this helpful:
http://code.google.com/webtoolkit/speedtracer/

On Sat, Feb 11, 2012 at 10:02 PM, Steven Young styoung.bi...@gmail.comwrote:

 [cross posting from mozilla's dev lists]

 I'm on the Timeline team at Facebook, which is going to be the new
 format for everyone's profiles real soon now.
 https://www.facebook.com/about/timeline We'd like to improve its
 browser performance, so I'd appreciate any suggestions for things we
 should change to speed it up. In particular, we'd like to make
 scrolling down through new content smoother. There are often brief
 (e.g. 300 ms) browser lockups, and other times there just seems to be
 a general feeling of heaviness.

 I'm going to list some of the specific issues we've identified, which
 we are debating how best to fix, but I'm also very interested to hear
 whatever anyone else thinks are the biggest perf bottlenecks.

 A few problems:

 (1) HTML / DOM size and CSS

 Our HTML is huge. About half of it is coming from the light blue
 like/comment widgets at the bottom of most stories. Within those
 widgets, a major portion of it is always the same. (Some of that is
 only needed once the user clicks into the widget, but we don't want
 another server round trip to fetch it.)  We also have a lot of CSS
 rules, and applying all that CSS to all those DOM nodes gets
 expensive. Experimentally, removing all like/comment widgets from the
 page does give noticeably smoother scrolling, although it doesn't
 completely fix the problem.

 Related: We've also noticed that if you scroll very far down a
 content-rich timeline, and then open and close the inline photo
 viewer, this causes a noticeable lag, as it re-renders all existing
 content on the page. To fix this, we investigated dynamically removing
 offscreen content from the DOM and replacing  it with empty divs of
 the same height, but we decided it wasn't worth the code complexity
 and fragility.

 (2) Repaints

 There are several fixed elements on the page like the blue bar at the
 top, the side bar, and our date navigator with the months/years.
 Chrome's --show-paint-rects flag showed that under most circumstances
 these fixed-position elements forced full-screen repaints instead of
 incremental repaints. The rules for what triggers a repaint vary from
 browser to browser, but we would ideally like to fix this everywhere.
 The cost of full page repaints also sometimes varies dramatically even
 comparing Chrome on two fairly newish Mac laptops.

 (3) Javascript for loading content as you scroll down

 We dynamically load timeline sections (e.g. a set of stories from
 2009) using our BigPipe system
 (https://www.facebook.com/note.php?note_id=389414033919) in an iframe.
 In a nutshell, the HTTP response to the iframe is sent with chunked
 encoding, a script tag at a time. Each script tag contains some code
 and and HTML content that is passed up to the parent window, which
 requests the CSS and JS associated with that HTML content. Once the
 CSS is downloaded, the HTML (timeline story markup) is inserted into
 an offscreen DOM element. Then, once the JS is loaded, we do some
 fairly complicated work before we actually display the content.

 First, we lay out the timeline stories in an offscreen element
 (position:absolute; left:-px) before inserting them into the
 viewable page. We then have JS which checks the heights of all the
 stories on in the offscreen element so it can swap stories back and
 forth between the two columns, to keep things sorted by time going
 down the page. To do this,  we query and cache the stories' offsetTop
 values all at once where possible. Probably, we could eliminate all
 this height-checking and column balancing if we implemented a machine
 learning algorithm to predict the height of each unit in advance, on
 the server side.

 Next, in an attempt to reduce user-percieved browser freezing while
 scrolling, our JS does not add new content in to the bottom of the
 main column as soon as it comes back from the server. Instead, we
 queue it up until the user stops scrolling and add it in then. We use
 document fragments where possible to insert elements. Web Inspector's
 profiler showed improvements when dynamically inserting many link
 rel=stylesheet tags in this fashion since we stopped thrashing
 between style recomputation and JS execution for each stylesheet,
 and instead just had one longer style recomputation segment.

 We throttle scroll/resize events so they fire every 150 ms

 All the while this is happening, we're potentially receiving more
 script tags in the iframe and doing the same thing for other pieces
 of content.


 We would love any pointers you guys have.

 Thanks,
 Steve
 ___
 webkit-dev mailing list
 webkit-dev@lists.webkit.org
 http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

___
webkit-dev mailing list

Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-13 Thread Steven Young
 will you be interested in creating a reduced test cases where WebKit is slow?

Ryosuke - For now, user complaints about slowness are too
unpredictable and poorly defined for me to create a simple test case.
I will report back here if we reach that point.

 (1) 50% of time spent in style calculation forced by accessing 
 element.offsetHeight in JavaScript.

Geoff - I am going to bite the bullet and rip this logic out. We are
pushing too much complexity into the browser.

 (2) 50% of time spent painting images... This is a simple speed vs quality 
 tradeoff. If you down-sampled the images on the server, they'd download and 
 paint much faster.

Geoff - Painting images specifically, or just repainting the page in general?

 Not sure what tools you have used but you may find this helpful: 
 http://code.google.com/webtoolkit/speedtracer/

David - Thanks!
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-13 Thread Geoffrey Garen
 (1) 50% of time spent in style calculation forced by accessing 
 element.offsetHeight in JavaScript.
 
 Geoff - I am going to bite the bullet and rip this logic out. We are
 pushing too much complexity into the browser.

Bear in mind that I didn't do enough analysis to explain why the .offsetHeight 
code was so costly. It may be possible to tune this code and keep it in the 
browser. For example, you could maintain a separate document for measuring 
items, so you could measure without reflowing the main document.

 (2) 50% of time spent painting images... This is a simple speed vs quality 
 tradeoff. If you down-sampled the images on the server, they'd download and 
 paint much faster.
 
 Geoff - Painting images specifically, or just repainting the page in general?

Painting images specifically.

Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


[webkit-dev] optimizing browser handling of Facebook Timeline scrolling

2012-02-11 Thread Steven Young
[cross posting from mozilla's dev lists]

I'm on the Timeline team at Facebook, which is going to be the new
format for everyone's profiles real soon now.
https://www.facebook.com/about/timeline We'd like to improve its
browser performance, so I'd appreciate any suggestions for things we
should change to speed it up. In particular, we'd like to make
scrolling down through new content smoother. There are often brief
(e.g. 300 ms) browser lockups, and other times there just seems to be
a general feeling of heaviness.

I'm going to list some of the specific issues we've identified, which
we are debating how best to fix, but I'm also very interested to hear
whatever anyone else thinks are the biggest perf bottlenecks.

A few problems:

(1) HTML / DOM size and CSS

Our HTML is huge. About half of it is coming from the light blue
like/comment widgets at the bottom of most stories. Within those
widgets, a major portion of it is always the same. (Some of that is
only needed once the user clicks into the widget, but we don't want
another server round trip to fetch it.)  We also have a lot of CSS
rules, and applying all that CSS to all those DOM nodes gets
expensive. Experimentally, removing all like/comment widgets from the
page does give noticeably smoother scrolling, although it doesn't
completely fix the problem.

Related: We've also noticed that if you scroll very far down a
content-rich timeline, and then open and close the inline photo
viewer, this causes a noticeable lag, as it re-renders all existing
content on the page. To fix this, we investigated dynamically removing
offscreen content from the DOM and replacing  it with empty divs of
the same height, but we decided it wasn't worth the code complexity
and fragility.

(2) Repaints

There are several fixed elements on the page like the blue bar at the
top, the side bar, and our date navigator with the months/years.
Chrome's --show-paint-rects flag showed that under most circumstances
these fixed-position elements forced full-screen repaints instead of
incremental repaints. The rules for what triggers a repaint vary from
browser to browser, but we would ideally like to fix this everywhere.
The cost of full page repaints also sometimes varies dramatically even
comparing Chrome on two fairly newish Mac laptops.

(3) Javascript for loading content as you scroll down

We dynamically load timeline sections (e.g. a set of stories from
2009) using our BigPipe system
(https://www.facebook.com/note.php?note_id=389414033919) in an iframe.
In a nutshell, the HTTP response to the iframe is sent with chunked
encoding, a script tag at a time. Each script tag contains some code
and and HTML content that is passed up to the parent window, which
requests the CSS and JS associated with that HTML content. Once the
CSS is downloaded, the HTML (timeline story markup) is inserted into
an offscreen DOM element. Then, once the JS is loaded, we do some
fairly complicated work before we actually display the content.

First, we lay out the timeline stories in an offscreen element
(position:absolute; left:-px) before inserting them into the
viewable page. We then have JS which checks the heights of all the
stories on in the offscreen element so it can swap stories back and
forth between the two columns, to keep things sorted by time going
down the page. To do this,  we query and cache the stories' offsetTop
values all at once where possible. Probably, we could eliminate all
this height-checking and column balancing if we implemented a machine
learning algorithm to predict the height of each unit in advance, on
the server side.

Next, in an attempt to reduce user-percieved browser freezing while
scrolling, our JS does not add new content in to the bottom of the
main column as soon as it comes back from the server. Instead, we
queue it up until the user stops scrolling and add it in then. We use
document fragments where possible to insert elements. Web Inspector's
profiler showed improvements when dynamically inserting many link
rel=stylesheet tags in this fashion since we stopped thrashing
between style recomputation and JS execution for each stylesheet,
and instead just had one longer style recomputation segment.

We throttle scroll/resize events so they fire every 150 ms

All the while this is happening, we're potentially receiving more
script tags in the iframe and doing the same thing for other pieces
of content.


We would love any pointers you guys have.

Thanks,
Steve
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev