CSS面试相关问题

浏览器渲染CSS的原因

了解浏览器渲染原理是为了解决性能问题。CSS设置会导致重绘和重排,渲染树会造成性能损耗

HTML会被解析成DOM树,CSS文件也会被解析成CSSOM树,DOM树和CSSOM的组合数就是渲染树。

这一过程中,浏览器会确定每个节点的样式到底是什么,并且这一过程是很消耗资源的,因为样式可以自定设置成某个接地那,也可以通过继承获得,这一过程,浏览器得地柜CSSOM树,然后确定具体的元素到底是什么样式。

<div>
 <a><span></span></a>
</div>
<style>
 span{color:red;}
 div > a > span {color: red}
</style>

对于第一种样式的方式,浏览器只需要找到页面中所有的span标签然后设置颜色,但是对于第二种设置样式的方式,浏览器首先需要找到所有的span标签,然后找到span标签上的a标签,最后再去找到div标签,然后给符合这种条件的span设置颜色,这种递归过程很复杂,所以应该尽可能避免写过于具体和模糊的CSS选择器,然后对于HTML来说尽量少的添加无意义标签,保证层级扁平化。

什么情况下阻塞渲染?

渲染的前提是生成渲染树,所以html和css肯定会阻塞渲染,如果想渲染快,就应该降低一开始需要渲染的文件大小,并且扁平化层级,也就是扁平化DOM树,优化选择器。

然后当浏览器解析到script标签时,暂停DOM的渲染,解析完成之后,在从暂停的位置重新渲染,所以说如果想要首屏渲染快,就不应该在首屏加载JS问价,这也是都建议将script标签放在body标签最底部的原因。

并不是说一定需要将script标签放在body标签最底层,也可以加上async或defer属性。

当script标签加上defer属性后,表示JS文件将会并行下载,但是会放在HTML加息完成后顺序执行,所以对于这猴子那个情况可以将script标签放在任意位置。

对于没有任何依赖的JS文件可以加上async属性,表示JS文件下载和解析不会阻塞渲染。

重绘(repaint)和回流(reflow)?

重绘:是当前节点需要更改外观而不会影响布局,比如改变color就叫重绘(针对CSS设置)

重排:是布局或几何属性需要改改称之为重排

重排必定会发生重绘,重绘不一定会引发重排。重排的成本比重绘高得多,改变父节点的子节点很可能会导致父节点一系列重排

以下几个动作可能会导致性能问题:

改变window大小

改变字体

添加或删除样式

文字改变

定位或浮动

盒模型

并且很多人不知道的是重绘和重排其实和Eventloop有关。html文件

减少重排重绘:

使用transform替代top

使用visibility替代display:none 因为前者只会引起重绘,display会造成重排,它改变了布局。

不要把节点的属性值放在一个循环里当成循环里的变量,因为没循环一次都会重新获取正确的值。

不要使用table布局,可能很小的改动会造成整个table的重新布局

动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用requestAnimationFrame

CSS选择符从右往左匹配查找,避免节点层级过多

将频繁的重绘和重排的节点设置为图层,图层能阻止该节点渲染行为影响到其他节点,比如对于vidio标签,浏览器会自动将该接地那变为图层

在不考虑缓存和优化网络协议的前提下,考虑可以通过哪些方式最快的渲染页面,关键渲染路径是什么?

  1. 从文件的大小考虑

  2. 从script标签使用上考虑
  3. 从CSS,HTML的代码书写考虑
  4. 从需要下载的内容是否需要在首屏使用考虑

CSS的盒模型

理解:元素被一个一个盒子包围着;

盒子分为:

  • 块级盒子 block box

  • 内联盒子 inline box

控制盒子属于显示哪种类型:

  • 控制盒子外部显示类型:display: block display: inline-block
  • 控制盒子内部显示类型:display: flex

JS获取盒子宽高

clientHeight : 盒子可视区域的宽高;heigh+padding

offsetHeight: 加上了盒子边框 (一般使用offsetHight/offsetWidth)

console.log( document.getElementById( 'wrap' ).clientHeight );//不包含margin

console.log( document.getElementById( 'wrap' ).offsetHeight );//不包含margin

CSS的盒子模型

盒子模型应用于块级盒子,内联盒子只应用盒子模型的一部分内容。

注: margin 不计入实际大小 —— 当然,它会影响盒子在页面所占空间,但是影响的是盒子外部空间。盒子的范围到边框为止 —— 不会延伸到margin。

盒子模型的分类:

  • 盒子模型:width=content-width+padding+border 、 height=content-height-padding+border
  • 替代盒模型:width=可见宽度、height=可见高度
    • 使用box-sizing: border-box控制

盒子的CSS属性

margin: 两个盒子在一起,外边距会重叠,且取最大的外边距

CSS可继承的属性

  font-size,font-family,color,line-height,word-space:增加或减少单词之间的空白字符

等等挺多的;

width不算是继承,给父元素设置50%,子元素并不是父元素的50%,只是默认为父元素的100%

visibility和display:none的区别?

visibility会导致重绘,但是display:none会导致重排,改变了布局,重排的代价比重绘大,且重排肯定会导致重绘,且可能会让父节点产生一系列重排;

在使用上尽量使用visibility代替display:none

CSS项目相关

必填* 

   .f-required::before {
      /* &::before { */
      content: '*';
      margin-left: -6px;
      display: inline-block;
      color: #ff5800;
      font-size: 14px;
      line-height: 1;
      /* } */
    }

动态调节内容高度

calc(100vh - ?);

~calc(100vh - ?); 不会出现负数

 

 

猜你喜欢

转载自blog.csdn.net/weixin_43374360/article/details/109726843
今日推荐