Closed jauyong closed 4 years ago
@jauyong Let's make sure this gets triaged tomorrow.
/cc @pbakaus we need to triage it asap.
@spacedmonkey Tagging you here since you made a discovery on potential implementation for font preview at some point, in case you still have it documented somewhere.
Instead of SVGs I recommend we try out creating a single preview stylesheet with all the fonts. I put together this small prototype: https://jsbin.com/bibabex/edit?html,js,output.
What it does is:
https://fonts.googleapis.com/css2?family=Architects+Daughter&display=swap&text=Architects+Daughter
data:base64:
URL.The benefits:
The negatives:
/cc @swissspidy @pbakaus
@dvoytenko I think we should try this!
One more optimization is to skip the base64 step and concat the binary woff/woff2 files into a single binary that we then split again based on some safe byte delimiter.
I'm fairly concerned about the memory overhead of having hundreds of fonts, albeit tiny, loaded into the editor at the same time, but we should try it out and see how it performs.
That's sounds cool! I will create a draft PR for this one, so we can see how it performs
We can even make the single stylesheet with inlined base64'd woff files in the github action run on a recurring basis. And if we want to be extra crazy, we can put it in CDN rather than keep it locally. Either way, it's a single stylesheet import done conditionally in the client once the user interacts with the font dropdown the first time. And we can display a loader there (or use straight-up code-splitting and use React Suspense).
Actually it would be cool, if gfonts simply provided such a stylesheet - a stylesheet with an @font-face for each font with only the glyphs for naming said font in there.
Another thing: Do we know what to do about illegible fonts? I suppose there are some dingbats in there - or at least some really obscure fonts where you can't read the letters easily?
@ndev1991, @barklund, @pbakaus
I just prototyped it in JS because that's what I know. But this is definitely the server-side-job task. We should just add it to our job that generates fonts.json and produce a "fonts-preview.css" at the same time.
Actually it would be cool, if gfonts simply provided such a stylesheet - a stylesheet with an @font-face for each font with only the glyphs for naming said font in there.
That'd be great, but I couldn't find anything like this. Doesn't mean it doesn't exist, so we should definitely search.
Another thing: Do we know what to do about illegible fonts? I suppose there are some dingbats in there - or at least some really obscure fonts where you can't read the letters easily?
We just should provide an alternative string for display. And we'll have to display it like <span style="normalFont">{fontName}</span><span style="previewFont">{previewText}</span>
. Wheres, for most of fonts previewText == fontName
and thus only one is needed.
One more optimization is to skip the base64 step and concat the binary woff/woff2 files into a single binary that we then split again based on some safe byte delimiter.
I thought about this some more and I think we should first try base64. We basically have a trade-off between network size and CPU in the main thread. If we put a prepared stylesheet with base64, it will prescanned and ready to go w/o the main thread intervention at all. And we still have tools available to us to optimize:
But I'd really just start with base64 + compression first. And see how that behaves.
However, what this points to, is that we need to change how we render our font previews. The most important optimization that's given us by browser: even if the font-face is declared, the font binary itself is not loaded until a content using it is display. What it means for us is that we definitely would want our font preview list to either render previews with display:none
or not render them at all and leave blanks. When the user scrolls to a group of previews (or close to them) we would flip display to non-none or render them. I.e. this is a form of virtual scrolling. This will gives us the biggest improvement for CPU and memory. And if we later implement (2) and/or (3) it will even be even better.
You can use https://developers.google.com/fonts/docs/getting_started#optimizing_your_font_requests to get fonts subsetted to only the characters you need, and https://developers.google.com/fonts/docs/developer_api to get a list of the public library :)
You can use https://developers.google.com/fonts/docs/getting_started#optimizing_your_font_requests to get fonts subsetted to only the characters you need, and https://developers.google.com/fonts/docs/developer_api to get a list of the public library :)
thanks @davelab6! These are very helpful, and we're already using both :) Our concrete questions is more around how to render a preview of all fonts in a way that isn't super slow to load or crashes the browser...we have a few options:
Any thoughts on that?
@pbakaus you don't need to load them all, you only need to load the visible ones, and load more as user scrolls and reveals more (that's the wat the catalog at fonts.google.com works) - the subsetted requests are very fast.
@tomasdev that's great to hear, thanks for the confirmation that that strategy works! OK, we'll focus on a virtual scroller then, which will dynamically load the current set of fonts when they're visible.
Ok. It all points to this:
Ok. It all points to this:
- We have several good ways to get minimal menu fonts efficiently.
- As the first priority we need to focus on virtualizing the font picker to ensure we only ask for menu fonts as we need them.
@dvoytenko when we meaning the menu fonts, visible fonts on dropdown? If we have 8 font families available once, we need to call maybe 16 fonts above 4 and bottom 4 additionally to make it smooth?
Yes. Apparently Google Fonts call this feature "menu fonts". You can load menu fonts like this:
https://fonts.googleapis.com/css?family=Roboto%7COpen+Sans&subset=menu
It's automatic and precached. So it should be pretty optimal. Though if we don't like the performance, we still have the same option of stitching it via base64.
There is features on fontpicker like popular fonts and suggested ones that used recently. Any ideas how we can fetch popular fonts? And how we can solve the suggested ones that used recently. Do we need to have them on db or just fonts that used for that story?
I looked into generating SVG previews of all the fonts. It wasn't something easy to do in the browser ( on the fly ) as I recall. Which left two options.
Those are the options I went down with font preview. If it is not clear, i think option 2 is better idea of the 2. Makes it easier to follow for custom font support later.
I would be very interested to know what the google docs team does.
Google Docs and Google Fonts essentially use https://fonts.googleapis.com/css?family=Roboto%7COpen+Sans&subset=menu.
As an editor I want to be able to preview fonts in the font picker
Acceptance Criteria
See #30
Design