> For the complete documentation index, see [llms.txt](https://ryukiedev.gitbook.io/wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ryukiedev.gitbook.io/wiki/zhi-shi-dian-shu-li/zhi-shi-dian-shu-li-html-liu-lan-qi.md).

# 09 知识点梳理：HTML和浏览器

### 一、 浏览器

#### 1. Cookie、sessionStorage、localStorage

***共同点***

都是保存在浏览器端，并且是同源的

***区别***

Cookie 和 session 都可用来存储用户信息，cookie 存放于客户端，session 存放于服务器端， 因为 cookie 存放于客户端有可能被窃取，所以 cookie 一般用来存放不敏感的信息，比如 用户设置的网站主题，敏感的信息用 session 存储，比如用户的登陆信息，session 可以 存放于文件，数据库，内存中都可以，cookie 可以服务器端响应的时候设置，也可以客 户端通过 JS 设置 cookie 会在请求时在 http 首部发送给客户端，cookie 一般在客户端有 大小限制，一般为 4K，

**下面从几个方向区分一下 cookie，localstorage，sessionstorage 的区别**

* 生命周期:
  * Cookie:可设置失效时间，否则默认为关闭浏览器后失效 Localstorage:除非被手动清除，否则永久保存
  * Sessionstorage:仅在当前网页会话下有效，关闭页面或浏览器后就会被清除 2、存放数据:
  * Cookie:4k 左右
  * Localstorage 和 sessionstorage:可以保存 5M 的信息
* http 请求:
  * Cookie:每次都会携带在 http 头中，如果使用 cookie 保存过多数据会带来性能问题
  * 其他两个:仅在客户端即浏览器中保存，不参与和服务器的通信
* 易用性:
  * Cookie:需要程序员自己封装，原生的 cookie 接口不友好
  * 其他两个:即可采用原生接口，亦可再次封装
* 应用场景:
  * 从安全性来说，因为每次 http 请求都回携带 cookie 信息，这样子浪费了带宽，所以 cookie 应该尽可能的少用
    * 此外 cookie 还需要指定作用域，不可以跨域调用，限制很多
    * 但是 用户识别用户登陆来说，cookie 还是比 storage 好用，其他情况下可以用 storage
  * localstorage 可以用来在页面传递参数
  * sessionstorage 可以用来保存一些临时的数据，防止用户刷新 页面后丢失了一些参数。

#### 2. 说一下 web worker

[MDN](https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers)

在 HTML 页面中，如果在执行脚本时，页面的状态是不可响应的，直到脚本执行完成后，页面才变成可响应。

web worker 是运行在后台的 js，独立于其他脚本，不会影响页面的性能。并且通过 postMessage 将结果回传到主线程。这样在进行复杂操作的时候，就不会阻塞主线程了。

***概念***

Web Worker (工作线程) 是 HTML5 中提出的概念，分为两种类型，`专用线程（Dedicated Web Worker）` 和`共享线程（Shared Web Worker）`。

`专用线程`仅能被创建它的脚本所使用（一个专用线程对应一个主线程），而`共享线程`能够在不同的脚本中使用（一个共享线程对应多个主线程）。

专用线程可以看做是默认情况的 Web Worker，其加上修饰词的目的是为了与共享线程进行区分。

***用途***

Web Worker 的意义在于可以将一些耗时的数据处理操作从主线程中剥离，使主线程更加专注于页面渲染和交互。

* 懒加载
* 文本分析
* 流媒体数据处理
* canvas 图形绘制
* 图像处理
* ...

***需要注意的点***

* 有同源限制
* 无法访问 DOM 节点
* 运行在另一个上下文中，无法使用Window对象
* Web Worker 的运行不会影响主线程，但与主线程交互时仍受到主线程单线程的瓶颈制约。换言之，如果 Worker 线程频繁与主线程进行交互，主线程由于需要处理交互，仍有可能使页面发生阻塞
* 共享线程可以被多个浏览上下文（Browsing context）调用，但所有这些浏览上下文必须同源（相同的协议，主机和端口号）

#### 3. Doctype 作用?

Doctype 声明于文档最前面，告诉浏览器以何种方式来渲染页面，这里有两种模式，严格模式和混杂模式。

**严格模式与混杂模式如何区分? 它们有何意义?**

* 严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行
* 混杂模式，向后兼容，模拟老式浏览器，防止浏览器无法兼容页面

#### 4. Cookie 如何防范 XSS 攻击

`XSS(跨站脚本攻击)`是指攻击者在返回的 HTML 中嵌入 javascript 脚本。

为了减轻这些 攻击，需要在 HTTP 头部配上，set-cookie:

* httponly
  * 这个属性可以防止 XSS,它会禁止 javascript 脚本来访问 cookie。
* secure
  * 这个属性告诉浏览器仅在请求为 https 的时候发送 cookie。
* 结果应该是这样的:Set-Cookie=`<cookie-value>`.....

> XSS 防御的总体思路是:对输入(和 URL 参数)进行过滤，对输出进行编码。也就是对提 交的所有内容进行过滤，对 url 中的参数进行过滤，过滤掉会导致脚本执行的相关内容; 然后对动态输出到页面的内容进行 html 编码，使脚本无法在浏览器中执行。虽然对输 入过滤可以被绕过，但是也还是会拦截很大一部分的 XSS 攻击。

#### 5. cookie session 区别

1. cookie 数据存放在客户的浏览器上，session 数据放在服务器上。
2. cookie 不是很安全，别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗 考虑到安全应当使用 session。
3. session 会在一定时间内保存在服务器上。当访问增多，会比较占用你服务器的性能，考虑到减轻服务器性能方面，应当使用 COOKIE。
4. 单个 cookie 保存的数据不能超过 4K，很多浏览器都限制一个站点最多保存 20 个 cookie。

#### 6. click在ios上有300ms延迟，原因及如何解决

***原因***

safari，为了能把PC端大屏幕的页面以较好的效果展示在小屏幕手机端上，采用了双击缩放（double tap to zoom）的方案。而这就是click在移动端ios会有300ms的缘由。

***解决方案一：***

禁止缩放，那么就没有了双击产生缩放的操作，那么就不需要等待300ms

```html
<meta name="viewport" content="user-scalable=no" />
```

***解决方案二： FastClcik***

* fast click 原理
  * 监听touchend事件（touchstart touchend会先于click触发）
  * 使用自定义DOM事件 模拟一个click事件
  * 把默认的click事件（300ms之后触发）禁止掉

> 很久不维护了，坑多

#### 7. 浏览器缓存

[HTTP强缓存和协商缓存](https://segmentfault.com/a/1190000008956069)

浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行存储，当访问者再次访问同一页面时，浏览器就可以直接从本地磁盘加载文档。

所以根据上面的特点，浏览器缓存有下面的优点：

1. 减少冗余的数据传输
2. 减少服务器负担
3. 加快客户端加载网页的速度

***第一次请求时***

![](/files/QdHkISOoeDJd7XolD7j3)

在第一次请求时，服务器会将页面最后修改时间通过Last-Modified标识由服务器发送给客户端，客户端记录修改时间；服务器还会生成一个Etag，并发送给客户端。

浏览器后续再次进行请求时： ![](/files/VgCkmmdP8ckEM8wJorO6)

浏览器缓存主要分为强强缓存（也称本地缓存）和协商缓存（也称弱缓存）。根据上图，浏览器在第一次请求发生后，再次发送请求时：

* 浏览器请求某一资源时，会先获取该资源缓存的header信息，
  * 然后根据header中的Cache-Control和Expires来判断是否过期。
  * 若没过期则直接从缓存中获取资源信息，包括缓存的header的信息，所以此次请求不会与服务器进行通信。
  * `这里判断是否过期，则是强缓存相关。后面会讲Cache-Control和Expires相关。`
* 如果显示已过期，浏览器会向服务器端发送请求
  * 这个请求会携带第一次请求返回的有关缓存的header字段信息
    * 比如客户端会通过If-None-Match头将先前服务器端发送过来的Etag发送给服务器，服务会对比这个客户端发过来的Etag是否与服务器的相同
      * 若相同，就将If-None-Match的值设为false，
        * 返回状态`304`
        * 客户端继续使用本地缓存，不解析服务器端发回来的数据
      * 若不相同就将If-None-Match的值设为true
        * 返回状态为200
        * 客户端重新机械服务器端返回的数据
  * 客户端还会通过If-Modified-Since头将先前服务器端发过来的最后修改时间戳发送给服务器，服务器端通过这个时间戳判断客户端的页面是否是最新的，如果不是最新的，则返回最新的内容，如果是最新的，则返回`304`，客户端继续使用本地缓存。

**两种缓存**

缓存分为两种:强缓存和协商缓存，根据响应的 header 内容来决定。

**强缓存、协商缓存什么时候用哪个**

* 强缓存是利用http头中的Expires和Cache-Control两个字段来控制的，用来表示资源的缓存时间。强缓存中，普通刷新会忽略它，但不会清除它，需要强制刷新。浏览器强制刷新，请求会带上Cache-Control:no-cache和Pragma:no-cache
* 协商缓存就是由服务器来确定缓存资源是否可用，所以客户端与服务器端要通过某种标识来进行通信，从而让服务器判断请求资源是否可以缓存访问。
  * 普通刷新会启用弱缓存，忽略强缓存。只有在地址栏或收藏夹输入网址、通过链接引用资源等情况下，浏览器才会启用强缓存，这也是为什么有时候我们更新一张图片、一个js文件，页面内容依然是旧的，但是直接浏览器访问那个图片或文件，看到的内容却是新的。

**为什么要有Etag**

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新，为什么还需要Etag呢？HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题：

* 一些文件也许会周期性的更改，但是他的内容并不改变(仅仅改变的修改时间)，这个时候我们并不希望客户端认为这个文件被修改了，而重新GET；
* 某些文件修改非常频繁，比如在秒以下的时间内进行修改，(比方说1s内修改了N次)，If-Modified-Since能检查到的粒度是s级的，这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)；
* 某些服务器不能精确的得到文件的最后修改时间。

Last-Modified与ETag是可以一起使用的，服务器会优先验证ETag，一致的情况下，才会继续比对Last-Modified，最后才决定是否返回304。

**具体有哪些请求头是跟缓存相关的**

强缓存相关字段有 expires，cache-control。如果 cache-control 与 expires 同时存在的话， cache-control 的优先级高于 expires。

协商缓存相关字段有 Last-Modified/If-Modified-Since，Etag/If-None-Match

#### 8. 输入一个URL,到这个页面呈现出来的过程

* DNS 解析
* TCP 连接
* 发送 HTTP 请求 服务器处理请求并返回 HTTP 报文 浏览器解析渲染页面
* 连接结束

![](/files/HI8rJLSy5RsVlptMMJzj)

#### 9. csrf 和 xss 的网络攻击及防范

* CSRF
  * 跨站请求伪造
    * 可以理解为攻击者盗用了用户的身份，以用户的名义发送了恶意请求，比如用户登录了一个网站后，立刻在另一个tab页面访问量攻击者用来制造攻击的网站，这个网站要求访问刚刚登陆的网站，并发送了一个恶意请求，这时候 CSRF 就产生了，比如这个制造攻击的网站使用一张图片，但是这种图片的链接却是可以修改 数据库的，这时候攻击者就可以以用户的名义操作这个数据库
  * 防御方式的话
    * 验证 HTTPReferer 字段
    * 在请求地址中添加 token 并 验证
    * 在 HTTP 头中自定义属性并验证。
* XSS
  * 跨站脚本攻击
    * 是说攻击者通过注入恶意的脚本，在用户浏览网页的时候进行攻 击，比如获取 cookie，或者其他用户身份信息，可以分为存储型和反射型，存储型是攻 击者输入一些数据并且存储到了数据库中，其他浏览者看到的时候进行攻击，反射型的 话不存储在数据库中，往往表现为将攻击代码放在 url 地址的请求参数中
  * 防御的话为 cookie 设置 httpOnly 属性，对用户的输入进行检查，进行特殊字符过滤。

#### 10. cookie 有哪些编码方式?

encodeURI()

#### 11. 说说 302，301，304 的状态码

* 301 Moved Permanently 永久移动。
  * 请求的资源已被永久的移动到新 URI，返回信息会 包括新的 URI，浏览器会自动定向到新 URI。今后任何新的请求都应使用新的 URI 代替
* 302 Found 临时移动。
  * 与 301 类似。但资源只是临时被移动。客户端应继续使用原有 URI
* 304 Not Modified 未修改。
  * 所请求的资源未修改，服务器返回此状态码时，不会返回 任何资源。客户端通常会缓存访问过的资源，通过提供一个头信息指出客户端希望只返 回在指定日期之后修改的资源

### 二、 HTML

#### 1. 对 HTML 语义化标签的理解

HTML5 语义化标签是指正确的标签包含了正确的内容，结构良好，便于阅读，比如 nav 表示导航条，类似的还有 article、header、footer 等等标签。

#### 2. iframe 是什么?有什么缺点?

* 定义
  * iframe 元素会创建包含另一个文档的内联框架
  * 提示:可以将提示文字放在`<iframe></iframe>`之间，来提示某些不支持 iframe 的浏览器
* 缺点:
  * 会阻塞主页面的 onload 事件
  * 搜索引擎无法解读这种页面，不利于 SEO
  * iframe 和主页面共享连接池，而浏览器对相同区域有限制所以会影响性能。

#### 3. addEventListener 参数

* event 指定事件名
* function 指定要事件触发时执行的函数
* useCapture 指定事件 是否在捕获或冒泡阶段执行。

#### 4. HTML5 新增的元素

* 首先 html5 为了更好的实践 web 语义化，增加了 header，footer，nav,aside,section 等语义 化标签
* 在表单方面，为了增强表单，为 input 增加了 color，emial,data ,range 等类型，
* 在存储方面，提供了 sessionStorage，localStorage,和离线存储，通过这些存储方式方便数 据在客户端的存储和获取
* 在多媒体方面规定了音频和视频元素 audio 和 vedio
* 另外还 有地理定位，canvas 画布，拖放，多线程编程的 web worker 和 websocket 协议。

### 三、 CSS

#### 1. 说一下 盒子模型

[MDN-强烈推荐好好读读](https://developer.mozilla.org/zh-CN/docs/Learn/CSS/Building_blocks/The_box_model)

#### 2. flex 弹性盒子

[MDN-flex](https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Flexbox)

#### 3. 画条 0.5 px 的线

直接设置0.5px，在不同的浏览器会有不同的表现

***transform 缩放***

```css
.scale-half {
    height: 1px;
    transform: scaleY(0.5);
    transform-origin: 50% 100%; /*为了防止线模糊*/
}
```

***meta viewport***

这样子就能缩放到原来的0.5倍，如果是1px那么就会变成0.5px。

```css
<meta name="viewport" content="initial-scale=0.5, maximum-scale=1.0, user-scalable=no" />
```

> 注意：移动端适用，字体也会变小，原理是css的1px在手机上并不是物理上的1像素，可能是2像素，initial-scale的值改为0.5之后就只代表1像素

***也可以直接用图片***

#### 4. 页面导入样式时，使用link和@import有什么区别

* 区别1：
  * link是XHTML标签，除了加载CSS外，还可以定义RSS等其他事务；
  * @import属于CSS范畴，只能加载CSS。
* 区别2：
  * link引用CSS时，在页面载入时同时加载；
  * @import需要页面网页完全载入以后加载。所以会出现一开始没有css样式，闪烁一下出现样式后的页面(网速慢的情况下)
* 区别3：
  * link是XHTML标签，无兼容问题；
  * @import是在CSS2.1提出的，低版本的浏览器不支持。
* 区别4：
  * link支持使用Javascript控制DOM去改变样式；
  * 而@import不支持。在html设计制作中，css有四种引入方式。

#### 5. css四种引入方式

***方式一： 内联样式***

```html
<div style="display: none;background:red"></div>
```

***方式二： 嵌入样式***

```html
<head>
    <style>
      .content {
         background: red;
       }
    </style>
</head>
```

***方式三：链接样式***

```html
<head>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
```

***方式四：导入样式***

导入方式指的是使用 CSS 规则引入外部 CSS 文件

```html
<style>
    @import url(style.css);
</style>
```

或者写在css样式中

```css
@charset "utf-8";
@import url(style.css);
*{ margin:0; padding:0;}
.notice-link a{ color:#999;}
```

***总结***

我们应尽量使用 `<link>` 标签导入外部 CSS 文件，避免或者少用使用其他三种方式。

#### 6. transition 和 animation 的区别

animation属性类似于transition，他们都是随着时间改变元素的属性值，那么区别是什么？

其主要区别在于：transition需要触发一个事件才会随着时间改变其CSS属性；animation在不需要触发任何事件的情况下，也可以显式的随时间变化来改变元素CSS属性，达到一种动画的效果。

1）CSS的transition需要借助别的方式来触发，比如CSS的状态选择器（如:hover）或 借助JavaScript来触发；animation可以自动触发

2）过渡只有一组（两个：开始-结束） 关键帧，动画可以设置多个。

#### 7. BFC 块格式化上下文

[MDN-块格式化上下文](https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context)

官方文档比较晦涩，建议搭配阅读

[一次弄懂css的BFC](https://zhuanlan.zhihu.com/p/127187654)

#### 8. 清除浮动

[清除浮动的四种方式及其原理理解](https://juejin.cn/post/6844903504545316877#heading-4)

#### 9. 垂直居中

[CSS垂直居中的七个方法](https://zhuanlan.zhihu.com/p/263417006)

* 设定行高（line-height）
  * 行内元素
* 添加伪元素（::before、::after）
* calc动态计算
* 使用表格或假装表格
* transform
* 绝对定位
* 使用Flexbox

#### 10. css3动画与js动画的区别

[参考](https://juejin.cn/post/6997255364857036813)

***JS动画***

* 缺点：
  * (1)JavaScript在浏览器的主线程中运行，而主线程中还有其它需要运行的JavaScript脚本、样式计算、布局、绘制任务等,对其干扰导致线程可能出现阻塞，从而造成丢帧的情况。
  * (2)代码的复杂度高于CSS动画
* 优点：
  * (1)JavaScript动画控制能力很强, 可以在动画播放过程中对动画进行控制：开始、暂停、回放、终止、取消都是可以做到的。
  * (2)动画效果比css3动画丰富,有些动画效果，比如曲线运动,冲击闪烁,视差滚动效果，只有JavaScript动画才能完成
  * (3)CSS3有兼容性问题，而JS大多时候没有兼容性问题

***CSS动画***

* 缺点：
  * (1)运行过程控制较弱,无法附加事件绑定回调函数。CSS动画只能暂停,不能在动画中寻找一个特定的时间点，不能在半路反转动画，不能变换时间尺度，不能在特定的位置添加回调函数或是绑定回放事件,无进度报告
  * (2)代码冗长。想用 CSS 实现稍微复杂一点动画,最后CSS代码都会变得非常笨重。
* 优点：
  * (1)浏览器可以对动画进行优化。
  * (2)代码相对简单,性能调优方向固定
  * (3)对于帧速表现不好的低版本浏览器，CSS3可以做到自然降级，而JS则需要撰写额外代码

#### 11. CSS动画流畅的原因与前提

渲染线程分为main thread(主线程)和compositor thread(合成器线程)。 如果CSS动画只是改变transform和opacity，这时整个CSS动画得以在compositor thread完成（而JS动画则会在main thread执行，然后触发compositor进行下一步操作）。

在JS执行一些昂贵的任务时，main thread繁忙，CSS动画由于使用了compositor thread可以保持流畅。

**CSS动画比JS流畅的前提：**

1. JS在执行一些昂贵的任务
2. 同时CSS动画不触发layout或paint，在CSS动画或JS动画触发了paint或layout时，需要main thread进行Layer树的重计算，这时CSS动画或JS动画都会阻塞后续操作。

* 只有如下属性的修改才符合“仅触发Composite，不触发layout或paint”：
  * backface-visibility
  * opacity
  * \*erspective
  * perspective-origin
  * transfrom

所以只有用上了3D加速或修改opacity时，css3动画的优势才会体现出来。

#### 12. css3动画与js动画怎么选

如果动画只是简单的状态切换，不需要中间过程控制，在这种情况下，css动画是优选方案。它可以让你将动画逻辑放在样式文件里面，而不会让你的页面充斥 Javascript 库。

然而如果你在设计很复杂的富客户端界面或者在开发一个有着复杂UI状态的 APP。那么你应该使用js动画，这样你的动画可以保持高效，并且你的工作流也更可控。

所以，在实现一些小的交互动效的时候，就多考虑考虑CSS动画。

对于一些复杂控制的动画，使用javascript比较可靠。

#### 13. 多行文本省略

```css
#post-title {
  display: -webkit-box;
  text-overflow: ellipsis;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
```

#### 14. 聊聊 visibility=hidden, opacity=0，display:none

* opacity=0，该元素隐藏起来了，但不会改变页面布局，并且，如果该元素已经绑定一些 事件，如 click 事件，那么点击该区域，也能触发点击事件的
* visibility=hidden，该元素 隐藏起来了，但不会改变页面布局，但是不会触发该元素已经绑定的事件
* display=none， 把元素隐藏起来，并且会改变页面布局，可以理解成在页面中把该元素删除掉一样

#### 15. 双边距重叠现象(外边距折叠)

多个相邻(兄弟或者父子关系)普通流的块元素垂直方向 marigin 会重叠

* 折叠的结果为:
  * 两个相邻的外边距都是正数时，折叠结果是它们两者之间较大的值。
  * 两个相邻的外边距都是负数时，折叠结果是两者绝对值的较大值。
  * 两个外边距一正一负时，折叠结果是两者的相加的和。

#### 16. position 属性 比较

* 固定定位 fixed:
  * 元素的位置相对于浏览器窗口是固定位置，即使窗口是滚动的它也不会移动。
  * Fixed 定位使元素的位置与文档流无关，因此不占据空间。
  * Fixed 定位的元素和其他元素重叠。
* 相对定位 relative:
  * 如果对一个元素进行相对定位，它将出现在它所在的位置上。
  * 然后，可以通过设置垂直 或水平位置，让这个元素“相对于”它的起点进行移动。
  * 在使用相对定位时，无论是 否进行移动，元素仍然占据原来的空间。
  * 因此，移动元素会导致它覆盖其它框。
* 绝对定位 absolute:
  * 绝对定位的元素的位置相对于最近的已定位父元素，如果元素没有已定位的父元素，那么它的位置相对于`<html>`。
  * absolute 定位使元素的位置与文档流无关，因此不占据空间。
  * absolute 定位的元素和其他元素重叠。
* 粘性定位 sticky:
  * 元素先按照普通文档流定位，然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。
  * 而后，元素定位表现为在跨越特定阈值前为相对定位，之后为固定定位。
* 默认定位 Static:
  * 默认值。没有定位，元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。
* inherit:
  * 规定应该从父元素继承 position 属性的值。

#### 17. css3 新特性

开放题。CSS3 边框如 border-radius，box-shadow 等;CSS3 背景如 background-size， background-origin 等;CSS3 2D，3D 转换如 transform 等;CSS3 动画如 animation 等。 参考 <https://www.cnblogs.com/xkweb/p/5862612.html>

#### 18. CSS 选择器有哪些

|   选择器   |                    示例                   |                                         MDN                                         |  -  |
| :-----: | :-------------------------------------: | :---------------------------------------------------------------------------------: | :-: |
|  类型选择器  |                 `h1 { }`                |        [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Type_selectors)       |  -  |
|  通配选择器  |                 `* { }`                 |     [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Universal_selectors)     |  -  |
|   类选择器  |                `.box { }`               |       [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Class_selectors)       |  -  |
|  ID 选择器 |              `#unique { }`              |         [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/ID_selectors)        |  -  |
| 标签属性选择器 |              `a[title] { }`             |     [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors)     |  -  |
|  伪类选择器  | `p:first-child { }` `button:hover {}` 等 |      [具体见：MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Pseudo-classes)     |  -  |
|  伪元素选择器 |           `p::first-line { }`           |       [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Pseudo-elements)       |  -  |
|  后代选择器  |               `article p`               |    [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Descendant_combinator)    |  -  |
|  子代选择器  |              `article > p`              |       [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Child_combinator)      |  -  |
| 相邻兄弟选择器 |                 `h1 + p`                | [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Adjacent_sibling_combinator) |  -  |
| 通用兄弟选择器 |                 `h1 ~ p`                |  [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/General_sibling_combinator) |  -  |

#### 19. CSS选择器优先级

[MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Specificity#选择器类型)

### 四、前端优化

#### 1. 可优化内容

* 降低请求量
  * 合并资源，减少 HTTP 请求数，minify / gzip 压缩，webP，lazyLoad。
* 加快请求速度
  * 预解析 DNS，减少域名数，并行加载，CDN 分发。
* 缓存
  * HTTP 协议缓存请求，离线缓存 manifest，离线数据缓存 localStorage。
* 渲染
  * JS/CSS 优化，加载顺序，服务端渲染，pipeline。

#### 2. 怎么看网站的性能如何

检测页面加载时间一般有两种方式：

* 一种是被动去测:
  * 就是在被检测的页面置入脚本或 探针，当用户访问网页时，探针自动采集数据并传回数据库进行分析
* 另一种主动监测的方式
  * 即主动的搭建分布式受控环境，模拟用户发起页面访问请求，主动采集性能数 据并分析，在检测的精准度上，专业的第三方工具效果更佳，比如说性能极客
