MST

星途 面试题库

面试题:Next.js在SSR场景下字体文件的加载优化

在Next.js的服务器端渲染(SSR)应用中,字体文件加载可能会影响性能。阐述你会采取哪些策略来优化字体文件的加载,例如如何防止FOUT(Flash of Unstyled Text)现象,如何配置Webpack来优化字体文件打包,以及如何利用Next.js的特定功能来提升加载效率。
44.4万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

防止FOUT现象

  1. 使用 @font - face 并设置 font - display: 在CSS中通过@font - face规则定义字体,并设置font - display属性。例如:
@font - face {
  font - family: 'MyFont';
  src: url('/fonts/myfont.woff2') format('woff2'),
       url('/fonts/myfont.woff') format('woff');
  font - display: swap;
}

font - display: swap 会让浏览器尽快显示文本,使用系统字体,一旦字体加载完成就替换为自定义字体,从而避免FOUT。

  1. 预加载字体: 在HTML的<head>标签中使用<link rel="preload"> 来预加载字体文件。例如:
<link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin>

crossorigin属性用于处理跨域字体,确保预加载能够正常工作。

配置Webpack优化字体文件打包

  1. 使用 url - loader 或 file - loader: 在Webpack配置中,可以使用url - loader(它基于file - loader)来处理字体文件。例如:
module.exports = {
  module: {
    rules: [
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'fonts/[name][ext]'
        }
      }
    ]
  }
};

asset/resource 类型会将字体文件输出为单独的文件,并在生成的HTML或CSS中引用。generator.filename指定了字体文件的输出路径。

  1. 压缩字体文件: 可以使用terser - webpack - plugin 等插件对字体文件进行压缩,减少文件大小,提高加载速度。在Webpack配置中添加:
const TerserPlugin = require('terser - webpack - plugin');
module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        // 配置相关压缩选项
      })
    ]
  }
};

利用Next.js特定功能提升加载效率

  1. Next.js 12+ 的 Image 优化功能类比: Next.js 12及以上版本对图片有强大的优化功能。虽然字体文件不能直接使用next/image,但思路类似。可以将字体文件放在public目录下,通过相对路径引用,利用Next.js的静态文件服务优化加载。

  2. 自定义 _document.js: 在Next.js中,可以通过自定义_document.js文件来控制页面的HTML结构。在这个文件中,可以添加预加载字体的<link>标签,确保字体在页面渲染前就开始加载。例如:

import Document, { Html, Head, Main, NextScript } from 'next/document';

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          <link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;
  1. 利用 Next.js 的 Incremental Static Regeneration: 如果字体文件不经常变化,可以利用Incremental Static Regeneration。在页面组件中设置revalidate时间,Next.js会在指定时间后重新生成静态页面,确保字体文件更新后能及时反映。例如:
export async function getStaticProps() {
  return {
    props: {},
    revalidate: 60 * 60 * 24 // 一天更新一次
  };
}