<commit_before>---
layout: post
title:  "高性能网站建设指南读书笔记"
categories: 性能优化
tags: 性能优化
excerpt: 总结了一下书上的14条规则
---

# 规则一、减少http请求

## 一、图片地图
注：点击一个图片的不同部分，弹出不同的页面。

 > **图片地图**：图片地图允许在一个图片上面关联多个url。这样，本来应该用多个分开的图片来实现的例子，就只需要用一个图片了。减少了http请求。
 
 + **实例**

```
<img src="/i/eg_planets.jpg" usemap="#planetmap" alt="..">
<map id="planetmap" name="planetmap">
     <area shape="rect" href="a.html" coords="0,0,50,50">
     <area shape="circle" href="b.html" coords="120,80,50">
     <area shape="poly" href="c.html" coords="0,0,50,50,100,100,200,200">
</map>
```
+ 解析
 >+ **<img>中的usemap属性**：这个属性可以引用<map>中的id 或 name 属性（取决于浏览器），所以我们应同时向 <map> 添加 id 和 name 属性。
>
>+ **<area>标签**：area 元素永远嵌套在 map 元素内部。area 元素可定义图像映射中的区域。
>
>+ **shape属性**：他有三个值Rect（矩形区域），circle（圆形区域），poly（多边形区域）。
>
>+ **rect**:  定义一个矩形区域，coords属性设置值为左上角、右下角的坐标，各个坐标之间用逗号分开。
>
>+ **circle**: 定义一个圆形区域，coords属性设置值为圆心坐标及半径，前两个参数分别为圆心的横、纵坐标，第三个参数为半径。
>
>+ **poly**:    定义一个多边型区域，coords属性设置值为多边形各个顶点的坐标值。

## 二、css sprites
注：对于html文档中不需要下载的图片，就可以用这个技术

+ 即，将多个图片合到一个图片上面去，然后使用background-position属性，可以将背景图片放置到html元素期望的位置上。
+ 合并后的图片比分离的图片总和小，因为，他降低了图片自身的开销（颜色表、格式信息，等等）。

## 三、内联图片

## 四、合并脚本和样式表

## 小结
 
 这个规则是在用户第一次访问网站时候，就可以有效的减少http请求的数量，可以同时改善首次浏览和后续浏览的时间。所以，是最重要的规则。
 
 # 规则二、使用内容发布网络
 
 + 内容发布网络(CDN)是一组分布在多个不同地理位置的服务器。

 # 规则三、添加Expires头
 
 + 静态的html页面想要设置使用缓存(cache-control要http 1.1才支持。若，cache-control和expires同时存在，则cache-control会替代掉expires)
 ```
 1.  <meta http-equiv="Cache-Control" content="max-age=7200" />
2.  <meta http-equiv="Expires" content="Mon, 20 Jul 2013 23:00:00 GMT" />
 ```
 + 现图片，css，js，flash的缓存，要在后台服务器中实现
 
# 规则四、压缩组件

  + **在http请求首部中添加accept-encoding首部```Accept-Encoding: gzip, deflate```.使服务器，用gzip或者deflate编码来压缩http响应包，来减少http响应的大小。**
  + 具体添加的方法是用ajax，在headers属性中设置，或者在beforeSend方法中设置
  
  # 规则五、将样式表放在顶部

  + 将样式表放在顶部实际上并不会降低页面加载的时间，反而，放在底部是最快的。但是，如果放在底部的话，会出现**白屏现象**和**无样式内容的闪烁**（即，页面加载的时候，文字先显示，然后图片。最后，在样式表被完整的解析之后，已经呈现的文字和图片又要用新的样式来进行重绘）。
  + 放在顶部可以用<link>标签和**带有@import规则的<style>标签**,如：```<style>@import url("style.css");</style>```来导入。但是，如果用后者，那么还是有可能会导致白屏现象。
  
 # 规则六、将脚本放在底部

 + 并行下载：http1.1规范中，建议浏览器从每个主机名并行地下载两个组件。所以，如果一个web页面平均地将其组件分别放在两个主机名下，那么整体的响应时间就会减半。
 + **脚本阻塞下载**：**在下载脚本的时候，并行下载实际上是被禁用的**。由于，脚本可能使用document.write来修改页面内容，因此浏览器会等待，以确保页面能够恰当地布局。**另外一个禁用并行下载的原因是，浏览器要保证脚本的顺序**。
 + **使用脚本时，对于所有位于脚本以下的内容，逐步呈现都被阻塞了，所以就该放在最后**。
 
