CSS重构:样式表性能调优
css同样需要好好写。
序言
- 为什么要读这本书?
其实这个问题说来话长,但是简单的说。就是用团队年会拿的奖金买的书。而且这是我读的第一本书。
而且,这是我读的第一本有关css的纸质书。因为作为一个前端,css总是被忽视一个技能。随着nodejs以及很多js框架的诞生,前端由以前的被UI兼职,现在独立出来,并且开始逐步抢占后端以及native端的底盘,我们越来越多去关注js的性能,设计模式,垃圾回收机制等等。
殊不知,CSS才是良好用户体验的关键。
秉持这一观点(仅代表个人),我推荐买了这本书。拿到手以后,薄薄的100多页,然后兴冲冲。。。
- 是什么吸引我
这里我要引用书中的序言
人们常将前端技术HTML CSS 和JavaScript亲切的称为“三剑客”, 大抵说的是它们并肩而支撑起了数以亿计的网站, 英勇、侠义之气概不亚于桃园结义的刘关张, 但若将网站比作一个少女,HTML可视作她的身躯,CSS必然是伊人的着装打扮,而JavaScript则是其言谈举止。胭脂粉易得,化妆之术难学。……改动一处样式,结果页面布局大乱,修改起样式来如履薄冰,这哪里是哪里啊!样式明明加上了,可千呼万唤就是不生效!伺候好一个浏览器,别家的又乱了,这还能按时发布吗?!
简单的文字,写出了前端选手们的心声啊。
重构的原则
- 什么是重构
重构是指在不改变代码行为的前提下,重写代码,使其更加简洁、易于复用。
在国内的大环境里,很多团队都急于尝鲜,项目进度飞快,需求上天入地、变化多端。重构这个东西基本成了程序员的梦想。或者换一句话说,不想重构自己代码的程序员不是一个好程序员。
为什么要重构呢?
显然,是因为当前的代码不够高效,且不利于维护。我们尽量提倡做小范围的重构,但是现实经常不如人意,很多基础的架构都冗余很多东西。那么问题来了。我们要重构,就要知道什么的是良好的架构
下面我列举书中提到的几点:
- 优秀的架构是可预测的,就是当其他人拿到你的代码时,可以很快理解它是做什么用的
- 优秀的架构可提升代码复用性
- 优秀的架构可扩展
- 优秀的架构可维护
如果我们重构可以使得后来的架构的达到以上目的,那么我们的重构就是值得的。否则,不要轻易去重构。
- 什么时候可以去重构代码
如果我们平时在修复bug,或者在开发新功能时,重构代码是最好的选择。只有不断的去重构代码,代码的质量才能达到卓越。
但是,现实是残酷的。很多时候,我所面临的代码里面有很多的依赖,重构这些依赖就好比拆毛衣上的线,拆的越多,需要重构的部分也就越多。这个时候,如果时间比较紧,先把工作做完是更好的选择。
还有,就是最好不要不要把重构的眼光放在一些无关痛痒的编码风格上,不要患有“不是我写的症”。
在一个技术团队中,一个优秀的领导能理解重构代码的重要性,但是未必所有人都是这样他们可能会持有一下观点:
- 花时间重写代码,看不到功能上的变化,浪费时间
- 这些代码还能继续正常工作,没有必要修复
- 你应该当初就把代码写正确。
如果有人持有以上建议,而且你对自己重构有信心并且,不会影响项目进度,作者建议你去重构。在这个地方,我个人觉得还是要保持谨慎。确认自己的重构是有效的,不要为了重构而重构。因为,不成熟的优化,也是一件让人头疼的事情。
如何写出更好的CSS
-
级联
级联是浏览器选择为元素用哪一种样式的方法。
-
选择器的优先级
样式的优先级(我暂且这么称呼,书中用特指度来描述)决定你的哪一行css是在工作的。
-
用权重相加的方式来计算优先级
一般而言,选择器越特殊,它的优先级越高。也就是选择器指向的越准确,它的优先级就越高。
通常我们用1表示标签名选择器的优先级,用10表示类选择器的优先级,用100标示ID选择器的优先级,如果是属性后面加了!important那么属性将会变为无穷。
举例:
- div.test1 .span var 优先级 1+10 +10 +1
- span#xxx .songs li 优先级1+100 + 10 + 1
- #xxx li 优先级 100 +1
-
通过选择器特指度来计算优先级
特指度是用来表示css识别元素的精确性,可以用(a, b, c, d)四个维度来表示
a 若果用style属性来表示css样式,则a = 1 否则为0
b b为id选择器的数量
c 类选择器属性选择器,伪类选择器的数量
d 类型选择器和伪元素的数量
在计算特指度时,左边选择的特指度最高,若两个值相等,需要比较右侧紧挨着的变量的值。如果两个选择器的特指度都相等,那么在css文档中排在后面的将生效。
举例: #nav-g > ul > li > a.nav-link
- 样式不是用style来加载的所以a = 1
- 有一个id选择器 b = 2
- 有一个类选择器 c = 1
- 有三个类型选择器 d为3
最后就是,除了!important之外,行内样式的特指度是最高的。
如果有两个属性都用!important,则规则集排在后面的生效
-
-
如何写好css
- 使用注释,我个人的观点,注释必须要有,但不宜过多,过多的注释同样会让人产生误解
- 结构一致,比如,有的人喜欢吧规则集写在一行里,例如li {color: #fff; font-size: 10px; ...},不过我个人更喜欢每个规则一行,然后按照一定的次序将他们排列
- 保持选择器的简单
- 简单的选择器有利于样式的重构,即使改变了dom的结构,但其任然可以正常工作
- 简单的选择器,性能更好,浏览器在关联规则表的时,通常会从右边开始匹配,使用特指度更高的选择器使得,样式能够快速的匹配。
- js与css的选择器分开,js最好去操作类名达到改变样式的目的,除了一些特定的功能比如说隐藏。
- 要使用有意义的命名
- 命名不需要粒度太细,否则就是过于模块化,这样的代码显得冗余,且没有达到代码复用的效果
-
css的分类
通用样式:浏览器通常会自带一些样式,我们需要一个通用的样式来将这些样式覆盖掉,以达到在不同的浏览器呈现统一的效果
-
基础样式 因为元素在没有设置样式的情况下会继承父容器的样式,有一些样式例如
- color
- font-family
- Line-height
不需要每次都去设置它们,我们只需要定义一个基础的样式。
- 文档元素<head></head> <link></link><title><base><meta>这些标签不会显示所以不需要样式
- 区块元素 <address> <article><aside><body><footer><header><nav><section>这些元素主要用来做布局用,所以要注意它们的盒模型属性的设置
- 标题和文本元素 <h1>-<h6> <p><pre><figure><ficaption>这些元素用来展示文本,所以要注意文本相关的属性
- 锚点标签元素:link :visited :focus :hover :active,这些元素标识了一些状态可以去关注out-line等
- 文本语义元素<abbr><b><cite><code><data><dfn><em><i><kbd><s><strong><time><u>等
- 列表元素<ol>(有序)<ul>(无序)<dl>(定义列表)
- 组合元素<div><main><spsan>
- 表格
- 表单
- 多媒体
组件样式,包括组件的基本样式以及其行为,例如不同状态,动画等
结构化样式
功能样式
浏览器特定样式
通过样式的分类,我们可以更好的去组织我们的样式,吧同类的样式放在一起,从而使得我们的样式文件更加容易去维护。
关于测试
这是一个永恒 的话题,下面列举几点
确定好自己的项目需要运行的范围,然后定制合适的测试环境,例如当前项目可以运行在多大屏幕上,可以在哪些浏览器上使用。
可以通过工具来查看,我们的css是否已经准确的挂载到dom树上
-
视觉回归测试
我之前以为视觉回归测试就是传说中“观察法”,其实里面还是有一些学问的。
- 测试重要的点
- 保持测试粒度
- 在不同的浏览器上测试
- 使用Gemini工具测试
指定编码规范,现在有很多工具例如eslint,css-beauty等
建立模式库,有利于编码规范,同样可以建立对应测试的模式库。
重构吧
了解了上述知识后,我们就可以来重构我们的项目。
建立不同类型的css,将他们组织在不同的文件中
去除无用的id以及僵尸代码。
重构是一个持续的过程,我们无法做到一次绝对完美的重构,但是,只要一直去做,那将会得到更好的用户体验。