Issue metadata
Sign in to add a comment
|
TextElider is too slow for unicode text
Reported by
jongkwon...@navercorp.com,
May 30 2018
|
||||||||||||||||||||||||
Issue description
UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3410.0 Safari/537.36
Steps to reproduce the problem:
1. Run the following test on mac.
TEST(TextEliderTest, ElideUnicode) {
const FontList font_list;
const std::string input = "가나다라마바사아자차카타파하가나다라마바사아자차카타파하";
base::string16 output =
ElideText(UTF8ToUTF16(input), font_list, 200, ELIDE_TAIL);
LOG(INFO) << "output: " << output;
}
TEST(TextEliderTest, ElideUnicode2) {
const FontList font_list;
const std::string input = "가나다라마바사아자차카타파하가나다라마바사아자차카타파하";
base::string16 output =
ElideText(UTF8ToUTF16(input), font_list, 200, ELIDE_TAIL, Typesetter::NATIVE);
LOG(INFO) << "output: " << output;
}
$ out/Cocoa/gfx_unittests --gtest_filter=TextEliderTest.ElideUnicode*
2. Result is as follows:
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from TextEliderTest
[ RUN ] TextEliderTest.ElideUnicode
[57944:775:0530/111727.135832:159167693828996:INFO:text_elider_unittest.cc(66)] output: 가나다라마바사아자차카타파하가나…
[ OK ] TextEliderTest.ElideUnicode (25 ms)
[ RUN ] TextEliderTest.ElideUnicode2
[57944:775:0530/111727.136499:159167694486037:INFO:text_elider_unittest.cc(74)] output: 가나다라마바사아자차카타파하가나…
[ OK ] TextEliderTest.ElideUnicode2 (1 ms)
[----------] 2 tests from TextEliderTest (26 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (26 ms total)
[ PASSED ] 2 tests.
[1/2] TextEliderTest.ElideUnicode (25 ms)
[2/2] TextEliderTest.ElideUnicode2 (1 ms)
SUCCESS: all tests passed.
What is the expected behavior?
What went wrong?
1. ElideText() is too slow with default typesetter on mac compared to Typesetter::NATIVE.
2. 25ms is greater than 16ms, which makes jank when run on UI thread.
Did this work before? N/A
Chrome version: 68.0.3410.0 Channel: n/a
OS Version: OS X 10.13.4
Flash Version:
,
May 31 2018
I think this is something of a known issue. Most specifically, Issue 267710. There's also Issue 797215 , Issue 740717, http://crbug.com/424082#c69 and http://crbug.com/641726#c29 . To insert an ellipsis without breaking, there's a fair amount of backtracking. FADE_TAIL tends to perform better. There might be something particularly screwy here that we can improve upon, or something mac-specific. I'll poke around a bit. Is there a specific place where this is happening a lot that you're most concerned about? We try to cache elide results in a RenderText object. And, E.g., the bookmarks model does eliding on a background thread (which might be a bug.. I'm not sure all our codepaths are threadsafe).
,
May 31 2018
I don't see the same performance impact you're seeing versus the native typesetter. you can see the test I'm using here - https://chromium-review.googlesource.com/#/c/chromium/src/+/1080477 Typesetter::NATIVE comes about about 2x faster (~0.5ms per run rather than 1ms per run). *RESULT LabelPerfTest: ElideUnicode= 1134.8316650390625 runs/s *RESULT LabelPerfTest: ElideUnicodeNative= 2130.805908203125 runs/s I expect the bulk of the 25ms you're seeing is a font glyph lookup which gets cached after the first time it's used. There aren't really any surprises. 80% of the time is spent inside hb_shape(). On mac this calls _hb_coretext_shape which mostly falls back to CoreText to do the heavy lifting anyway. One possible avenue to explore: There are *two* calls to RenderTextHarfBuzz::ShapeRun(). Once before eliding and once after. The first is used just to determine whether we need to elide at all. Maybe one can be skipped.. This seems to be the fastpath that FADE_TAIL can already take -- since an ellipsis doesn't need to be inserted, text runs are not broken, so only one pass is needed. 4.65 s 97.7% 1.00 ms gfx::ElideText(std::__1::basic_string<unsigned short, base::string16_internals::string16_char_traits, std::__1::allocator<unsigned short> > const&, gfx::FontList const&, float, gfx::ElideBehavior, gfx::Typesetter) 3.35 s 70.2% 1.00 ms gfx::RenderText::UpdateDisplayText(float) 3.09 s 64.9% 2.00 ms gfx::RenderTextHarfBuzz::ShapeRun(std::__1::basic_string<unsigned short, base::string16_internals::string16_char_traits, std::__1::allocator<unsigned short> > const&, gfx::internal::TextRunHarfBuzz*) 2.62 s 54.9% 0 s hb_shape 1.25 s 26.1% 2.00 ms gfx::RenderTextHarfBuzz::ShapeRun(std::__1::basic_string<unsigned short, base::string16_internals::string16_char_traits, std::__1::allocator<unsigned short> > const&, gfx::internal::TextRunHarfBuzz*) 1.03 s 21.6% 0 s hb_shape Based on the above, I'm moving this to available. I don't think there's any low-hanging fruit here or new concern specific to unicode or to mac that isn't already covered by other bugs.
,
Jun 4 2018
I got the same result in LabelPerfTest above, where ElideText() with RenderTextHarfBuzz didn't show much difference. (The font glyph lookup cache might be the reason?) I am experiencing janks when I open bookmark bar and move mouse around the bookmark bar menus (with MacViewsBrowser). MenuItemView::PaintButton() takes more than 20ms every time I open the bookmark bar menus. I logged the elapsed times in MenuItemView::PaintButton() and Canvas::DrawStringRectWithFlags(): [94155:775:0529/165952.166760:INFO:menu_item_view.cc(844)] PaintButton with title: 중국 알리페이, 국내 편의점 2만곳에 모바일결제 인프라 깐다 - 대한민국 IT포털의 중심! 이티뉴스 [94155:775:0529/165952.166776:INFO:menu_item_view.cc(845)] title length: 55 [94155:775:0529/165952.166799:INFO:canvas_skia.cc(176)] Harfbuzz created: 0ms [94155:775:0529/165952.185057:INFO:canvas_skia.cc(240)] ElideTextAndAdjustRange finished: 18ms [94155:775:0529/165952.185085:INFO:canvas_skia.cc(248)] UpdateRenderText finished: 18ms [94155:775:0529/165952.188449:INFO:canvas_skia.cc(257)] render_text->Draw() finished: 21ms [94155:775:0529/165952.188505:INFO:menu_item_view.cc(973)] end: 21ms I could remove the jank by using gfx::Typesetter::NATIVE in ElideTextAndAdjustRange() of canvas_skia.cc and BookmarkBarView::CreateToolTipForURLAndTitle().
,
Jun 4 2018
Ahh, likely the real bug here is similar to Issue 740717 MenuItemView::PaintMinorIconAndText() creates a new gfx::RenderText object each time it needs to repaint (e.g. background change on hover). I think MenuItemView should retain the RenderText object created so it doesn't need to do repeated typesetting.
,
Jun 4 2018
There was no minor text when I tested this, but gfx::ElideText() also creates a new gfx::RenderText object each time.
,
Jun 5 2018
oop - yeah all the calls to DrawStringRectWithFlags will be creating fresh gfx::RenderText objects too, which can be cached instead. DrawStringRectWithFlags being slow is a common theme in the other bugs as well. I think we can attempt to deprecate DrawStringRectWithFlags. The Cocoa approach would be to use -[NSAttributedString drawInRect:] (and gfx::RenderText is basically an NSAttributedString). That is, Cocoa sorta forces you to into a pattern of keeping the typeset text around. https://developer.apple.com/documentation/foundation/nsattributedstring/1531631-drawinrect?changes=_2&language=objc
,
Jun 25 2018
Robert did some tracing in Issue 826265 , which is pointing to elide calls coming from BookmarkBarView::CreateToolTipForURLAndTitle() whilst populating a11y properties.
,
Jul 1
,
Nov 19
**UI mass Triage** We were unable to find repro steps for this bug. If you have more data to reproduce this bug or have clear repro steps, please reopen or file a new issue. Thanks!
,
Nov 19
Not sure what was "checked" here.
,
Nov 20
I think this issue can be closed now. It shows no latency on Chrome/70.0.3538.102.
,
Nov 20
Trent mentioned a few open issues about eliding performance above, it's probably safe to dup this to one of those. I'll dup to Issue 267710 for now, feel free to change as needed. |
|||||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||||
Comment 1 by sdy@chromium.org
, May 30 2018Components: UI