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国际化多语言探索实践~

相关推荐
GIS之路几秒前
OpenLayers 获取地图状态
前端·javascript·html
FogLetter16 分钟前
深入理解Flex布局:grow、shrink和basis的计算艺术
前端·css
remember_me17 分钟前
前端打印实现-全网最简单实现方法
前端·javascript·react.js
前端小巷子20 分钟前
IndexedDB:浏览器端的强大数据库
前端·javascript·面试
Whbbit199920 分钟前
如何使用 Vue Router 的类型化路由
前端·vue.js
JYeontu25 分钟前
浏览器书签还能一键下载B站视频封面?
前端·javascript
陈随易25 分钟前
Bun v1.2.16发布,内存优化,兼容提升,体验增强
前端·后端·程序员
聪明的水跃鱼26 分钟前
Nextjs15 基础配置使用
前端·next.js
happyCoder27 分钟前
如何判断用户设备-window.screen.width方式
前端
Sun_light33 分钟前
深入理解JavaScript中的「this」:从概念到实战
前端·javascript