全面详解 CSS 原理( 三 )


五、内联样式如何解析?通过上文的了解,我们知道,当 CSS Parser 解析完 CSS 脚本后,会生成 CSSStyleSheetList ,他保存在Document 对象上 。为了更快的计算样式,必须对这些 CSSStyleSheetList 进行重新组织 。
计算样式就是从 CSSStyleSheetList 中找出所有匹配相应元素的 property-value 对 。匹配会通过CSSSelector 来验证,同时需要满足层叠规则 。
将所有的 declaration 中的 property 组织成一个大的数组 。数组中的每一项纪录了这个 property 的selector,property 的值,权重(层叠规则) 。
可能类似如下的表现:
p > a {   color : red;   background-color:black;}  a {  color : yellow}  div {   margin : 1px;}重新组织之后的数组数据为(weight我只是表示了他们之间的相对大小,并非实际值 。)
selectorselectorweightacolor:yellow1p > acolor:red2p > abackground-color:black2divmargin:1px3
好了,到这里,我们来解决上述问题:
首先,要明确,内敛样式只是 CSS 三种加载方式之一;
其次,浏览器解析分为两个分支,HTML Parser 和 CSS Parser,两个 Parser 各司其职,各尽其责;
最后,不同的 CSS 加载方式产生的 Style rule ,通过权重来确定谁覆盖谁;

到这里就不难理解了,对浏览器来说,內联样式与其他的加载样式方式唯一的区别就是权重不同 。
深入了解,请阅读Webkit CSS引擎分析https://blog.csdn.net/scusyq/article/details/7059063
六、何谓 computedStyle ?到这里,你以为完了?Too young too simple, sometimes naive!
浏览器还有一个非常棒的策略,在特定情况下,浏览器会共享 computedStyle,网页中能共享的标签非常多,所以能极大的提升执行效率!如果能共享,那就不需要执行匹配算法了,执行效率自然非常高 。
也就是说:如果两个或多个 element 的 computedStyle 不通过计算可以确认他们相等,那么这些 computedStyle 相等的 elements 只会计算一次样式,其余的仅仅共享该 computedStyle。
那么有哪些规则会共享 computedStyle 呢?
  • 该共享的element不能有id属性且CSS中还有该id的StyleRule.哪怕该StyleRule与Element不匹配 。
  • tagName和class属性必须一样;
  • mappedAttribute必须相等;
  • 不能使用sibling selector,譬如:first-child, :last-selector, + selector;
  • 不能有style属性 。哪怕style属性相等,他们也不共享;
span>p style="color:red">paragraph1span>p>span>p style="color:red">paragraph2span>p>当然,知道了共享 computedStyle 的规则,那么下面我们也就了解了:不会共享 computedStyle 的规则,这里就不展开讨论了 。
深入了解,请参考:Webkit CSS 引擎分析 - 高效执行的 CSS 脚本https://blog.csdn.net/scusyq/article/details/7059063
七、眼见为实
全面详解 CSS 原理

文章插图
 
如上图,我们可以看到不同的 CSS 选择器的组合,解析速度也会受到不同的影响,你还会轻视 CSS 解析原理吗?
感兴趣的同学可以参考这里:speed/validity selectors test for frameworks
八、有何收获?1、使用 id selector 非常的高效 。在使用 id selector 的时候需要注意一点:因为 id 是唯一的,所以不需要既指定 id 又指定 tagName:Badp#id1 {color:red;}  Good  #id1 {color:red;}
当然,你非要这么写也没有什么问题,但这会增加 CSS 编译与解析时间,实在是不值当 。
2、避免深层次的 node ,譬如:
Bad  div > div > div > p {color:red;} Good  p-class{color:red;}3、慎用 ChildSelector ;
4、不到万不得已,不要使用 attribute selector,如:p[att1=”val1”] 。这样的匹配非常慢 。更不要这样写:p[id=”id1”] 。这样将 id selector 退化成 attribute selector 。
Bad  p[id="id1"]{color:red;}  p[class="class1"]{color:red;}  Good #id1{color:red;}  .class1{color:red;}5、理解依赖继承,如果某些属性可以继承,那么自然没有必要在写一遍;6、规范真的很重要,不仅仅是可读性,也许会影响你的页面性能 。这里推荐一个 CSS 规范http://nec.netease.com/standard/css-sort.html,可以参考一下 。
九、总结
“学会使用”永远都是最基本的标准,但是懂得原理,你才能触类旁通,超越自我 。


推荐阅读