我正在使用NextJS与Mantine开发一个网站。我使用createStyles来添加样式。我也尝试使用尽可能多的mantine组件。
当我在Vercel上部署站点时,我发现除了CLS之外,所有站点性能参数都很棒,这很糟糕;如此可怕,以至于你在第一次启动网站时就能感觉到内容的转变。
仅作为示例,Header的代码如下:
import { useState } from 'react';
import {
createStyles, Container, Anchor, Group, ActionIcon, useMantineColorScheme
} from '@mantine/core';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import Sun from '@/public/svg/sun.svg';
import MoonStars from '@/public/svg/moonStars.svg';
const useStyles = createStyles((theme) => ({
inner: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
},
burger: {
[theme.fn.largerThan('sm')]: {
display: 'none',
}
},
links: {
fontWeight: 700,
textTransform: 'uppercase',
textDecoration: 'none',
fontSize: theme.fontSizes.md,
},
mainLink: {
color: theme.colorScheme === 'dark' ? theme.colors.dark[1] : theme.colors.gray[6],
borderBottom: `2px solid transparent`,
transition: 'border-color 100ms ease, color 100ms ease',
'&:hover': {
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
textDecoration: 'none',
},
},
mainLinkActive: {
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
borderBottomColor: theme.colors[theme.primaryColor][theme.colorScheme === 'dark' ? 5 : 6],
},
sideText: {
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
}
}));
export default function Component() {
const { colorScheme, toggleColorScheme } = useMantineColorScheme();
const { classes, cx } = useStyles();
let pathname = usePathname();
const [active, setActive] = useState(() => {
if (pathname.split('/')[1] === '') return 0;
if (pathname.split('/')[1] === 'blog') return 1;
});
let mainLinks = [
{ "link": "/", "label": "About" },
{ "link": "/blog", "label": "Blog" },
]
const mainItems = mainLinks.map((item, index) => (
<Anchor component={Link} href={item.link} key={item.label} py='xl' px='md'
className={cx(classes.mainLink, { [classes.mainLinkActive]: index === active }, classes.links)}
onClick={() => setActive(index)} >
{item.label}
</Anchor>
));
const changeColorScheme = () => {
toggleColorScheme();
localStorage.setItem('color-scheme', colorScheme === 'dark' ? 'light' : 'dark');
}
return (
<Container pos='relative' mb='2rem'>
<Container pos='sticky' className={classes.inner}>
<div className={classes.links}>
<Group spacing={0} >
{mainItems}
</Group>
</div>
<Group position="center" my="xl">
<ActionIcon
onClick={() => changeColorScheme()}
size="lg"
sx={(theme) => ({
backgroundColor:
theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0],
color: theme.colorScheme === 'dark' ? theme.colors.yellow[4] : theme.colors.blue[6],
})}>
{colorScheme === 'dark' ? <Sun /> : <MoonStars />}
</ActionIcon>
</Group>
{/* <Burger opened={opened} onClick={toggle} className={classes.burger} size="sm" /> */}
</Container>
</Container>
);
}
字符串
如果你想自己尝试,可以找到website deployed here
我能想到的一个主要问题是,也许mantine将所有组件都转换为JS,而发布太多的JS使其变得动态,因此所有的转换都是如此
如果使用mantine组件导致了问题,我准备转向原生HTML组件,但我需要确定是否是Mantine导致了问题。
请帮助找出究竟是什么原因导致了高CLS的高内容转移,以及如何改善/防止内容转移。
2条答案
按热度按时间qojgxg4l1#
我能想到的一个主要问题是,也许mantine将所有组件都转换为JS,而发布太多的JS使其变得动态,因此所有的转换都是如此
这就是问题所在HTML和CSS总是比JavaScript快。由于您的Mantime组件依赖于JavaScript,您的HTML和CSS首先加载,导致未样式化的内容 Flink 。
1.最好的方法是切换到原生HTML,但这非常困难。
1.另一个很好的方法是使用像Radix UI或Base UI这样的无头UI库。大多数组件不需要JavaScript,并且已经遵循WAI-ARIA可访问性标准。您仍然需要手动定义CSS样式。
1.但是,最简单的方法是在项目的根目录中创建一个
loading.tsx
文件,以减少CLS。这里是docs for that。最后,这里有一篇关于reduce CLS的一般提示的好文章。
ygya80vv2#
要减少Next.js站点中的累积布局偏移(CLS),您可以应用以下优化:
1.设置显式维度:确保所有元素都具有明确的宽度和高度值,以防止布局偏移。在您的代码中,将尺寸应用于 Package 标头的
Container
组件。字符串
1.预加载字体:如果您使用的是自定义字体,请在HTML的
<head>
部分添加preload
链接,以提前加载字体。型
1.优化镜像加载:确保图像针对Web进行了优化,并使用现代图像格式(如WebP)来减小其大小。此外,对图像实现延迟加载,以推迟其加载,直到它们接近视口。您可以使用像
react-lazyload
这样的库来实现这一点。1.延迟非关键JavaScript:将非关键JavaScript移动到
<body>
标记的末尾,或使用defer
属性延迟其执行。这确保了在JavaScript执行之前呈现基本内容,减少了布局变化的机会。1.最小化第三方脚本:限制第三方脚本的数量,只包括那些必不可少的。第三方脚本可能会引入意外的布局变化并影响性能。
1.避免在改变布局的属性上进行CSS转换:在将CSS过渡或动画应用于影响布局的属性(如宽度或高度)时要小心。如果需要设置这些属性的动画,请考虑设置不透明度或变换的动画。
1.使用Next.js Image组件:Next.js提供了一个
Image
组件,可以自动优化图像并处理响应式图像加载。用Image
组件替换常规的<img>
标记,以更好地优化图像并减少CLS。1.保证图片尺寸明确:博客页面上的许多图像没有明确的尺寸设置。这可能会导致加载图像时布局发生变化。要解决这个问题,请将
width
和height
属性添加到<img>
标记中,或者使用Next.jsImage
组件,并定义width
和height
属性。1.优化字体加载:考虑在CSS中使用
font-display
属性来控制字体在加载过程中的显示方式。通过设置font-display: swap
,您可以确保在加载自定义字体时文本内容保持可见,从而最大限度地减少字体加载引起的布局变化。1.压缩CSS和JavaScript:通过缩小CSS和JavaScript文件来优化它们,以减小它们的文件大小。较小的文件加载速度更快,用户体验更流畅。
1.确保平滑过渡:如果您使用的是过渡或动画,请确保它们是平滑的,并且不会导致突然的偏移或抖动。检查正在设置动画的所有布局更改属性,并确保它们具有适当的缓动和持续时间。
1.减少渲染阻塞资源:使用Google PageSpeed Insights或Lighthouse等工具分析您的网站,以识别任何渲染阻止资源。尽量减少CSS和JavaScript文件的数量,并考虑异步加载或代码拆分,以提高初始渲染速度。
通过应用这些优化,您应该能够减少CLS并提高Next.js站点的性能。请记住使用Lighthouse或Web Vitals等工具来衡量影响,以确保您的CLS改进有效。