1.css的书写顺序到底会影响渲染性能吗
页面的渲染流程
渲染引擎首先通过网络获得所请求文档的内容,通常以8K分块的方式完成。下面是渲染引擎在取得内容之后的基本流程:
解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树
这里先解释一下几个概念,方便大家理解:
DOM Tree:浏览器将HTML解析成树形的数据结构。
CSS Rule Tree:浏览器将CSS解析成树形的数据结构。
Render Tree: DOM和CSSOM合并后生成Render Tree。
layout: 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系,从而去计算出每个节点在屏幕中的位置。
painting: 按照算出来的规则,通过显卡,把内容画到屏幕上。
reflow(回流):当浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫 reflow。reflow 会从 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置。reflow 几乎是无法避免的。
现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。
通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。\
repaint(重绘):改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。
注意:
(1)display:none 的节点不会被加入Render Tree,而visibility: hidden 则会,所以,如果某个节点最开始是不显示的,设为display:none是更优的。
(2)display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。
(3)有些情况下,比如修改了元素的样式,浏览器并不会立刻reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。但是在有些情况下,比如resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。
举个栗子
width: 200px;
height: 200px;
position: absolute;
按照上文介绍的页面的渲染过程,这段代码在运行到postion的时候就可能会reflow(回流),进而导致页面进行repaint(重绘),所以调整css的书写顺序能够避免这一过程
position: absolute;
width: 200px;
height: 200px;
不过现代浏览器的引擎和性能相比于几年前有很大的提升,所以css的写作顺序对于渲染性能问题上几乎可以忽略不计= =。不过养成好的书写规范仍是至关重要的好习惯!
2.css的书写顺序
建议遵循以下顺序:
- 布局定位属性:display / position / float / clear / visibility / overflow(建议 display 第一个写,毕竟关系到模式)
- 自身属性:width / height / margin / padding / border / background
- 文字样式:font-family font-size font-style font-weight font-varient color
- 文本属性:color / font / text-decoration / text-align / vertical-align / white- space / break-word
- 其他属性(CSS3) :content / cursor / border-radius / box-shadow / text-shadow / background:linear-gradient …
display: block;
position: relative;
float: left;
width: 100px;
height: 100px;
margin: 0 10px;
padding: 20px 0;
font-size:12px;
color: #333;
background: rgba(0,0,0,.5);
border-radius: 10px;
3.使用stylelint规范css代码
开源比较流行的 CSS lint 方案:Csslint、SCSS-Lint、Stylelint,而Stylelint是基于AST 的方式扩展CSS,除原生CSS 语法,也支持 SCSS、Less 这类预处理器,并且有非常多的第三方插件,因此选择了Stylelint作为CSS Lint的工具。
Stylelint 优点
- 其支持 Less、Sass 这类预处理器
- 在社区活跃度上,有非常多的 第三方插件
- 在 Facebook,Github,WordPress 等公司得到实践,能够覆盖很多场景
安装依赖
- stylelint — 运行工具
- stylelint-config-standard — stylelint的推荐配置(如果想使用airbnb或prettier的规范,也可以将stylelint-config-standard改为stylelint-config-airbnb或stylelint-config-prettier)
- stylelint-order — 排序插件(先写定位,再写盒模型,再写内容区样式,最后写 CSS3 相关属性)
- stylelint-commponent 解析依赖
- stylelint-config-prettier 关闭所有不必要的或可能与Prettier冲突的规则
- stylelint-config-styled-components 共享stylelint的配置 校验styled-component
配置Stylelint
Stylelint的配置方式有以下几种:
- 在package.json中添加stylelint属性并添加规则
- 在.stylelintrc文件中指定,.stylelintrc文件支持添加一个文件扩展名来区分 JSON,YAML 或 JS 格式,如创建.stylelintrc.json、.stylelintrc.yaml、.stylelintrc.yml或.stylelintrc.js文件
- 在stylelint.config.js文件中指定,该文件将会exports一个配置对象
采用.stylelintrc.js 进行配置
3.1stylelint 配置项
- plugins //数组,可以是一个 npm 模块名,一个绝对路径,或一个相对于要调用的配置文件的路径
- extends //数组,该配置项允许我们extend一个已存在的配置文件(无论是你自己的还是第三方的配置),当一个配置继承了里一个配置,它将会添加自己的属性并覆盖原有的属性
- rules //对象,它告诉Stylelint该检查什么,该怎么报错
- ignoreFiles //数组,配置忽略的文件路劲
参考配置如下:
module.exports = {
extends: [
'stylelint-config-standard',
'stylelint-config-prettier',
'stylelint-config-html/vue',
'stylelint-config-recommended-vue/scss',
'stylelint-config-recommended-less',
'stylelint-config-recommended-scss',
],
plugins: ['stylelint-order'],
overrides: [
{
"files": ["**/*.vue"],
"customSyntax": "postcss-html"
}
],
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', ],
rules: {
indentation: 2,
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep', ':deep']
}
],
'number-leading-zero': 'always',
'no-descending-specificity': null,
'function-url-quotes': 'always',
'string-quotes': 'single',
'unit-case': null,
'color-hex-case': 'lower',
'color-hex-length': 'long',
'rule-empty-line-before': 'never',
'font-family-no-missing-generic-family-keyword': null,
'selector-type-no-unknown': null,
'block-opening-brace-space-before': 'always',
'at-rule-no-unknown': null,
'no-duplicate-selectors': null,
'property-no-unknown': null,
'no-empty-source': null,
'selector-class-pattern': null,
'keyframes-name-pattern': null,
'selector-pseudo-class-no-unknown': [
true,
{ ignorePseudoClasses: ['global', 'deep'] }
],
'function-no-unknown': null,
'order/properties-order': [
'position',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'justify-content',
'align-items',
'float',
'clear',
'overflow',
'overflow-x',
'overflow-y',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'width',
'min-width',
'max-width',
'height',
'min-height',
'max-height',
'font-size',
'font-family',
'font-weight',
'border',
'border-style',
'border-width',
'border-color',
'border-top',
'border-top-style',
'border-top-width',
'border-top-color',
'border-right',
'border-right-style',
'border-right-width',
'border-right-color',
'border-bottom',
'border-bottom-style',
'border-bottom-width',
'border-bottom-color',
'border-left',
'border-left-style',
'border-left-width',
'border-left-color',
'border-radius',
'text-align',
'text-justify',
'text-indent',
'text-overflow',
'text-decoration',
'white-space',
'color',
'background',
'background-position',
'background-repeat',
'background-size',
'background-color',
'background-clip',
'opacity',
'filter',
'list-style',
'outline',
'visibility',
'box-shadow',
'text-shadow',
'resize',
'transition'
]
}
};
3.2 执行和忽略Stylelint检查
执行Stylelint检查
// 对某个文件进行检查
stylelint "src/App.vue" --fix
// 对指定后缀名的文件进行检查
stylelint "src/*.{vue,less,postcss}" --fix
忽略Stylelint检查
1.使用注释禁用规则
使用/* stylelint-disable */,可以在代码片段禁用所有规则或禁用特定规则。
/* stylelint-disable */
a {}
/* stylelint-enable */
/* stylelint-disable selector-no-id, declaration-no-important */
#id {
color: pink !important;
}
/* stylelint-enable */
使用/* stylelint-disable-line */,可以在个别行上禁用规则。
#id { /* stylelint-disable-line */
color: pink !important; /* stylelint-disable-line declaration-no-important */
}
使用/* stylelint-disable-next-line */,可以在下一行禁用规则。
#id {
/* stylelint-disable-next-line declaration-no-important */
color: pink !important;
}
2.创建.stylelintignore忽略文件检查
//.stylelintignore
node_modules
pont
client/api
4.Vscode插件使用
在vscode中安装以下插件:
- Stylelint插件 配置setting.json 与之前# 【前端规范】01.JS代码规范(Eslint + Prettier+Vscode配置)类似,配置工作区的setting.json如下
{
//开启自动修复
"editor.codeActionsOnSave": {
"source.fixAll": true, // 开启自动修复
"source.fixAll.stylelint": true, // 开启stylelint自动修复
},
// 配置stylelint检查的文件类型范围
"stylelint.validate": [
"css",
"less",
"postcss",
"scss",
"sass",
"vue"
],
"stylelint.enable": true,
"css.validate": false,
"less.validate": false,
"scss.validate": false,
}