# 规则七、避免css表达式

 + css表达式是动态设置css属性的一种强大的方式。直接用expression()函数，就可以在express中写js代码。甚至可以调用外部js中的函数。
 ```
 width: expression(serCntr(), document.body.clientWidth = "600px");
 min-width: expression(altBgcolor(this));
 <script>
 function altBgcolor(elem) {
     elem.style.backgroundColor = "red";
 }
 </script>
 ```
 + css表达式的问题：css表达式的问题在于他进行求值得频率很高。他们不止在页面呈现和大小改变的时候求值，当页面滚动，甚至是鼠标在页面上面拖拽的时候都要进行求值。
 + 可以用一次性表达式和事件处理器来代替css表达式。
 
# 规则八、使用外部js和css

 + **对比**：存粹而言，内联要快一些。由于，外部文件会增加http的请求次数，若，浏览器没有缓存外部文件，则内联会快。
 + **实用情况：如果，页面的浏览量少，那么内联文件就越强势，因为外部文件的缓存有可能过期。如果，组件的重用率很高，则外部文件就很好**。
 + 主页：对于一些主页来说，用户可能只会浏览这个主页，而不会浏览他的其他内容，则用内联比较好。另一些可能需要浏览主页的其他内容的，则用外部（**动态脚本注入**）比较好。
 
# 规则九、减少DNS查找

 + Keep-Alive：Keep-Alive由于链接是持久的，因此无需DNS查找。
 + DNS查找的数量与web页面中唯一主机名的数量相等，这包括URL、图片、脚本文件、样式表、Flash对象等的主机名。减少唯一主机名的数量就可以减少DNS查找的数量。
 
 # 规则十、精简js

 + 精简：就是从代码中移除不必要的字符以减少其大小，进而改善加载时间。在代码被精简后，所有的注释以及不必要的空白字符（空格、换行和制表符）都将被移除。
 + 混淆：混淆是可以应用在源代码上的另外一种方式。它也会移除注释和空白，但是它还会改写代码（如，将函数和变量名字改写为更短的字符串），这样增加了对代码进行反向工程的难度。
 + 精简css：和精简js差不多。
 + **简单来说这个规则就是用grunt等来对代码进行压缩**。
 
# 规则十一、避免重定向

 + 重定向中301和302这两个状态码用的最多，而303和307是http1.1中的，几乎没有什么什么人用。**301 Moved Permanently是指请求的URL被移除，重定向到Location中的URL处。
 302 Found和301类似，但是Location中的URL是临时定位资源，以后来时用老的URL**。
 + 用js的**document.location**直接设置URL可以进行重定向。
 + HTML文档头中包含**meta refresh标签**可以在其content属性所指定的秒数之后重定向用户。
 如：```<meta http-equiv="refresh" content="0, url=http://tangwanli.com">```
 + **url中缺少结尾斜线会进行重定向。如：```http://tangwanli.com/what```会被重定向到```http://tangwanli.com/what/```。但是，主机名后面缺少斜线时不会发生重定向，如：```http://tangwanli.com```**
 
 # 规则十二、删除重复脚本

 + 页面包含多个相同的js脚本时会损伤性能。造成这个问题的原因是开发一个网站需要大量的资源，而来自不同团队的人都要向页面添加HTML，则容易造成这个问题。
 + 可在模板系统中实现一个脚本管理模块，开解决这个问题。
 
# 规则十三、配置ETag

 + 条件GET请求：缓存的新鲜度检测的时候，发送的请求为条件GET请求。
 + ETag的问题：（1）对于完全相同的组件，从一台服务器获取原始组件，然后向另外一个服务器发送条件GET请求，ETag是不会匹配的。但是，现在很多服务器采用服务器集群和虚拟缓存。（2）ETag还降低了代理缓存的效率。代理后面用户缓存的ETag经常和代理缓存的ETag不匹配。
 + If-None-Match比If-Modified-Since具有更高的优先级。但是，如果同时出现这两个头部，那么服务器禁止返回304，除非两个请求中的字段完全一样。
 + ETag用还是不用：如果不对ETag进行配置的话，那么最好就是完全移除ETag。 
 
 # 规则十四、使Ajax可缓存

 + 用户是否等待的关键因素在于Ajax请求是被动还是主动的。**被动请求**是为了将来使用而预先发起的。即，在用户主动发起请求之前自己发起的请求，所以如果用户需要什么东西，可能这个东西已经是存在于缓存中了。**主动请求**是基于用户当前操作而发起的请求。发起主动请求的时候，用户可能仍然需要等待响应。<commit_msg>modify<commit_after>---
layout: post
title:  "高性能网站建设指南读书笔记"
categories: 性能优化
tags: 性能优化
excerpt: 总结了一下书上的14条规则
---

