使用 Next.js 进行动态导入和代码拆分

在生产环境中优化性能有时可能是一项艰巨的任务。微调网站性能不容忽视,因为缺点会导致网页速度慢且用户体验不佳。这些网站往往加载缓慢,图像呈现缓慢,从长远来看,会导致网站访问者的跳出率增加,因为大多数用户不愿意等待内容弹出。

在本教程中,我们将介绍在 Next.js 应用程序中提高站点性能的不同模式。

目标和先决条件

在本文的最后,读者将清楚地了解如何在 Next.js Web 应用程序中最大限度地提高性能。我们将介绍以下内容:

  • 什么是动态导入和代码拆分?

  • 动态导入与静态导入有何不同?

  • Next.js 中动态导入的好处

  • 在 Next.js 中实现动态导入和代码拆分

    • 动态导入命名导出

    • 动态导入多个组件

  • 客户端渲染的动态导入

    • 库的动态导入

要阅读本文,需要先了解 Next.js 框架。

什么是动态导入和代码拆分?

动态导入,也称为代码拆分,是指将 JavaScript 代码包分成更小的块的做法,然后将它们拼凑在一起并加载到应用程序的运行时中,作为大幅提高网站性能的一种手段。

它是作为 JavaScript 中静态导入的升级而开发的,这是使用导入语法在 JavaScript 模块的顶层添加模块或组件的导入的标准方法。

虽然这是一种常用的方法,但在性能优化方面存在一些缺点,尤其是在以下情况下:

  • 大型代码库,这会创建更大的包大小并导致加载时间更长,因为构建过程会将所有需要的文件编译到单个包中

  • 需要某些用户操作的网页,例如单击导航菜单项以触发页面加载。此处,仅当满足导航条件时才会呈现所需页面,并且在静态导入组件时可能会触发缓慢的初始页面加载

动态导入与静态导入有何不同?

与静态导入不同,动态导入通过应用称为代码拆分的方法来工作。代码拆分是将代码分成不同的包,这些包使用树形格式并行排列,其中模块是动态加载的——这些模块仅在需要时才导入并包含在 JavaScript 包中。代码分割得越多,包越小,页面加载速度越快。

此方法创建多个在网页运行时动态加载的捆绑包。动态导入使用编写为内联函数调用的导入语句。

让我们看一个比较。假设我们希望在我们的应用程序中导入一个导航组件;导航组件的静态和动态导入示例如下所示:

静态导入:

import Nav from './components/Nav'
export default function Home() {
  return (
    <div>
      <Nav/>
    </div>
  )
}

动态导入:

import dynamic from "next/dynamic";
import { Suspense } from "react";
export default function Home() {
  const Navigation = dynamic(() => import("./components/Nav.js"), {
    suspense: true,
  });
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <Navigation />
      </Suspense>
    </div>
  );
}

在这里,导航组件的相关部分在import()块中指定。请注意,next/dynamic不允许在参数中使用模板文字或变量import()。

此外,react/suspense有一个指定的后备元素,在导入的组件可用之前一直显示。

Next.js 中动态导入的好处

通过实施动态导入来优化站点性能,反过来会带来以下站点优势:

  • 更快的页面加载:网站加载和显示内容的速度至关重要,因为您的受众希望快速完成工作并且不会停留在缓慢的网页上

    • 动态导入也对图像加载时间产生积极影响

  • 低跳出率:跳出率是指用户在不与网站交互的情况下退出您的网页的速率,通常表明(并且是由)缓慢的加载时间造成的。较低的跳出率通常意味着更快的网站性能

  • 改进的站点交互时间:这涉及 TTI 或交互时间,即用户请求操作与用户获得结果之间的时间间隔。这些交互可以包括点击链接、滚动页面、在搜索字段中输入输入、将商品添加到购物车等。

  • 更好的网站转化率:随着越来越多的用户从使用经过优化的网站中获得满足感,他们将更有可能进行转化

有了所有这些好处,您可能正在考虑如何在您的应用程序中使用动态导入。那么,最大的问题是,我们如何在 Next.js 应用程序中实现动态导入和代码拆分?下一部分显示了有关如何实现此目的的详细步骤。

在 Next.js 中实现动态导入和代码拆分

Next.js 通过该模块可以轻松地在 Next 应用程序中创建动态导入next/dynamic,如上所示。该next/dynamic模块实现了 React 组件的延迟加载导入,并基于React Lazy构建。

它还利用React Suspense 库来允许应用程序在需要时推迟加载组件,从而由于更轻的 JavaScript 构建而提高了初始加载性能。

动态导入命名导出

在本文前面,我们演示了使用next/dynamic. 但我们也可以对从另一个文件导出的函数或方法进行动态导入。这证明如下:

import React from 'react'
​
export function SayWelcome() {
  return (
    <div>Welcome to my application</div>
  )
}
const SayHello = () => {
  return (
    <div>SayHello</div>
  )
}
export default SayHello

在上面的代码中,我们有一个组件 ,SayHello和一个命名的导入,SayWelcome。我们可以只对SayWelcome方法进行动态显式导入,如下所示:

import dynamic from "next/dynamic";
import { Suspense } from "react";
export default function Home() {
  const SayWelcome = dynamic(
    () => import("./components/SayHello").then((res) => res.SayWelcome)
  );
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <SayWelcome />
      </Suspense>
    </div>
  );
}

上面的代码导入SayHello组件,然后SayWelcome从响应中返回导出。

免费追书VIP版App,没广告打扰支持小说下载,书源覆盖全网!

动态导入多个组件

假设我们有UserDetails和UserImage组件。我们可以按如下方式导入和显示这两个组件:

import dynamic from 'next/dynamic'
​
const details = dynamic(() => import('./components/UserDetails'))
const image = dynamic(() => import('./components/UserImage'))
​
function UserAccount() {
  return (
    <div>
      <h1>Profile Page</h1>
      <details />
      <image />
    </div>
  )
}
​
const App = () => {
  return (
    <>
      <UserAccount />
  )
    </>
}
​
export default App

UserDetails在上面的代码中,我们为和组件添加了动态导入UserImage,然后我们将这些组件组合成一个组件,UserAccount. 最后,我们UserAccount在应用程序中返回了组件。

客户端渲染的动态导入

使用该next/dynamic模块,我们还可以禁用导入组件的服务器端渲染,并在客户端渲染这些组件。这特别适用于不需要太多用户交互或具有外部依赖关系的组件,例如 API。这可以通过在导入组件时将ssr属性设置为来完成:false

import dynamic from 'next/dynamic'
​
const HeroItem = dynamic(() => import('../components/HeroItem'), {
  ssr: false,
})
​
const App = () => {
  return (
    <>
      <HeroItem />
  )
    </>
}

在这里,HeroItem组件将服务器端呈现设置为false,因此它改为在客户端呈现。

库的动态导入

除了导入本地组件,我们还可以为外部依赖添加动态导入。

例如,假设我们希望在用户请求时使用 Axiosfetch从 API 获取数据。我们可以为它定义一个动态导入Axios并实现它,如下所示:

import styles from "../styles/Home.module.css";
import { React, useState } from "react";
​
export default function Home() {
  const [search, setSearch] = useState("");
  let [response, setResponse] = useState([]);
  const api_url = `https://api.github.com/search/users?q=${search}&per_page=5`;
​
  return (
    <div className={styles.main}>
      <input
        type="text"
        placeholder="Search Github Users"
        value={search}
        onChange={(e) => setSearch(e.target.value)}
      />
​
      <button
        onClick={async () => {
          // dynamically load the axios dependency
          const axios = (await import("axios")).default;
          const res = await axios.get(api_url).then((res) => {
            setResponse(res);
          });
​
        }}
      >
        Search for GitHub users
      </button>
​
      <div>
        <h1>{search} Results</h1>
        <ul>
          {response?.data ? (
            response && response?.data.items.map((item, index) => (
              <span key={index}>
                <p>{item.login}</p>
              </span>
            ))
          ) : (
            <p>No Results</p>
          )}
        </ul>
      </div>
    </div>
  );
}

在上面的代码中,我们有一个用于在 GitHub 上搜索用户名的输入字段。我们使用useState()Hook 来管理和更新输入字段的状态,并且我们已经将Axios依赖设置为在单击按钮时动态导入Search for GitHub users。

当响应返回时,我们通过它进行映射并显示usernames其名称与输入字段中输入的搜索查询相对应的五个用户。 下面的 GIF 演示了上面的代码块:

结论

我们在本文中了解了动态导入/代码拆分、其优势以及如何在 Next.js 应用程序中使用它。

总体而言,如果您想缩短网站加载所需的时间,动态导入和代码拆分是必不可少的方法。如果网站有图像,或者显示的结果取决于用户交互,动态导入将显着提高网站的性能和用户体验。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pxr007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值