Next.js 优化打包体积减少69%

Next.js 优化打包体积减少69%

本文主要是针对具体问题的解决,性能优化的实践,提供一个思路和方法,各位看官具体情况需要具体处理。

项目背景

笔者首先是从网站的使用体验上,感觉速度没有之前快了,于是打开了network 和 lighthouse

发现 next.js 构建产物 _app-178bb03084901d5c.js 有499KB,这么大,同时 lighthouse 也指出了一些其他问题。

jsx 复制代码
"next": "13.1.6",
"react": "18.2.0",
"react-dom": "18.2.0",

在不同网速下,情况如下

开始优化

Lighthouse和核心网页指标

  • Largest Contentful Paint (LCP) :衡量加载 性能。 为了提供良好的用户体验,LCP 必须在网页首次开始加载后的 2.5 秒内发生。
  • Interaction to Next Paint (INP) :衡量互动 。为了提供良好的用户体验,网页的 INP 不得超过 200 毫秒
  • Cumulative Layout Shift (CLS) :衡量视觉稳定性 。为了提供良好的用户体验,必须将 CLS 保持在 0.1. 或更低

Google 的性能评估工具,用于优化网站性能、可访问性、最佳实践和 SEO。优化前如下图

优化产物体积

安装 [@next/bundle-analyzer](https://www.npmjs.com/package/@next/bundle-analyzer) 是 Next.js 的一个插件,可帮助您管理 JavaScript 模块的大小。它生成每个模块的大小及其依赖关系的可视化报告。您可以使用这些信息来删除较大的依赖项、拆分代码或仅在需要时加载某些部分,从而减少传输到客户端的数据量。

jsx 复制代码
npm i @next/bundle-analyzer
# or
yarn add @next/bundle-analyzer
# or
pnpm add @next/bundle-analyzer

然后修改 next.config.js

jsx 复制代码
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
})
 
/** @type {import('next').NextConfig} */
const nextConfig = {}
 
module.exports = withBundleAnalyzer(nextConfig)

分析依赖包

jsx 复制代码
ANALYZE=true npm run build
# or
ANALYZE=true yarn build
# or
ANALYZE=true pnpm build

执行分析命令后~

我们就看到,这个体积确实大,发现 highlight.js,加载了全部语言包,这对我来说不是必须的,应该采用异步或者轻量加载的方式。但是我的代码中没有使用highlight.js,通过pnpm why highlight.js 发现被其他库引入的(react-syntax-highlighter),找到了问题的源头,于是开始修改相关组件。其中之一

jsx 复制代码
// 轻量导入的方式
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';

优化 Cumulative Layout Shift

顶部的"轮播图"是根据systemconfig api 返回结果动态渲染的,它导致 "布局偏移",因为他不一定存在。设置元素的 displayvisibilityopacity 等 CSS 属性来隐藏元素,这种方式是不行的。

Next.js 的服务端渲染解决问题,决定这个"轮播图"是否出现,通过服务端提前拿到是否展示轮播图的结果,这样客户端就不会出现偏移了

jsx 复制代码
export async function getServerSideProps(content: any) {
  const baseurl = `http://${process.env.HOSTNAME || 'localhost'}:${process.env.PORT || 3000}`;
  const { data } = (await (await fetch(`${baseurl}/api/platform/getSystemConfig`)).json()) as {
    data: SystemConfigType;
  };

  return {
    props: {
      ...(await serviceSideProps(content)),
      showCarousel: data.showCarousel
    }
  };
}

优化图片

首先使用 next/image 优化图像,减小图片大小,使用 priority 对影响LCP的图像优先渲染。

应该对检测为最大内容绘制 (LCP) 元素的任何图像使用优先级属性。具有多个优先级图像可能是合适的,因为不同的图像可能是不同视口尺寸的LCP元素。

jsx 复制代码
import Image from 'next/image'
 
export default function Page() {
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="Picture of the author"
      priority
    />
  )
}

使用 tinify.cn/ 压缩图片大小,使用更好格式的图片

优化无障碍访问

这里只做了小小的处理,给相关的按钮增加了id,能够提高页面的可访问性,这里就不多说了

总结

这里是网站优化过之后的 lighthouse, 有了很明显的提升。

优化过的依赖体积,由原来的 485KB 减少到 154KB,优化大约百分之69%

优化过的 network

结语

下次见各位看官,Next.js国际化多语言探索实践~

相关推荐
那就可爱多一点点1 小时前
H5页面多个视频如何只同时播放一个?
前端·音视频
前端郭德纲3 小时前
浅谈React的虚拟DOM
前端·javascript·react.js
2401_879103684 小时前
24.11.10 css
前端·css
ComPDFKit5 小时前
使用 PDF API 合并 PDF 文件
前端·javascript·macos
yqcoder5 小时前
react 中 memo 模块作用
前端·javascript·react.js
优雅永不过时·6 小时前
Three.js 原生 实现 react-three-fiber drei 的 磨砂反射的效果
前端·javascript·react.js·webgl·threejs·three
神夜大侠9 小时前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱9 小时前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js
柯南二号9 小时前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
wyy72939 小时前
v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条
前端·ui·html