【问题标题】:Prefetch works but throws an "uncaught (in promise) error"预取有效,但引发“未捕获(承诺)错误”
【发布时间】:2019-07-16 06:53:33
【问题描述】:

我正在尝试按照 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() 方法。怎么了?

【问题讨论】:

    标签: reactjs next.js preconnect


    【解决方案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);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 2020-01-21
      • 2022-12-19
      • 2019-04-17
      • 2021-11-28
      • 2018-05-12
      相关资源
      最近更新 更多