Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@wangying3426
Copy link
Contributor

@wangying3426 wangying3426 commented Oct 21, 2019

We found that it cost a very long time to measure a Chinese paragraph for Text Widget. As the picture shown, the Layout::measureText function takes more than 400ms.

download1

The reason we discovered is that it will search the best-matched font-family in the Layout::measureText function for each Chinese character. If not matched, it will search the fallback font-family, however, this process is time consuming, especially for a very long paragraph.

Therefore, we cached the fallback font-family for reuse, and the same length text only cost 8ms.

download2

At last, here is a case:

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  String longText = 'Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。毫秒级的热重载,修改后,您的应用界面会立即更新。使用丰富的、完全可定制的widget在几分钟内构建原生界面。快速发布聚焦于原生体验的功能。分层的架构允许您完全自定义,从而实现难以置信的快速渲染和富有表现力、灵活的设计。Flutter包含了许多核心的widget,如滚动、导航、图标和字体等,这些都可以在iOS和Android上达到原生应用一样的性能。Flutter的热重载可帮助您快速地进行测试、构建UI、添加功能并更快地修复错误。在iOS和Android模拟器或真机上可以在亚秒内重载,并且不会丢失状态。Flutter拥有丰富的工具和库,可以帮助您轻松地同时在iOS和Android系统中实现您的想法和创意。 如果您没有任何移动端开发体验,Flutter是一种轻松快捷的方式来构建漂亮的移动应用程序。 如果您是一位经验丰富的iOS或Android开发人员,则可以使用Flutter作为视图(View)层, 并可以使用已经用Java / ObjC / Swift完成的部分(Flutter支持混合开发)。路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewController。所谓路由管理,就是管理页面之间如何跳转,通常也可被称为导航管理。Flutter中的路由管理和原生开发类似,无论是Android还是iOS,导航管理都会维护一个路由栈,路由入栈(push)操作对应打开一个新页面,路由出栈(pop)操作对应页面关闭操作,而路由管理主要是指如何来管理路由栈。';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            children: <Widget>[
              Text(longText, maxLines: 4)
            ],
          ),
        ),
      ),
    );
  }
}

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

1 similar comment
@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@wangying3426
Copy link
Contributor Author

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.

What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@googlebot I signed it!

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

1 similar comment
@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@wangying3426 wangying3426 changed the title Fix: Load fallback font-family performance problem Fix load fallback font-family performance problem Oct 21, 2019
@wangying3426 wangying3426 changed the title Fix load fallback font-family performance problem Optimize loading fallback font-family performance Oct 24, 2019
Copy link
Member

@jason-simmons jason-simmons left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!

uint32_t FontCollection::sNextId = 0;

const uint32_t kMinFallbackScore = 0x20000000;
std::vector<std::shared_ptr<FontFamily>> sFallbackFamilies;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a member of the FontCollection class instead of a global. The member will need to be mutable because FontCollection::getFamilyForChar is const.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a unclear to me exactly why this is called sFallbackFamilies, maybe consider a more descriptive name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a unclear to me exactly why this is called sFallbackFamilies, maybe consider a more descriptive name?

@GaryQian What's your suggested name?


uint32_t FontCollection::sNextId = 0;

const uint32_t kMinFallbackScore = 0x20000000;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace the calcFamilyScore >= kMinFallbackScore checks with a call to calcCoverageScore.

calcFamilyScore is a combination of calcCoverageScore and some other scores. If calcCoverageScore returns a nonzero result, then that is equivalent to calcFamilyScore returning a score >= 0x20000000.

uint32_t langListId,
int variant) const {
if (ch >= mMaxChar) {
for (size_t i = 0; i < sFallbackFamilies.size(); i++) {
Copy link
Contributor

@GaryQian GaryQian Oct 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(optional) Since this is identical to the snippet below (line 355), consider using helper function to help keep these two sections in sync.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, since it would be helpful to have a short comment explaining why this is necessary.

@cbracken
Copy link
Member

@wangying3426 are you planning to follow-up on the changes requested by @jason-simmons and @GaryQian?

@wangying3426
Copy link
Contributor Author

@wangying3426 are you planning to follow-up on the changes requested by @jason-simmons and @GaryQian?

OK,I will improve it soon.

jason-simmons added a commit to jason-simmons/flutter_engine that referenced this pull request Dec 13, 2019
If a new fallback font is discovered during paragraph layout, the fallback
font cache in txt::FontCollection will use that font in future layouts.

However, that cache is not available if the new fallback font needs to be
used for other characters within the current layout.  This PR adds a cache
to minikin::FontCollection and checks whether fonts in the cache can handle
a character before calling the fallback font provider.

See flutter#13257
jason-simmons added a commit to jason-simmons/flutter_engine that referenced this pull request Dec 13, 2019
If a new fallback font is discovered during paragraph layout, the fallback
font cache in txt::FontCollection will use that font in future layouts.

However, that cache is not available if the new fallback font needs to be
used for other characters within the current layout.  This PR adds a cache
to minikin::FontCollection and checks whether fonts in the cache can handle
a character before calling the fallback font provider.

See flutter#13257
jason-simmons added a commit that referenced this pull request Dec 13, 2019
If a new fallback font is discovered during paragraph layout, the fallback
font cache in txt::FontCollection will use that font in future layouts.

However, that cache is not available if the new fallback font needs to be
used for other characters within the current layout.  This PR adds a cache
to minikin::FontCollection and checks whether fonts in the cache can handle
a character before calling the fallback font provider.

See #13257
@wangying3426
Copy link
Contributor Author

@jason-simmons has solved this problem, see #14482 , so I will close this PR.

filmil pushed a commit to filmil/engine that referenced this pull request Mar 13, 2020
…ter#14482)

If a new fallback font is discovered during paragraph layout, the fallback
font cache in txt::FontCollection will use that font in future layouts.

However, that cache is not available if the new fallback font needs to be
used for other characters within the current layout.  This PR adds a cache
to minikin::FontCollection and checks whether fonts in the cache can handle
a character before calling the fallback font provider.

See flutter#13257
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants