Skip to content

Commit

Permalink
feat update blog
Browse files Browse the repository at this point in the history
  • Loading branch information
jgchenu committed May 8, 2019
1 parent 0638292 commit 6a0b812
Show file tree
Hide file tree
Showing 133 changed files with 8,230 additions and 0 deletions.
75 changes: 75 additions & 0 deletions css/animation,transition,transform/animation.html
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>animation</title>
<style>
.box {
height: 100px;
width: 100px;
border: 15px solid black;
animation: changebox 1s ease-in-out 1s infinite alternate running forwards;
}

.box:hover {
animation-play-state: paused;
}

@keyframes changebox {
10% {
background: red;
}
50% {
width: 80px;
}
70% {
border: 15px solid yellow;
}
100% {
width: 180px;
height: 180px;
}
}
</style>
</head>
<body>
<!--
animation: name duration timing-function delay iteration-count direction play-state fill-mode;
name
用来调用@keyframes定义好的动画,与@keyframes定义的动画名称一致
duration
指定元素播放动画所持续的时间
timing-function
规定速度效果的速度曲线,是针对每一个小动画所在时间范围的变换速率
delay
定义在浏览器开始执行动画之前等待的时间,值整个animation执行之前等待的时间
iteration-count
定义动画的播放次数,可选具体次数或者无限(infinite)
direction
设置动画播放方向:normal(按时间轴顺序),reverse(时间轴反方向运行),alternate(轮流,即来回往复进行),alternate-reverse(动画先反运行再正方向运行,并持续交替运行)
play-state
控制元素动画的播放状态,通过此来控制动画的暂停和继续,两个值:running(继续),paused(暂停)
fill-mode
控制动画结束后,元素的样式,有四个值:none(回到动画没开始时的状态),forwards(动画结束后动画停留在结束状态),backwords(动画回到第一帧的状态),both(根据animation-direction轮流应用forwards和backwards规则),注意与iteration-count不要冲突(动画执行无限次)
-->
<div class="box"></div>
</body>
</html>
37 changes: 37 additions & 0 deletions css/animation,transition,transform/transition.html
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>transition</title>
<style>
#box {
height: 100px;
width: 100px;
background: green;
transition: transform 1s ease-in 1s;
}

#box:hover {
transform: rotate(180deg) scale(.5, .5);
}
</style>

</head>
<body>
<!--
transition: property duration timing-function delay;
transition-property: 规定设置过渡效果的 CSS 属性的名称
transition-duration:规定完成过渡效果需要多少秒或毫秒
transition-timing-function:规定速度效果的速度曲线
transition-delay:定义过渡效果何时开始
-->
<div id="box"></div>

</body>
</html>
40 changes: 40 additions & 0 deletions css/bfc/BFC内外互不影响.html
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>BFC</title>
</head>

<body>
<style>
#margin {
background-color: red;
overflow: hidden;
/*创建BFC*/
}

#margin p {
margin: 5px auto 25px;
background-color: blue;
}
</style>
<!-- BFC元素内的子元素布局不受BFC外面的元素影响,同时也不影响BFC外面的元素 -->
<section id="margin">
<h3 style="background-color: #fff;">垂直方向边距重叠,margin: 5px auto 25px;</h3>
<p>1</p>
<p>2</p>
<p>3</p>

<h3 style="background-color: #fff;">清除重叠,给子元素增加一个父元素f,给他f创建一个BFC</h3>
<p>1</p>
<div style="overflow: hidden;background-color: yellow;">
<p>2</p>
</div>
<p>3</p>
</section>
</body>

</html>
49 changes: 49 additions & 0 deletions css/bfc/BFC的浮动子元素算进高度.html
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>

<body>
<style>
#float {
background-color: red;
}

#float .float {
float: left;
}

#float:after {
content: "";
/* display: inline-block 设置bfc隔绝开 但是这样会撑开父元素的高度*/
}

#float2 {
background-color: red;
overflow: hidden;
/*创建BFC*/
}

#float2 .float {
float: left;
}
</style>

<h3 style="background-color: #fff;">子元素是float元素时,不参与计算,父元素红色背景不显示</h3>
<section id="float">
<div class="float">我是浮动元素,子元素是浮动元素的时候,高度计算没有包含进来,此时父级元素高度为0</div>
</section>
<!-- BFC元素内的浮动子元素 有算进父元素的高度,能避免父元素的高度坍塌-->
<h3 style="background-color: #fff;">BFC子元素即使是float也会参与计算,父元素为BFC,背景为红色</h3>
<section id="float2">
</style>
<div class="float">我是浮动元素,BFC子元素是浮动元素的时候,参与计算,此时父级元素高度是21px;</div>
</section>
</body>

</html>
12 changes: 12 additions & 0 deletions css/bfc/bfc.md
@@ -0,0 +1,12 @@
#### BFC的原理(渲染规则):

* 1.在BFC元素垂直方向的边距会发生重叠;
* 2.BFC的区域不会与浮动元素的box重叠,可用来清除浮动和布局的;
* 3.BFC在页面上是一个独立的容器,外面的元素不会影响里面的元素,反之,里面的元素不会影响外面的元素;
* 4.计算BFC高度的时候,浮动元素也会参加计算。

#### 如何创建BFC?

* 1.position的值不为static或者relative;
* 2.display属性值为inline-block, table-cell, 和 table-caption,table;
* 3.overflow的值不为visiable,即overflow:auto;/overflow:hidden都可创建BFC
42 changes: 42 additions & 0 deletions css/bfc/浮动子元素与BFC子元素不重叠.html
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>

<body>
<style>
#layout {
background-color: red;
}

#layout .left {
float: left;
width: 100px;
height: 100px;
background-color: pink;
}

#layout .right {
height: 110px;
background-color: blue;
}
</style>
<!-- 元素内的BFC子元素跟浮动子元素不会发生重叠 -->

<section id="layout">
<h3 style="background-color: #fff;">左侧固定宽度,右侧自适应;左浮动,且右侧高度高于左侧</h3>
<div class="left">float: left;height: 100px;</div>
<div class="right">height: 110px;</div>

<h3 style="background-color: #fff;">BFC不与float重叠</h3>
<div class="left">float: left;height: 100px;</div>
<div class="right" style="overflow: auto;">height: 110px;用overflow: auto;创建BFC,就不会再与左侧部分发生重叠</div>
</section>
</body>

</html>
132 changes: 132 additions & 0 deletions css/css优化技巧.md
@@ -0,0 +1,132 @@
### CSS性能优化的8个技巧

#### 1.内联首屏关键CSS(实践)
性能优化中有一个重要的指标:首次有效绘制(First Meaningful Paint,简称FMP)即指页面的首要内容(primary content)出现在屏幕上的时间。

内联CSS能够使浏览器开始页面渲染的时间提前:因为在HTML下载完成之后就能渲染了。
使用外部CSS文件时,需要在HTML文档下载完成后才知道所要引用的CSS文件,然后才下载它们。

局限性:不适合内联过多的css,因为`初始拥塞窗口`存在限制(TCP相关概念,通常是 14.6kB,压缩后大小),如果内联CSS后的文件超出了这一限制,系统就需要在服务器和浏览器之间进行更多次的往返,这样并不能提前页面渲染时间。我们应当`只将渲染首屏内容所需的关键CSS内联到HTML`中。而且内联之后的CSS不会进行缓存,每次都会重新下载。

使用:内联首屏的关键css,使用外部css引入剩余的css,这样启动缓存,还可以使用异步加载。

#### 2.异步加载CSS(实践)

CSS会阻塞渲染,在CSS文件请求、下载、解析完成之前,浏览器将不会渲染任何已处理的内容。有时,这种阻塞是必须的,因为我们并不希望在所需的CSS加载之前,浏览器就开始渲染页面。那么将首屏关键CSS内联后,剩余的CSS内容的阻塞渲染就不是必需的了,可以使用外部CSS,并且异步加载。

第一种方式

使用JavaScript动态创建样式表link元素,并插入到DOM中。
```js
// 创建link标签
const myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
// 插入到header的最后位置
document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );
```

第二种方式

将link元素的`media`属性设置为用户浏览器不匹配的媒体类型(或媒体查询),如`media="print"`,甚至可以是完全不存在的类型`media="noexist"`。对浏览器来说,如果样式表不适用于当前媒体类型,其优先级会被放低,会在不阻塞页面渲染的情况下再进行下载。
当然,这么做只是为了实现CSS的异步加载,别忘了在文件加载完成之后,将media的值设为`screen``all`,从而让浏览器开始解析CSS。
```html
<link rel="stylesheet" href="mystyles.css" media="noexist" onload="this.media='all'">
```
与第二种方式相似,我们还可以通过rel属性将link元素标记为alternate可选样式表,也能实现浏览器异步加载。同样别忘了加载完成之后,将rel改回去。
```html
<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">
```
上述的三种方法都较为古老。现在,rel="preload"5这一Web标准指出了如何异步加载资源,包括CSS类资源。
```html
<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">
```

注意,as是必须的。忽略as属性,或者错误的as属性会使preload等同于XHR请求,浏览器不知道加载的是什么内容,因此此类资源加载优先级会非常低。as的可选值可以参考上述标准文档。

看起来,`rel="preload"`的用法和上面两种没什么区别,都是通过更改某些属性,使得浏览器异步加载CSS文件但不解析,直到加载完成并将修改还原,然后开始解析。

但是它们之间其实有一个很重要的不同点,那就是使用`preload`,比使用不匹配的`media`方法能够更早地开始加载CSS。所以尽管这一标准的支持度还不完善,仍建议优先使用该方法。

#### 3.文件压缩

性能优化时有一个最容易想到,也最常使用的方法,那就是文件压缩,这一方案往往效果显著。
文件的大小会直接影响浏览器的加载速度,这一点在网络较差时表现地尤为明显。相信大家都早已习惯对CSS进行压缩,现在的构建工具,如`webpack``gulp/grunt``rollup`等也都支持CSS压缩功能。压缩后的文件能够明显减小,可以大大降低了浏览器的加载时间。

#### 4. 去除无用CSS

找到并删除代码中无用的CSS

一般情况下,会存在这两种无用的CSS代码:

* 一种是不同元素或者其他情况下的重复代码,
* 一种是整个页面内没有生效的CSS代码。


减少重复代码:在编写的代码时候,我们应该尽可能地提取公共类,减少重复。
,在不同开发者进行代码维护的过程中,总会产生不再使用的CSS的代码,当然一个人编写时也有可能出现这一问题。而这些无用的CSS代码不仅会增加浏览器的下载量,还会增加浏览器的解析时间,这对性能来说是很大的消耗。所以我们需要找到并去除这些无用代码。

