m00*_*m00 12 reactjs server-side-rendering styled-components next.js vercel
我正在使用 next.js 样式组件的全局样式,每次我重新加载我的页面时,我都能看到字体闪烁。
我有我的字体文件 public/fonts/Inconsolata
我在频谱聊天中到处寻找,next.js github问题,但似乎找不到任何解决方案。
页面/index.js
import styled from 'styled-components';
const H1 = styled.h1`
font-family: 'Inconsolata Bold';
font-weight: 700;
color: #000;
`;
const index = () => {
return (
<div>
<H1>font flashes</H1>
</div>
);
};
export default index;
Run Code Online (Sandbox Code Playgroud)
页面/_app.js
import App from 'next/app';
import React from 'react';
import GlobalStyle from '../src/style/globalStyle';
export default class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
return (
<>
<GlobalStyle />
<Component {...pageProps} />
</>
);
}
}
Run Code Online (Sandbox Code Playgroud)
页面/_document.js
import Document from 'next/document';
import { ServerStyleSheet } from 'styled-components';
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
)
};
} finally {
sheet.seal();
}
}
}
Run Code Online (Sandbox Code Playgroud)
样式/globalStyle.js
import { createGlobalStyle } from 'styled-components';
const globalStyle = createGlobalStyle`
@font-face {
font-family: 'Inconsolata';
src: url('./fonts/Inconsolata/Inconsolata-Regular.woff2') format('woff2'),
url('./fonts/Inconsolata/Inconsolata-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
font-display: fallback;
}
@font-face {
font-family: 'Inconsolata Bold';
src: url('./fonts/Inconsolata/Inconsolata-Bold.woff2') format('woff2'),
url('./fonts/Inconsolata/Inconsolata-Bold.woff') format('woff');
font-weight: 700;
font-style: bold;
font-display: fallback;
}
`;
export default globalStyle;
Run Code Online (Sandbox Code Playgroud)
我在使用 NextJS 12、Google Fonts 和 SCSS 模块时也遇到了类似的问题。
我的部分解决方案是
@font-face- 更急切地加载字体font-display: optional- 告诉 CSS 在字体未及时加载时使用后备这意味着没有 Flash Of Unstyled Text (FOUT),但在较慢的连接上,首次加载时将使用后备字体。
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preload"
href="https://fonts.gstatic.com/s/inconsolata/v21/QlddNThLqRwH-OJ1UHjlKENVzkWGVkL3GZQmAwLyya15IDhunA.woff2"
as="font"
type="font/woff2"
crossOrigin=""
/>
<link
rel="preload"
href="https://fonts.gstatic.com/s/inconsolata/v21/QlddNThLqRwH-OJ1UHjlKENVzkWGVkL3GZQmAwLyx615IDhunJ_o.woff2"
as="font"
type="font/woff2"
crossOrigin=""
/>
// CSS file with @font-face rules and font-display: optional
<link
href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@300;400;700&display=optional"
rel="stylesheet"
/>
</head>
Run Code Online (Sandbox Code Playgroud)
在此示例中,最后一个link元素请求一个 CSS 文件,该文件包含许多带有声明和值的@font-face规则。srcurl()
如果函数中的资源url()没有预加载到 head 中,那么在解析 CSS 之前不会请求它们。
我认为这就是导致 FOUT 的原因。
通过包含<link rel="preload" src="..."/>元素,可以更快地加载字体。
并且设置font-display: optional告诉浏览器如果字体没有及时加载则使用后备。
我正在开发的网站:Soundboard
更新:
Next.js 发布了一项名为Automatic Webfont Optimization的新功能。
只需包含您的字体(目前仅适用于 Google 字体),它将在构建时作为原始 css 包含在内。
// Before
<link
href="https://fonts.googleapis.com/css2?family=Inter"
rel="stylesheet"
/>
// After
<style data-href="https://fonts.googleapis.com/css2?family=Inter">
@font-face{font-family:'Inter';font-style:normal.....
</style>
Run Code Online (Sandbox Code Playgroud)
查看 Next.js 人员如何在他们的网站上处理它,该网站是开源的,可以在这里找到。检查一下,它对我有用。
通过预加载链接在 css @font-face 中导入您使用的字体
<link
rel="preload"
href="/assets/my-font.woff2"
as="font"
type="font/woff2"
/>
Run Code Online (Sandbox Code Playgroud)
您的字体声明应该在 SSR HTML 页面上,因此请使用<style jsx global />将其包含在您的页面中。它可以是外部文件或直接在style元素中。
| 归档时间: |
|
| 查看次数: |
3660 次 |
| 最近记录: |