## 规则一、减少http请求

### 一、图片地图
注：点击一个图片的不同部分，弹出不同的页面。

 > **图片地图**：图片地图允许在一个图片上面关联多个url。这样，本来应该用多个分开的图片来实现的例子，就只需要用一个图片了。减少了http请求。
 
 + **实例**

```
<img src="/i/eg_planets.jpg" usemap="#planetmap" alt="..">
<map id="planetmap" name="planetmap">
     <area shape="rect" href="a.html" coords="0,0,50,50">
     <area shape="circle" href="b.html" coords="120,80,50">
     <area shape="poly" href="c.html" coords="0,0,50,50,100,100,200,200">
</map>
```
+ 解析
 >+ **<img>中的usemap属性**：这个属性可以引用<map>中的id 或 name 属性（取决于浏览器），所以我们应同时向 <map> 添加 id 和 name 属性。
>
>+ **<area>标签**：area 元素永远嵌套在 map 元素内部。area 元素可定义图像映射中的区域。
>
>+ **shape属性**：他有三个值Rect（矩形区域），circle（圆形区域），poly（多边形区域）。
>
>+ **rect**:  定义一个矩形区域，coords属性设置值为左上角、右下角的坐标，各个坐标之间用逗号分开。
>
>+ **circle**: 定义一个圆形区域，coords属性设置值为圆心坐标及半径，前两个参数分别为圆心的横、纵坐标，第三个参数为半径。
>
>+ **poly**:    定义一个多边型区域，coords属性设置值为多边形各个顶点的坐标值。

### 二、css sprites
注：对于html文档中不需要下载的图片，就可以用这个技术

+ 即，将多个图片合到一个图片上面去，然后使用background-position属性，可以将背景图片放置到html元素期望的位置上。
+ 合并后的图片比分离的图片总和小，因为，他降低了图片自身的开销（颜色表、格式信息，等等）。

### 三、内联图片

### 四、合并脚本和样式表

### 小结
 
 这个规则是在用户第一次访问网站时候，就可以有效的减少http请求的数量，可以同时改善首次浏览和后续浏览的时间。所以，是最重要的规则。
 
## 规则二、使用内容发布网络
 
 + 内容发布网络(CDN)是一组分布在多个不同地理位置的服务器。

## 规则三、添加Expires头
 
 + 静态的html页面想要设置使用缓存(cache-control要http 1.1才支持。若，cache-control和expires同时存在，则cache-control会替代掉expires)
 ```
 1.  <meta http-equiv="Cache-Control" content="max-age=7200" />
2.  <meta http-equiv="Expires" content="Mon, 20 Jul 2013 23:00:00 GMT" />
 ```
 + 现图片，css，js，flash的缓存，要在后台服务器中实现
 
## 规则四、压缩组件

  + **在http请求首部中添加accept-encoding首部```Accept-Encoding: gzip, deflate```.使服务器，用gzip或者deflate编码来压缩http响应包，来减少http响应的大小。**
  + 具体添加的方法是用ajax，在headers属性中设置，或者在beforeSend方法中设置
  
## 规则五、将样式表放在顶部

  + 将样式表放在顶部实际上并不会降低页面加载的时间，反而，放在底部是最快的。但是，如果放在底部的话，会出现**白屏现象**和**无样式内容的闪烁**（即，页面加载的时候，文字先显示，然后图片。最后，在样式表被完整的解析之后，已经呈现的文字和图片又要用新的样式来进行重绘）。
  + 放在顶部可以用<link>标签和**带有@import规则的<style>标签**,如：```<style>@import url("style.css");</style>```来导入。但是，如果用后者，那么还是有可能会导致白屏现象。
  
## 规则六、将脚本放在底部

 + 并行下载：http1.1规范中，建议浏览器从每个主机名并行地下载两个组件。所以，如果一个web页面平均地将其组件分别放在两个主机名下，那么整体的响应时间就会减半。
 + **脚本阻塞下载**：**在下载脚本的时候，并行下载实际上是被禁用的**。由于，脚本可能使用document.write来修改页面内容，因此浏览器会等待，以确保页面能够恰当地布局。**另外一个禁用并行下载的原因是，浏览器要保证脚本的顺序**。
 + **使用脚本时，对于所有位于脚本以下的内容，逐步呈现都被阻塞了，所以就该放在最后**。
 