当然,如果手动删除这些无用CSS是很低效的。我们可以借助[Uncss7](https://github.com/uncss/uncss)库来进行。

Uncss可以用来移除样式表中的无用CSS,并且支持多文件和JavaScript注入的CSS。

### 建议型

### 1. 有选择地使用选择器

CSS选择器的匹配是从右向左进行的,这一策略导致了不同种类的选择器之间的性能也存在差异。相比于`#markdown-content-h3`,显然使用`#markdown .content h3`时,浏览器生成渲染树(render-tree)所要花费的时间更多。因为后者需要先找到DOM中的所有`h3`元素,再过滤掉祖先元素不是`.content`的,最后过滤掉`.content`的祖先不是`#markdown`的。试想,如果嵌套的层级更多,页面中的元素更多,那么匹配所要花费的时间代价自然更高。

* Tips:为什么CSS选择器是从右向左匹配的?
CSS中更多的选择器是不会匹配的,所以在考虑性能问题时,需要考虑的是如何在选择器不匹配时提升效率。从右向左匹配就是为了达成这一目的的,通过这一策略能够使得CSS选择器在不匹配的时候效率更高。这样想来,在匹配时多耗费一些性能也能够想的通了。


#### 2. 减少使用昂贵的属性

在浏览器绘制屏幕时,所有需要浏览器进行操作或计算的属性相对而言都需要花费更大的代价。当页面发生重绘时,它们会降低浏览器的渲染性能。所以在编写CSS时,我们应该尽量减少使用昂贵属性,如`box-shadow/border-radius/filter/透明度/:nth-child`等。

当然,并不是让大家不要使用这些属性,因为这些应该都是我们经常使用的属性。之所以提这一点,是让大家对此有一个了解。当有两种方案可以选择的时候,可以优先选择没有昂贵属性或昂贵属性更少的方案,如果每次都这样的选择,网站的性能会在不知不觉中得到一定的提升。

#### 3. 优化重排与重绘

在网站的使用过程中,某些操作会导致样式的改变,这时浏览器需要检测这些改变并重新渲染,其中有些操作所耗费的性能更多。我们都知道,当FPS为60时,用户使用网站时才会感到流畅。这也就是说,我们需要在16.67ms内完成每次渲染相关的所有操作,所以我们要尽量减少耗费更多的操作。

**3.1 减少重排**

重排会导致浏览器重新计算整个文档,重新构建渲染树,这一过程会降低浏览器的渲染速度。如下所示,有很多操作会触发重排,我们应该避免频繁触发这些操作。

* 改变font-size和font-family
* 改变元素的内外边距paading跟marin
* 通过JS改变CSS类
* 通过JS获取DOM元素的位置相关属性(如width/height/left等)
* CSS伪类激活
* 滚动滚动条或者改变窗口大小

此外,我们还可以通过CSS Trigger15查询哪些属性会触发重排与重绘。
值得一提的是,某些CSS属性具有更好的重排性能。如使用Flex时,比使用inline-block和float时重排更快,所以在布局时可以优先考虑Flex。

**3.2 避免不必要的重绘**

当元素的外观(如`color,background,visibility`等属性)发生改变时,会触发重绘。在网站的使用过程中,重绘是无法避免的。不过,浏览器对此做了优化,它会将多次的重排、重绘操作合并为一次执行。

不过我们仍需要避免不必要的重绘,如页面滚动时触发的`hover事件`,可以在滚动的时候禁用hover事件,这样页面在滚动时会更加流畅。

此外,我们编写的CSS中动画相关的代码越来越多,我们已经习惯于使用动画来提升用户体验。我们在编写动画时,也应当参考上述内容,减少重绘重排的触发。除此之外我们还可以通过`硬件加速``will-change`来提升动画性能,本文不对此展开详细介绍,感兴趣的小伙伴可以点击链接进行查看。

最后需要注意的是,用户的设备可能并没有想象中的那么好,至少不会有我们的开发机器那么好。我们可以借助Chrome的开发者工具进行CPU降速,然后再进行相关的测试,降速方法如下图所示。

![css](https://raw.githubusercontent.com/jgchenu/staticAssets/master/web-learning/css1.png)

如果需要在移动端访问的,最好将速度限制更低,因为移动端的性能往往更差。


#### 4. 不要使用@import
最后提一下,不要使用`@import`引入CSS,相信大家也很少使用。
不建议使用@import主要有以下两点原因。

首先,使用`@import`引入CSS会影响浏览器的并行下载。使用`@import`引用的CSS文件只有在引用它的那个css文件被下载、解析之后,浏览器才会知道还有另外一个css需要下载,这时才去下载,然后下载后开始解析、构建`render tree`等一系列操作。这就导致浏览器无法并行下载所需的样式文件。

其次,多个`@import`会导致下载顺序紊乱。在IE中,`@import`会引发资源文件的下载顺序被打乱,即排列在`@import`后面的js文件先于`@import`下载,并且打乱甚至破坏`@import`自身的并行下载。
所以不要使用这一方法,使用link标签就行了。



0 comments on commit 6a0b812

Please sign in to comment.