我正尝试根据Chrome Lighthouse审核报告的建议,将prefetch
指令与我的字体一起使用。但是,这样做会引发以下错误:
未捕获(承诺)错误:超过3000毫秒超时
我的堆栈涉及用于SSR的NextJS。我的 index.jsx 看起来像这样:
import React, { PureComponent, Fragment } from 'react';
import Typography from '@material-ui/core/Typography';
import { withStyles } from '@material-ui/core/styles';
import Head from 'next/head';
import Link from 'next/link';
import withRoot from '../lib/withRoot';
import Fonts from '../lib/Fonts'
const styles = theme => ({
root: {
textAlign: 'center',
paddingTop: theme.spacing.unit * 20,
},
paragraph: {
fontFamily: 'Oswald',
}
});
class Index extends PureComponent {
constructor(props) {
super(props);
this.state = {
open: false,
};
}
componentDidMount() {
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/serviceWorker.js'); }
Fonts();
}
render() {
const { classes } = this.props;
const { open } = this.state; // eslint-disable-line no-unused-vars
const title = 'Home';
const description = 'This is the description for the homepage';
return (
<Fragment>
<Head>
<title>{ title }</title>
<meta name="description" content={description} key="description" />
</Head>
<div className={classes.root}>
<Typography gutterBottom>
<Link href="/blog">
<a>View posts page</a>
</Link>
</Typography>
</div>
<p className={classes.paragraph}>All men must die</p>
</Fragment>
);
}
}
export default withRoot(withStyles(styles)(Index));
Fonts.js 看起来像这样:
const FontFaceObserver = require('fontfaceobserver');
const addFont = (fontUrl) => {
const fontName = fontUrl.split('=')[1].split(':')[0].split('&')[0];
const fontNameWithSpace = fontName.replace(/\+/g, ' ');
const link = document.createElement('link');
link.href = fontUrl;
link.rel = 'stylesheet';
document.head.appendChild(link);
const addedFont = new FontFaceObserver(fontNameWithSpace);
addedFont.load().then(() => {
document.documentElement.classList.add(fontName);
});
};
const Fonts = () => {
// Oswald
addFont('https://fonts.googleapis.com/css?family=Oswald:400,500,600,700&display=swap');
// Roboto
addFont('https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap');
// Source Sans Pro
addFont('https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600&display=swap');
};
export default Fonts;
如您所见,我仅通过 componentDidMount()在浏览器上运行 Fonts()方法。怎么了?
答案 0 :(得分:1)
FontFaceObserver负载有一些额外的参数,
* Starts observing the loading of the specified font. Immediately returns a new Promise that resolves when the font is available and rejected when the font is not available.
* @param testString If your font doesn't contain latin characters you can pass a custom test string.
* @param timeout The default timeout for giving up on font loading is 3 seconds. You can increase or decrease this by passing a number of milliseconds.
*/
load(testString?: string | null, timeout?: number): Promise<void>;
有些人在这里有相同的问题:
Prefetch and slow connections causes Uncaught (in promise)
/ promise rejected error
在您的情况下,只需为您的负载承诺增加一些时间:
// null for testString parameter
addedFont.load(null,5000).then(() => {
document.documentElement.classList.add(fontName);
});