In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces the relevant knowledge of "what are the methods of dealing with Web Chinese fonts?" in the operation of actual cases, many people will encounter such a dilemma, and then let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Background introduction
In the Web project, using an appropriate font can bring a good experience to the user. But there are too many font files, if you want to see the font effect, you can only open them one by one, which greatly affects your work efficiency. Therefore, you need to implement a function that can preview fonts based on fixed text and user input. There are two main problems to be solved in the process of implementing this function:
The loading time is too long due to the large size of Chinese font.
The preview is not displayed until the font is loaded.
Now sum up the solution of the problem and my thinking.
Use web custom fonts
Before we talk about these two issues, let's briefly describe how to use a Web custom font. To use a custom font, you can rely on the @ font-face rule defined by CSS Fonts Module Level 3. A method that is basically compatible with all browsers is as follows:
@ font-face {font-family: "webfontFamily"; / * take any name * / src: url ('webfont.eot'); url (' web.eot?#iefix') format ("embedded-opentype"), url ("webfont.woff2") format ("woff2"), url ("webfont.woff") format ("woff"), url ("webfont.ttf") format ("truetype"); font-style:normal The name defined in font-weight:normal;} .webfont {font-family: webfontFamily; / * @ font-face * /}
Since woff2, woff, and ttf formats are already well supported in most browsers, the above code can also be written as follows:
@ font-face {font-family: "webfontFamily"; / * take any name * / src: url ("webfont.woff2") format ("woff2"), url ("webfont.woff") format ("woff"), url ("webfont.ttf") format ("truetype"); font-style:normal; font-weight:normal;}
With the @ font-face rule, we just need to upload the font source file to cdn, let the url value of the @ font-face rule be the address of the font, and finally apply this rule to the Web text to achieve the font preview effect.
But in doing so, we can obviously find that the loading time caused by the large font size is too long. Let's open the Network panel of the browser to see:
You can see that the size of the font is 5.5 MB and the loading time is 5.13 s. On the other hand, many Chinese fonts on the quark platform are between 20 and 40 MB, and it can be expected that the loading time will increase further. If the user is still in a weak network environment, this waiting time is unacceptable.
First, the large size of Chinese fonts leads to a long loading time. Analyze the reasons
Then why Chinese fonts are so large compared with English fonts are mainly due to two reasons:
Chinese fonts contain a large number of glyphs, while English fonts contain only 26 letters and some other symbols.
The lines of Chinese glyphs are much more complex than those of English glyphs, and they are used to control that Chinese glyph lines have more location points than English glyphs, so there is a larger amount of data.
With the help of opentype.js, we can count the difference between a Chinese font and an English font in the number of glyphs and the number of bytes occupied by glyphs:
Font name glyph number of bytes occupied by FZQingFSJW_Cu.ttf87314762272JDZhengHT-Bold.ttf12218328
The font preview of the quark platform needs to meet two ways, one is the fixed character preview, the other is to preview according to the characters entered by the user. However, no matter which preview method, only a small number of characters of the font will be used, so it is not necessary to load the font in full, so we need to simplify the font file.
two。 How to reduce the font file volume unicode-range
The unicode-range attribute is generally used with the @ font-face rule, which is used to control the use of specific fonts for specific characters. But it can not reduce the size of the font file, interested readers can try.
CSS unicode-range specific characters use font-face custom fonts
Fontmin
Fontmin is a font subset scheme implemented by pure JavaScript. As mentioned earlier, the reason why Chinese fonts are larger than English fonts is that they have more glyphs, so the idea to simplify a font file is to remove useless glyphs:
/ / pseudo code const text = 'font preview' const unicodes = text.split ('') .map (str = > str.charCodeAt (0)) const font = loadFont (fontPath) font.glyf = font.glyf.map (g = > {/ / get the corresponding glyph} according to unicodes)
In fact, simplification is not that simple, because a font file consists of many tables (table), and there are associations between these tables. For example, the maxp table records the number of glyphs, and the loca table stores the offset of the glyph position. At the same time, the font file starts with offset table (offset table), and offset table records the information of all font tables, so if we change the glyf table, we have to update other tables at the same time.
Before we discuss how fontmin intercepts fonts, let's take a look at the structure of font files:
The above structure is limited to cases where the font file contains only one font, and the glyph outline is based on the TrueType format (which determines the value of sfntVersion), so the offset table starts at 0 bytes of the font file. If the font file contains multiple fonts, the offset table for each font is specified in TTCHeader, which is outside the scope of the article.
Offset table (offset table):
TypeNameDescriptionuint32sfntVersion0x00010000uint16numTablesNumber of tablesuint16searchRange (Maximum power of 2 hmtx-> prep, which is not required for table data.
Inadequacies of fontmin
In the process of intercepting fonts, fonteditor-core will only process the 14 tables mentioned above, and discard the rest of the tables. Each font usually contains two tables, vhea and vmtx, which are used to control the spacing of fonts in vertical layout. If you use fontmin to intercept fonts, you will lose this information. You can see the difference when the text is displayed vertically (the right side is after interception):
How to use fontmin
After understanding the principle of fontmin, we can use it happily. After the server receives the request from the client, intercepts the font through fontmin, and fontmin returns the Buffer corresponding to the intercepted font file. Don't forget that the font path in the @ font-face rule supports base64 format, so we just need to change the Buffer to base64 format and embed it in @ font-face and return it to the client, and then the client inserts the @ font-face into the tag as CSS.
For the fixed preview content, we can also save the font file on CDN, but the disadvantage of this approach is that if the CDN is unstable, it will cause the font to fail to load. If using the above method, each intercepted font exists in the form of a base64 string, then you can do a cache on the server side, there is no problem. The code for generating a font subset using fontmin is as follows:
Const Fontmin = require ('fontmin') const Promise = require (' bluebird') async function extractFontData (fontPath) {const fontmin = new Fontmin () .src ('. / font/senty.ttf') .use (Fontmin.glyph ({text: 'font preview'})) .use (Fontmin.ttf2woff2 ()) .dest ('. / dist') await Promise.promisify (fontmin.run, {context: fontmin}) ()} extractFontData ()
For the fixed preview content, we can generate the divided font in advance, and for the dynamic preview content entered by the user, we can also follow this process:
Get input-> intercept glyph-> upload CDN-> generate @ font-face-> insert page
According to this process, the client needs to request twice to obtain font resources (don't forget to request fonts after @ font-face inserts the page), and it takes a long time to intercept glyphs and upload CDN. Is there a better way? We know that the outline of the glyph is determined by a series of location points, so we can obtain the coordinates of the location points in the glyf table and draw the specific glyph directly through the SVG image.
SVG is a powerful image format that can be interacted with using CSS and JavaScript, where the path element is mainly applied
We can use opentype.js to obtain the location information and generate the path tag. After the client gets the input glyph path element, it only needs to traverse to generate the SVG tag.
3. Advantages of reducing font file size
A comparison table of file size and loading speed after font interception is attached below. It can be seen that the loading speed of the intercepted font is 145 times faster than that of full loading.
Fontmin supports the generation of woff2 files, but the official documents have not been updated. At first, I used the woff file, but the woff2 format file is smaller and the browser supports it well.
Font name time HanyiSentyWoodcut.ttf48.2MB17.41sHanyiSentyWoodcut.woff21.7KB0.19sHanyiSentyWoodcut.woff212.2KB0.12s II, the preview content is not displayed before the font is loaded.
This is the second problem in implementing the preview function.
There are two concepts of blocking period and switching period in the font display behavior of browsers. Take Chrome as an example, there will be a period of blank space before the font is loaded, which is called the blocking period. If the loading is still not completed during the blocking period, the backup font will be displayed first, enter the exchange period, and wait for the font to be loaded and replaced. This will cause the font on the page to flash, which does not match the effect I want. And the font-display attribute controls this behavior of the browser, can we change the value of the font-display attribute to achieve our purpose?
Font-display
Block PeriodSwap PeriodblockShortInfiniteswapNoneInfinitefallbackExtremely ShortShortoptionalExtremely ShortNone
The display strategy of fonts is related to the value of font-display. The default font-display value of the browser is auto, and its behavior is similar to the value block.
The first strategy is FOIT (Flash of Invisible Text). FOIT is the default representation of browsers when loading fonts, and the rules are as mentioned earlier.
The second strategy is FOUT (Flash of Unstyled Text). FOUT instructs the browser to use the backup font until the custom font is loaded, and the corresponding value is swap.
Application of two different strategies: Google Fonts FOIT Han Yi font FOUT
In the quark project, the effect I want is that the preview is not displayed until the font is loaded, and the FOIT strategy is the closest. However, the longest time for FOIT text content to be invisible is about 3 seconds. If the user's network condition is not good, the backup font will still be displayed after 3 seconds, causing the page font to flash, so the font-display attribute does not meet the requirements.
According to the data, CSS Font Loading API also provides a solution at the JavaScript level:
FontFace 、 FontFaceSet
Take a look at their compatibility first:
It's IE,IE again. No users. No worries.
We can construct a FontFace object through the FontFace constructor:
Const fontFace = new FontFace (family, source, descriptors)
Family
Font name, specifying a name as the value of the CSS property font-family
Source
Font source, which can be a url or ArrayBuffer
Descriptors optional
Style:font-style
Weight:font-weight
Stretch:font-stretch
Display: font-display (this value can be set, but will not take effect)
Unicode-ranges of unicodeRange:@font-face rules
Variant:font-variant
FeatureSettings:font-feature-settings
After constructing a fontFace, the font is not loaded, and the load method of the fontFace must be executed. The load method returns a resolve value of promise,promise, which is the font after the load is successful. But just loading successfully will not make the font effective, you also need to add the returned fontFace to the fontFaceSet.
The method of use is as follows:
/ * * @ param {string} path font file path * / async function loadFont (path) {const fontFaceSet = document.fonts const fontFace = await new FontFace ('fontFamily', `url (' ${path}') format ('woff2') `) .load () fontFaceSet.add (fontFace)}
Therefore, on the client side, we can first set the CSS of the text content to opacity: 0, wait for the execution of await loadFont (path), and then set the CSS to opacity: 1, so that we can control that the content is not displayed until the custom font is loaded.
This is the end of the content of "what are the methods of dealing with Web Chinese fonts". Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 282
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.