## 规则七、避免css表达式

 + css表达式是动态设置css属性的一种强大的方式。直接用expression()函数，就可以在express中写js代码。甚至可以调用外部js中的函数。
 ```
 width: expression(serCntr(), document.body.clientWidth = "600px");
 min-width: expression(altBgcolor(this));
 <script>
 function altBgcolor(elem) {
     elem.style.backgroundColor = "red";
 }
 </script>
 ```
 + css表达式的问题：css表达式的问题在于他进行求值得频率很高。他们不止在页面呈现和大小改变的时候求值，当页面滚动，甚至是鼠标在页面上面拖拽的时候都要进行求值。
 + 可以用一次性表达式和事件处理器来代替css表达式。
 
## 规则八、使用外部js和css

 + **对比**：存粹而言，内联要快一些。由于，外部文件会增加http的请求次数，若，浏览器没有缓存外部文件，则内联会快。
 + **实用情况：如果，页面的浏览量少，那么内联文件就越强势，因为外部文件的缓存有可能过期。如果，组件的重用率很高，则外部文件就很好**。
 + 主页：对于一些主页来说，用户可能只会浏览这个主页，而不会浏览他的其他内容，则用内联比较好。另一些可能需要浏览主页的其他内容的，则用外部（**动态脚本注入**）比较好。
 
## 规则九、减少DNS查找

 + Keep-Alive：Keep-Alive由于链接是持久的，因此无需DNS查找。
 + DNS查找的数量与web页面中唯一主机名的数量相等，这包括URL、图片、脚本文件、样式表、Flash对象等的主机名。减少唯一主机名的数量就可以减少DNS查找的数量。
 
## 规则十、精简js

 + 精简：就是从代码中移除不必要的字符以减少其大小，进而改善加载时间。在代码被精简后，所有的注释以及不必要的空白字符（空格、换行和制表符）都将被移除。
 + 混淆：混淆是可以应用在源代码上的另外一种方式。它也会移除注释和空白，但是它还会改写代码（如，将函数和变量名字改写为更短的字符串），这样增加了对代码进行反向工程的难度。
 + 精简css：和精简js差不多。
 + **简单来说这个规则就是用grunt等来对代码进行压缩**。
 
## 规则十一、避免重定向

 + 重定向中301和302这两个状态码用的最多，而303和307是http1.1中的，几乎没有什么什么人用。**301 Moved Permanently是指请求的URL被移除，重定向到Location中的URL处。
 302 Found和301类似，但是Location中的URL是临时定位资源，以后来时用老的URL**。
 + 用js的**document.location**直接设置URL可以进行重定向。
 + HTML文档头中包含**meta refresh标签**可以在其content属性所指定的秒数之后重定向用户。
 如：```<meta http-equiv="refresh" content="0, url=http://tangwanli.com">```
 + **url中缺少结尾斜线会进行重定向。如：```http://tangwanli.com/what```会被重定向到```http://tangwanli.com/what/```。但是，主机名后面缺少斜线时不会发生重定向，如：```http://tangwanli.com```**
 
## 规则十二、删除重复脚本

 + 页面包含多个相同的js脚本时会损伤性能。造成这个问题的原因是开发一个网站需要大量的资源，而来自不同团队的人都要向页面添加HTML，则容易造成这个问题。
 + 可在模板系统中实现一个脚本管理模块，开解决这个问题。
 
## 规则十三、配置ETag

 + 条件GET请求：缓存的新鲜度检测的时候，发送的请求为条件GET请求。
 + ETag的问题：（1）对于完全相同的组件，从一台服务器获取原始组件，然后向另外一个服务器发送条件GET请求，ETag是不会匹配的。但是，现在很多服务器采用服务器集群和虚拟缓存。（2）ETag还降低了代理缓存的效率。代理后面用户缓存的ETag经常和代理缓存的ETag不匹配。
 + If-None-Match比If-Modified-Since具有更高的优先级。但是，如果同时出现这两个头部，那么服务器禁止返回304，除非两个请求中的字段完全一样。
 + ETag用还是不用：如果不对ETag进行配置的话，那么最好就是完全移除ETag。 
 
## 规则十四、使Ajax可缓存

 + 用户是否等待的关键因素在于Ajax请求是被动还是主动的。**被动请求**是为了将来使用而预先发起的。即，在用户主动发起请求之前自己发起的请求，所以如果用户需要什么东西，可能这个东西已经是存在于缓存中了。**主动请求**是基于用户当前操作而发起的请求。发起主动请求的时候，用户可能仍然需要等待响应。
{'fraction_non_alphanumeric': 0.16172238211202125, 'fraction_numerical': 0.019260571175559, 'mean_word_length': 9.302166476624857, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5895829', 'n_tokens_mistral': 6779, 'n_tokens_neox': 7594, 'n_words': 303}