精简 CSS
- 移除未使用的 CSS(“死代码”),可借助工具如 PurgeCSS、UnCSS 自动检测并删除未被页面使用的样式。
- 避免重复样式,通过提取公共样式(如 @mixin 或公共类)减少代码冗余。利用预处理器(Sass、Less)变量、混合宏功能减少重复代码。
- 避免过度嵌套(如 div > ul > li > a 可简化为 .nav-link),复杂选择器会增加浏览器匹配元素的计算成本。
- 避免全局样式滥用,使用 CSS Modules 或 Scoped CSS(如 Vue)隔离样式,减少 CSSOM 构建时间。
压缩 CSS
使用 Gzip 或 Brotli 压缩传输,或通过 PostCSS、csso 等工具压缩代码
后处理器(PostCSS)可自动优化代码(如自动前缀、压缩、删除冗余样式)
拆分 CSS
- 按页面或组件拆分 CSS,避免单个超大 CSS 文件阻塞首屏渲染。
- 利用媒体查询拆分不同场景的样式(如 @media print 单独拆分打印样式),浏览器会根据当前场景只加载必要的部分。
内联首屏 CSS
将关键 CSS(首屏必需样式)内联到 <head>
中,避免外部 CSS 文件加载延迟导致的首屏空白。
异步加载非首屏 CSS
- 通过 JavaScript 动态插入
<link>
标签
减少触发重排与重绘的CSS操作
- 集中修改样式(如通过添加 / 移除类一次性修改多个样式,而非逐条设置 element.style)。
- 避免频繁读取会触发重排的属性(如 offsetWidth、scrollTop),可先缓存值再使用。
使用性能更好的 CSS 语法
- 优先使用 ID 或类选择器,避免使用通配符(*)、属性选择器([type=“text”])等低效选择器,尤其是在大型页面中。
- 避免链式类选择器(如 .box.container.large),增加匹配复杂度
- 浏览器匹配选择器的顺序是 “从右到左”,例如 .list li a 会先查找所有
<a>
,再过滤父元素为<li>
且祖先为.list
的元素,效率较低。
优化示例:将.list li a
改为.list-link
(直接给<a>
添加类)。 - 对静态效果可使用图片代替;对动画效果尽量在小范围元素上使用。
content-visibility: auto
延迟渲染不在视口内的元素
浏览器会跳过不在视口内元素的渲染过程(包括布局、绘制等),从而减少浏览器的工作负担。
使用场景
长列表、滚动页面中存在大量离屏元素的情况,例如电商商品列表、新闻资讯列表等。
.list-item {content-visibility: auto;
}
will-change
提前告知浏览器元素可能会发生的变化,让浏览器有时间提前做好优化准备(如创建独立的图层、预先计算等),从而使动画或过渡更加流畅。
浏览器会根据 will-change 指定的属性,对元素进行相应的优化处理。但需要注意,不能滥用该属性,否则可能会消耗过多的内存和性能。
使用场景
即将发生动画或过渡的元素,例如元素的位置移动、大小变换、透明度变化等。
.box {will-change: transform, opacity;
}
transform
使用 transform 进行动画或过渡时,浏览器会将元素提升到独立的图层进行处理,并且不会触发页面的重排(布局)和重绘(绘制),只需要进行复合操作,性能更高。
复合操作是将页面中不同图层的内容合并成最终的页面显示,这个过程相对高效。而重排和重绘会消耗大量的计算资源。
使用场景
各种需要动画效果的元素,如滑动的轮播图、弹出的对话框等。
.slide {transition: transform 0.3s ease;
}
.slide:hover {transform: translateX(10px);
}
opacity
使用 opacity 进行动画或过渡时,也不会触发重排和重绘,只需要进行复合操作,性能较好。
透明度的变化只影响元素的显示效果,不会改变元素的布局和几何形状,因此浏览器可以高效地处理。
使用场景
元素的淡入淡出效果,如模态框的显示与隐藏、按钮的 hover 效果等。
.fade {transition: opacity 0.3s ease;opacity: 1;
}
.fade:hover {opacity: 0.5;
}
contain
限制元素内部的渲染影响范围,告诉浏览器该元素的渲染不会影响到外部,从而让浏览器可以进行更高效的渲染优化。
contain 有多个取值,如 layout(表示元素内部的布局变化不会影响外部)、paint(表示元素的绘制只在自身范围内,不会溢出到外部)、size(表示元素的大小不会受内部内容变化的影响)等。通过合理设置这些值,可以减少浏览器需要检查和更新的区域。
使用场景
内部结构复杂、但与外部布局关联性较小的元素,例如独立的组件、卡片等
.component {contain: layout paint size;
}
background-attachment: fixed(谨慎使用)
使背景图片固定在视口中,不会随着页面的滚动而滚动。在某些情况下,合理使用可以减少背景图片的重绘次数。
但如果背景图片较大或页面滚动频繁,可能会导致性能问题,因此需要谨慎使用,根据实际情况测试效果。
body {background-image: url('bg.jpg');background-attachment: fixed;
}
image-rendering
用于控制图片缩放时的渲染方式,合理设置可以使图片在缩放时保持更好的视觉效果,同时在一定程度上减少渲染开销。
- auto:默认值,使用浏览器默认的图片缩放算法。
- pixelated:当图片放大时,会以像素块的形式显示,适合像素风格的图片,渲染效率较高。
使用场景
需要进行缩放显示的图片,尤其是像素风格的图片。
.pixel-art {image-rendering: pixelated;
}
position: fixed / position: absolute (适度使用)
将元素从文档流中脱离,其位置变化不会影响其他元素的布局,从而减少因元素移动导致的重排。
固定定位(fixed)或绝对定位(absolute)的元素会独立计算布局,其尺寸或位置的修改仅影响自身,不会触发父元素或兄弟元素的布局更新。
使用场景
悬浮组件(如导航栏、弹窗、广告位),避免其位置变化牵连其他元素的布局计算。
注意事项
过多脱离文档流的元素可能增加图层管理成本,需适度使用。
float(合理使用)
浮动元素的布局计算相对独立,其位置调整对周边元素的影响范围较小(仅影响 “浮动流” 内的元素)。
使用场景
图文混排(如新闻段落中的图片浮动),避免图片与文字的布局相互干扰导致频繁重排。
注意事项
滥用浮动可能导致布局混乱,且现代布局更推荐 flex 或 grid,但特定场景下浮动仍有性能优势。
pointer-events: none
禁止元素响应鼠标事件(如点击、 hover 等),浏览器无需为该元素监听鼠标交互,减少事件处理开销。
元素被设置为 pointer-events: none 后,会被排除在鼠标事件目标之外,浏览器无需对其进行事件捕获和处理。
使用场景
纯装饰性元素(如背景图案、动画特效层),无需用户交互的元素可禁用鼠标事件,提升事件处理效率。
.decorative-layer {pointer-events: none;
}
user-select: none
禁止用户选中元素内容,减少浏览器对文本选中状态的跟踪和渲染
浏览器默认会监听文本选中事件并绘制选中高亮,禁用后可减少这部分的渲染开销。
使用场景
按钮、图标、导航等无需复制的元素,避免用户误选并降低渲染压力。
.button {user-select: none;
}
backface-visibility: hidden
隐藏元素旋转时的 “背面”,减少 3D 变换中的渲染计算,降低 GPU 负载。
使用场景
3D 旋转动画(如卡片翻转效果),无需显示背面时使用,提升动画流畅度。
.card {transform-style: preserve-3d;backface-visibility: hidden;
}
isolation: isolate
创建一个新的堆叠上下文,限制元素内部的渲染影响范围,避免与外部元素的堆叠计算相互干扰。
堆叠上下文是浏览器处理元素层叠顺序的机制,isolation: isolate 强制创建独立上下文,减少跨上下文的层叠计算。
使用场景
复杂组件(如弹窗、下拉菜单),避免其内部元素的层叠关系影响页面其他部分的渲染。
.dropdown {isolation: isolate;
}
overflow: hidden
浏览器默认会计算元素所有内容的布局,即使超出容器范围,overflow: hidden 可让浏览器直接忽略超出部分,降低计算量。
配合 content-visibility: auto 使用时,裁剪效果可进一步提升离屏元素的渲染效率。
使用场景
图片容器、卡片组件等需要裁剪内容的元素,避免超出部分的无效渲染。
touch-action
浏览器对触摸事件的默认处理(如手势识别)较为复杂,touch-action 可禁用不必要的行为,提升触摸交互的响应速度。
使用场景
移动端自定义交互元素(如滑动组件、手势控制区域),例如禁用滚动:
.swipe-container {touch-action: none; /* 禁用所有默认触摸行为 */
}
font-display(@font-face 中)
使用 font-display: swap 避免字体加载期间的文本不可见(FOIT);限制字体变体(如字重、样式)数量,减少字体文件体积。
通过设置字体加载期间的显示策略(如使用系统默认字体暂代),减少浏览器等待字体加载时的渲染阻塞。
使用场景
引入自定义字体时,优化字体加载体验:
@font-face {font-family: 'MyFont';src: url('myfont.woff2') format('woff2');font-display: swap; /* 加载时使用备用字体,加载完成后替换 */
}
避免使用低性能的 CSS 语法
- 避免使用通配符(*)、属性选择器([type=“text”])等低效选择器
- 避免使用过大的背景图
- 避免昂贵的 CSS 属性,部分属性计算成本高,如 box-shadow(尤其是模糊半径大时)、filter(如 blur)、clip-path 等,频繁使用或应用于大面积元素会导致性能下降。
- CSS 变量(–var)虽灵活,但频繁通过 JavaScript 读写会触发额外的样式计算,高频率交互场景下需谨慎使用。
- 预处理器(Sass、Less)的嵌套功能需合理使用,避免编译后生成复杂选择器;
- 避免@import:@import会导致 CSS 加载串行化(必须等前一个加载完成才加载下一个),改用
<link>
并行加载。