-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve loading times for maps with CJK text #3466
Comments
Does this resolve the same problem? #395 |
@huangyingjie yes, and it's tracked in mapbox/node-fontnik#36. We should definitely pick this up again. |
I think there two possible ways to ameliorate the problem with CJK glyph:
|
This may reduce the total data downloaded slightly but would likely increase HTTP request overhead and doesn't really address the underlying issue.
I tried doing this a while back without much success, building a set of frequently used glyphs to always be loaded initially based on names in OpenStreetMap data, then loading other ranges on demand. The problem was that there's such a long tail of uncommonly used glyphs that loading a typical map view will still grab many disparate glyph ranges even after preloading a common set of ~4096 glyphs. I even tried building a single range of all necessary glyphs based on OSM data, but this was incredibly fragile and even slight changes to the underlying data caused many additional glyph range requests. I think the most promising approach here would be to completely scrap the concept of glyph "ranges" for ideographic scripts, as they don't provide the benefits seen in syllabic scripts (where only a few ranges are necessary to render all labels in a given script). Instead, we could dynamically request only the glyphs needed to initially render a map view, and request subsequent glyphs in batches as necessary when the view changes. We'd have to weigh the backend performance impact here of potentially losing an HTTP caching layer, unless this is somewhere we could take advantage of HTTP/2 pipelining when requesting individual glyphs instead of combining them dynamically on a server. ^ @huangyingjie @jingsam I'm interested in hearing your perspectives on whether the approach I suggested sounds promising, as I'm primarily approaching this issue through an engineering/analytical lense rather than an a linguistic understanding. Let's track further discussion on this topic over in mapbox/node-fontnik#36. |
Hey everyone! I built a new tiny library that can generate an SDF using system fonts and Canvas 2D on the fly: https://mapbox.github.io/tiny-sdf/ I'll be experimenting with integrating it into GL JS to be used for CJK text so that CJK glyph pbf downloads can be avoided entirely. There will be drawbacks like getting small stuttering on tile loads (because of Canvas text rendering on the main thread), and worse font rendering quality (because SDFs would be generated from a small bitmap rather than an exact letter geometry). But this is probably still better than waiting for a 10+ MB glyph download for a single map screen — especially with slow internet speeds in China, like #3748 where user waited 4 minutes for the map to load on a 50kb/s connection. cc @jfirebaugh @yhahn @kkaefer @mikemorris @itcongaili |
Wow, this will be huge (err, tiny) for many CJK use cases. There are still some thorny questions to work out – what else is new in CJK? – but hopefully we can come up satisfactory answers to take advantage of the work you’ve done. Will the style designer retain any control over the font face? Will we generate the SDF based on the default font, or will we insist on a pan-Unicode font named in the font stack, like Arial Unicode MS? (Seems like TinySDF would be compatible with either approach.) Han unification means that the same Unicode codepoint may be used for five distinctly shaped glyphs, one per language. Unicode relies on language-specific fonts to render the right shape. There can also be significant differences among the various script styles and therefore among the various system fonts for a given language. If the designer sees a gothic (sans-serif) font in Studio, they may be inclined to set it at a size that becomes illegible on a system that defaults to a Mingti (serif) or Songti font. The designer may also want to vary typefaces the same way Western labels may be set in roman or italics. Will there be any affordance for fonts that don’t fit a square grid perfectly? Some system CJK fonts, like SimLi, are patterned on a rectangular grid. |
@huangyingjie Did you solve the problem? |
@bearnxx Yes, I build a dynamic server to produce pbfs. |
@huangyingjie 可以告诉我具体怎么解决这个问题吗? (Google Translate: "Can you tell me how to solve this problem?") |
@JunYanchan Splitting the |
@huangyingjie感谢你的回复,可以详细加我QQ(494584784)聊聊吗?因为这样说 好像还是有点模糊哦 (Google Translate: "Let's talk on QQ talk") |
@huangyingjie Where did you download the.ttf file? |
Hey everyone, we have some great progress on this issue in PR #4895 — please check it out! Feedback welcome. |
#4895 gives the style designer no control over the font face, although apparently a developer using GL JS does retain the ability to specify fonts via the
@ChrisLoer and I brainstormed on some approaches to solving this issue, although it probably remains outside the scope of #4895:
|
@JunYanchan @huangyingjie @bearnxx We've merged PR #4895 into master, so it's now possible to set up a set of local font "overrides" to use for generating CJK glyphs instead of fetching them from the server. You can see an example that shows two maps before and after the override at https://github.com/mapbox/mapbox-gl-js/blob/master/debug/tinysdf.html. For a live demo without any set up on your part, see https://chrisloer.github.io/tiny-sdf/index.html. We plan to keep making improvements to our CJK support, but we're counting on feedback from Mapbox users like you who are actually developing Chinese maps. If you could try out the changes, it would help us a lot.
谢谢! |
Wow, this really was a big improvement which incline to the rule of css fonts. Designers have choices of the level controlling on the map visual styles. If designers want to keep identical map styles, just use online fonts; otherwise they think some fonts are not matters, use local fonts. I'm wandering when this feature comes to mapbox-gl-native? |
Thank you very much, I have tried to use this method, and really load a lot faster, and now the map load 1MB + on it, in fact, our company designers on the font is not particularly large requirements, can reference the local font is enough. |
@jingsam and @JunYanchan Thank you! I am currently investigating doing something similar on Android. Every platform (Web/Android/iOS/Qt/etc.) handles fonts differently, so we will have to develop solutions one at a time. |
@ChrisLoer Really awesome, unbelievable improvement.
|
@ChrisLoer I find that only CJK will rendered by local fonts, any other glyphs in range: 0-255、65024-65279 are still fetched from remote server. |
@huangyingjie The current approach relies on all of the locally rendered glyphs having a glyph "advance" of "1 em". This assumption works for CJK ideographs, but the assumption doesn't work for glyphs in many other writing systems (including the glyphs in the 0-255 range). Because the browser doesn't tell us how wide each glyph is, and because we don't completely control which font the browser uses to render the glyph, we can't reliably guess the glyph advance. If we don't get the glyph advances right, labels will end up looking broken. So for now, the answer is "no, we can't render all glyphs locally", although we'll keep looking at alternative solutions. |
@jingsam We're working on a gl-native port right now, you can watch the progress at mapbox/mapbox-gl-native#10522, and if you want to try using those builds locally feel free to comment on that PR asking for guidance. |
I guess this issue can be safely closed as done for GL JS? |
Motivation
I need a new feature that used to reduce glyphs pbf size.
When using Chinese with mapbox-gl-js in browser, it always download too many font pbfs that are too large(each 100Kb+, nearly 8M total in Beijing). This made me waiting over 10s for map initialization.
When the language is English, the problem disappear, because it downloads very few pbfs.
I knew
?optimize=true
, but this cannot help reducing font size.@xrwang
The text was updated successfully, but these errors were encountered: