▼ 关注「之家前端共享」,获取更多技术干货 ▼
在上篇文章前端性能优化秘籍:掌握CSS选择器的正确姿势中,介绍了CSS选择器的使用方式,下面了解下优化技巧。
CSS,作为构建网页视觉表现的核心技术之一,它的优化对于提升前端性能尤为关键。然而,随着项目规模的扩大和功能的增多,CSS代码往往会变得冗长和难以维护,这不仅增加了页面的加载时间,还可能影响页面的渲染效率和用户体验。
精简CSS代码,并不是简单地减少代码行数,而是一个全面审视和重构CSS使用方式的过程。它要求我们深入理解CSS的选择器、属性和布局原理,通过精心设计和优化,去除多余的代码,减少浏览器的解析负担,从而提升页面的加载速度和渲染性能。
本文将探讨一系列实用的CSS精简技巧和最佳实践,从基础的代码编写规范到高级的性能优化策略,旨在帮助开发者深入理解如何通过精简CSS代码来提升前端性能。我们将一起学习如何构建更高效、更快速且易于维护的Web前端项目。
精简CSS代码是前端性能优化的重要步骤,因为它直接关系到页面加载时间和渲染效率。以下是一些实用的技巧来精简CSS代码并提升前端性能:
使用简写属性
利用CSS的简写属性,例如`margin`、`padding`、`border`等,以减少代码量。
CSS简写属性可以帮助你更高效地编写样式代码。以下是一些常用的CSS简写属性示例:
`margin`和`padding`的简写:
1/* 一个值:所有边都使用这个值 */
2
3margin: 10px;
4
5padding: 10px;
6
7/* 二个值:第一个值是上下,第二个值是左右 */
8
9margin: 5px10px;
10
11padding: 5px10px;
12
13/* 三个值:上,左右,下 */
14
15margin: 1px2px3px;
16
17padding: 1px2px3px;
18
19/* 四个值:上,右,下,左 */
20
21margin: 1px2px3px4px;
22
23padding: 1px2px3px4px;
`border`的简写:
1/* 一次性设置border的宽度、样式和颜色 */
2border: 1px solid #000;
`background`的简写:
1/* 一次性设置背景的颜色和图片,可以设置多个背景图片 */
2background: #fffurl(image.png) no-repeat center;
`font`的简写:
1/* 一次性设置字体的样式、粗细、大小和行高 */
2font: italic bold 16px/1.5'Arial', sans-serif;
`list-style`的简写:
1/* 一次性设置列表的图片、位置和样式 */
2list-style: square inside url(bullet.png);
简写属性可以帮助你减少代码量,并使样式更加集中和清晰。
避免重复样式
审查CSS代码,删除重复的选择器和属性声明。
合理使用继承(inheritance)和组合(composition)。
例如,假设我们有一个网站,其中的按钮在多个页面上具有相同的基本样式,但在某些情况下可能需要一些额外的样式。我们可以这样写CSS:
基础按钮样式:
1.button {
2 padding: 10px20px;
3 border: 1px solid #000;
4 text-align: center;
5 cursor: pointer;
6}
特殊按钮样式:
1.button--special {
2 background-color: #f00;
3 color: #fff;
4}
在HTML中,我们可以这样使用:
1<buttonclass="button">普通按钮</button>
2<buttonclass="button button--special">特殊按钮</button>
这种方法通过合理使用类的组合,避免了在普通按钮上应用`--special`类所带来的不必要的重写,从而减少了代码冗余。
压缩CSS
使用工具如CSSNano、Clean-CSS或Webpack的CSS压缩插件来移除空格、注释和换行符,减小文件大小。
例如,使用Webpack的CSS压缩插件css-minimizer-webpack-plugin 来完成 CSS 样式文件的压缩。
要使用该插件,必须现先在本地安装它:
1npm install css-minimizer-webpack-plugin --save-dev
只安装没有用,要使用该插件能够生效,我们必须在 webpack.config.js 配置文件进行配置。需要注意,这个插件不是在 plugin(插件) 中进行配置,而是在optimization(优化)中进行配置。
1// webpack.config.js
2const CssMinimizerPlugin= require("css-minimizer-webpack-plugin");
3module.exports = {
4 optimization: {
5 minimizer: [
6 new CssMinimizerPlugin(),
7 ],
8 },
9}
编译打包,打开 .css样式文件,发现 CSS 样式文件已经被压缩。默认情况下仅在生产环境开启 CSS 优化。如果还想在开发环境下启用 CSS 优化,需要在 webpack.config.js 配置文件中将 optimization.minimize 设置为 true。
1const CssMinimizerPlugin= require("css-minimizer-webpack-plugin");
2module.exports = {
3 optimization: {
4 minimizer: [
5 new CssMinimizerPlugin(),
6 ],
7 minimize:true,
8 },
9}
移除未使用的CSS
使用Chrome DevTools的Coverage工具或其他类似工具来分析并移除未使用的CSS代码。并利用purgecss去除多余的css。
安装`purgecss-webpack-plugin`:
1npm i purgecss-webpack-plugin -D
其次,需要安装`mini-css-extract-plugin`
1npm i mini-css-extract-plugin -D
最后,它还需要`glob`(一般自带,不用安装),或者`glob-all`(推荐使用)。
1npm i glob-all -D
基本配置:
在这个配置中,需要指定`Purgecss`的`paths`,这个`glob-all`可以设置多条路径,更加方便一些。这些路径是用来指定`css`使用的位置途径的。也就是说`css`删减的标准。
运行结果:
为了显示它的特别效果。用了一个`bootstrap`框架,来看看它的`css`清理效果。就使用一个小组件,目标就是仅仅保留这个小组件的`css`存在,以最终达到瘦身的目的。代码如下:
1// `npm`安装`bootstrap`:
2npm i bootstrap -D
3
4// `./src/main.js`引入`bootstrap.css`:
5import'bootstrap/dist/css/bootstrap.css';
6
7// `./html/index.html`模版,引入个按钮用例:
8<buttontype="button"class="btn btn-lg btn-success">Success</button>
执行结果对比:
操作 | size |
`bootstrap.css`原版 | 193kb |
开启`sourcemap`关闭`purgecss` | 483kb |
开启`sourcemap`和`purgecss` | 4.78kb |
关闭`sourcemap`开启`purgecss` | 4.59kb |
使用CSS重置或归一化
采用CSS重置(reset)或归一化(normalize)来减少浏览器默认样式的差异。
以下是一个简单的CSS重置示例,它会移除常见元素的默认margin和padding,并设置了默认字体和背景:
CSS Reset:
1html, body, div, span, applet, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, big, cite, code,del, dfn, em, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var,b, u, i, center,dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td,article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary,time, mark, audio, video {
2 margin: 0;
3 padding: 0;
4 border: 0;
5 font-size: 100%;
6 font: inherit;
7 vertical-align: baseline;
8 box-sizing: border-box;
9 /* Ensure padding and borders are included in element sizes */
10 -webkit-font-smoothing: antialiased;
11 /* Improve text rendering on Webkit browsers */
12}
13
14/* HTML5 display-role reset for older browsers */
15article,
16aside,
17details,
18figcaption,
19figure,
20footer,
21header,
22hgroup,
23menu,
24nav,
25section {
26 display: block;
27}
28
29body {
30 line-height: 1;
31}
32
33ol, ul {
34 list-style: none;
35}
36
37blockquote, q {
38 quotes: none;
39}
40
41blockquote:before,
42blockquote:after,
43q:before,
44q:after {
45 content: '';
46 content: none;
47}
48
49table {
50 border-collapse: collapse;
51 border-spacing: 0;
52}
53/* Custom styles */
54body {
55 font-family: 'Arial', sans-serif;
56 background-color: #fff;
57 color: #333;
58}
对于非首屏渲染的CSS,可以异步加载,以减少首屏加载时间。
在现代浏览器中,可以使用`<link>`标签的`rel="preload"`属性来异步加载非关键CSS。以下是一个示例代码:
1<!DOCTYPE html>
2<htmllang="en">
3<head>
4<metacharset="UTF-8">
5<metaname="viewport"content="width=device-width, initial-scale=1.0">
6<title>异步加载CSS</title>
7<!-- 异步加载样式表 -->
8<linkrel="preload"as="style"href="style.css"onload="this.onload=null;this.rel='stylesheet'">
9<noscript><linkrel="stylesheet"href="style.css"></noscript>
10<!-- 其他关键样式 -->
11<style>
12/* 关键CSS */
13body { background-color: #fff; }
14</style>
15</head>
16<body>
17<h1>Hello World</h1>
18</body>
19</html>
在这个例子中,`<link rel="preload">`被用来异步加载`style.css`文件。当加载完成时,通过 JavaScript 的`onload`事件处理函数将`link`标签的`rel`属性从`preload`更改为`stylesheet`,这样浏览器就会应用该样式表。`<noscript>`标签中的`<link>`是为不支持 JavaScript 的环境准备的后备方案。
关键CSS内联
将影响首屏渲染的关键CSS内联到HTML文档的`<head>`中,减少外部请求。
1<head>
2 <style>
3 /* 关键CSS规则 */
4 body{font-family: sans-serif;color:#111;}
5 .header{background-color:#333;color:white;}
6</style>
7</head>
代码分割
对于大型应用,可以使用代码分割技术将CSS分割成多个小块,按需加载。
以下是使用Sass和Webpack进行CSS分割的简单示例:
安装必要的包:
1npm install sass-loader sass webpack --save-dev
创建一个Sass文件,并使用@import进行分割:
1//styles/main.scss
2@import"variables";
3@import"mixins";
4@import"components/button";
5@import"components/header";
6@import"layout/grid";
创建分割的Sass部分:
1// styles/variables.scss
2$primary-color: blue;
3
4// styles/mixins.scss
5@mixin button-style
6{
7 /* Button style */
8}
9
10// styles/components/button.scss
11@import"mixins";
12.button {
13 @include button-style;
14 color: $primary-color;
15}
16
17// styles/components/header.scss
18.header { /* Header style */}
19
20// styles/layout/grid.scss
21.grid { /* Grid style */}
配置Webpack以使用split-chunks插件进行代码分割:
1// webpack.config.js
2const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3module.exports = {
4 entry: './src/index.js',
5 output: { filename: 'bundle.js', },
6 module: {
7 rules: [
8 {
9 test: /.scss$/,
10 use: [
11 MiniCssExtractPlugin.loader,
12 'css-loader',
13 'sass-loader',
14 ],
15 },
16 ],
17 },
18 plugins: [
19 newMiniCssExtractPlugin({filename: 'styles.css',}),
20 ],
21 optimization: {
22 splitChunks: {
23 cacheGroups: {
24 styles: {
25 name: 'styles',
26 test: /.scss$/,
27 chunks: 'all',
28 enforce: true,
29 },
30 },
31 },
32 },
33};
使用Sass或Less等预处理器的变量、混合(mixins)、函数等特性来提高代码复用性。
1// 在Sass中,变量以$符号开始
2
3$primary-color: #3bbfce;
4$margin: 16px;
5
6.content-navigation {
7 border-color: $primary-color;
8 color: darken($primary-color, 10%);
9}
10
11.border {
12 padding: $margin / 2;
13 margin: $margin / 2;
14 border-color: $primary-color;
15}
1// 混合允许你定义一个可重用的代码块:
2@mixin border-radius($radius) {
3 -webkit-border-radius: $radius;
4 -moz-border-radius: $radius;
5 -ms-border-radius: $radius;
6 border-radius: $radius;
7}
8
9.box { @include border-radius(10px); }
1// Sass也允许你定义自己的函数:
2@function pow($base, $exponent) {
3 $result: 1;
4 @for $_ from 1 through $exponent {
5 $result: $result * $base;
6 }
7 @return $result;
8}
9
10.sidebar {
11 width: pow(2, 3) * 1px; // 8px
12}
1// 在Less中,变量也是以@符号开始:
2@primary-color: #3bbfce;
3@margin: 16px;
4
5.content-navigation {
6 border-color: @primary-color;
7 color: darken(@primary-color, 10%);
8}
9
10.border {
11 padding: @margin / 2;
12 margin: @margin / 2;
13 border-color: @primary-color;
14}
1// 混合在Less中的使用类似于Sass:
2.border-radius(@radius) {
3 -webkit-border-radius: @radius;
4 -moz-border-radius: @radius;
5 -ms-border-radius: @radius;
6 border-radius: @radius;
7}
8
9.box { .border-radius(10px); }
1// Less中的函数通常是内置的,用于处理颜色和数学运算等:
2@base: 5%;
3.calculate(@value) {
4 width: (@value * @base);
5}
6
7.container {
8 .calculate(20); // 计算后的宽度为 100%
9}
在这些例子中,我们可以看到Sass和Less都提供了强大的工具来帮助开发者编写更加高效和模块化的CSS代码。通过使用变量、混合和函数,可以减少重复代码,使样式表更加易于维护和扩展。
除上述之外,我们还可以通过其它方法来进行优化,例如:
利用CDN服务分发CSS文件,并设置合适的缓存策略。
通过构建工具自动化压缩、合并和优化CSS的过程。
定期使用PageSpeed Insights、Lighthouse等工具监测网站性能,识别CSS性能瓶颈。
通过实施这些策略,可以显著减少CSS代码的体积,加快页面加载速度,提升用户体验。
感谢阅读本文,希望它能为你提供一些启发和帮助。欢迎留言分享您的看法和经验。
▼ 关注「之家前端共享」,获取更多技术干货 ▼