前言

1. 雅虎军规显而易见的就是雅虎公司出的,雅虎公司一直都是相应的各种规范上的践行者,有一种系列的书都是雅虎出的,它们每一本书的封面都有一只动物,下图是其中一本的示例,如果说你是想要一直从事前端这个行业的话,建议你把这一系列的书都看一下,这些书有些之前的是 雅虎 出的,后来就是 图灵 出的了

2. 参考网址:

雅虎军规官网地址:英文版

雅虎军规:中文翻译版

3. 什么是雅虎军规?

随着移动端现在的崛起,已经不止是上面的 35 条军规了,还有非常非常多的军规,这些军规是你必须要践行的,因为像上面的 35 条军规一样,这些都是在进行网站性能优化中必须掌握的,不是说一定要全都用上,只是说这些能用的你要尽量的用上,这些军规可以结合一些使前端工程自动化的工具来进行开发,自动化就是说:能用框架或者是自动化工具解决的问题,从来不用人工去介入。

正文

1. 减少 HTTP 请求次数

对 js 和 css 请求数量进行优化

将多个 js 文件合并成可以是两三个 js 文件,这样请求就会减少了,相应的 css link 也是这个道理

雪碧图

在和美工配合的时候页面上的图标之类的可以进行合并,将多个图片合并到一个画布上,这样就可以减少很多的请求。

2. 减少 DNS 的查找次数

什么是 DNS 的查找次数?

假如说我们访问 map.baidu.com 的时候,这个网址是需要进行查找的,他需要通过你输入的这个网址去查找相应的域名(IP),之后才会到真正的服务器上

一般 DNS 的设置都是运维工程师来负责的,但是对于我们前端也是有几点需要注意的

上面的 meta 将 控制 dns 预解析 的值设置为了 on 这样就可以开启 dns 预解析
下面的 link 可以强制主机名查询 ,假设在页面其他位置如果引用了 该 link 的 dns 中的资源的话, 实际上在其引用之前就已经提前将其所需要的 DNS 给解析好了,这样的话就可以直接找到资源,不需要再解析 DNS 耗时了,速度也就会非常的快了,这也是我们前端可以做到的一点,下图的是其在 京东 官网上的使用

3. 避免跳转

什么是避免跳转?

这个就是说人家好不容易到你这台机器上来了,发现你这个页面不是之前的页面了,然后你这边再次做了一个跳转 打开了别的页面,尽量不要做成这种不必要的多次跳转

跳转时会建立一个 301 或者是 302 的请求报头

下图的示例是我在浏览器上以开发者模式下的手机模式输入了 PC 端的网址,打开之后会发现请求报头是 302,这个 302 被永久的建立在了这个 Header 上 ,如果没有这个 Header 的话,浏览器也分不清到底是 301 还是 302 ,他就是靠这个来标识的

301 或者 302 这样的状态码可以参考 HTTP 状态码_百度百科 中的说明进行了解,在做性能优化这方面,一些常见的状态码是必须要了解的
为了去向全栈工程师发展,这个东西是必会的,全栈的话会让你在公司或者是开发项目时所占的权重会更高一些

4. 可缓存的 AJAX

什么是可缓存的 AJAX?

这个就是说我们在进行这样的请求的时候,可以把这样的 AJAX 进行一次缓存

实现的方法

gzip 组件


一般前台请求的资源都会在后台通过 gzip 组件将资源压缩之后再发送回来,然后再在客户端这边来解压,这样再传输过程中相应的资源文件就会变小很多

设置 ETags

这个全称为:Entity Tag,意思是实体标签,从名字上看,是对于某种实体的一个标识。它属于 HTTP 协议的一部分,也就是所有的 Web 服务器都应该(也确实能)支持这个特性。它的作用是用一个特殊的字符串来标识某个资源的“版本”,客户端(浏览器)来请求的时候,可以比较,如果 ETag 一致,则表示该资源并没有修改过,客户端(浏览器)可以使用自己缓存的版本。

如何实现 AJAX 的缓存,具体可参考 Ajax 请求与浏览器缓存 - ted - 博客园 ,这个实现是需要服务端来进行配合的,但是这个整个的过程你得知道,还有如果想要实现 AJAX 缓存的话请求方式尽量设置成 get ,

5. 推迟加载内容

具体可参考 微距摄影_百度图片搜索 ,这个网站使用的就是滚动加载的方式,你在往下滚动时下面的图片的边滚动边请求的

6. 预加载

参考:详解 HTML5 中 rel 属性的 prefetch 预加载功能使用

7. 减少 DOM 元素数量

要尽量的去控制页面的 HTML 的数量,最好的方式是遵循 一个标签三个元素的方式:div before after

8. 根据域名划分页面内容

尽量不要把所有的资源都放在同一台服务器上,至少将 js css images 这些静态的东西放在一个 CDN 的服务器上,这样就需要多个机器来支撑这样的分离

9. 使 iframe 的数量最小

iframe 在页面中能尽量不用的话就不用,这个标签可以在页面页面中插入一个新的 HTML 文档,iframe 也有相应的优缺点

10. 不要出现 404 错误

这个意思就是页面尽量不要丢东西,HTTP 请求是会耗时的即使这个资源已经不存在了

11. 使用内容分发网络

这个就是上面所说的 CDN ,也就是说如果服务器有多余的话就一定要将 html js css 这些静态的资源单独放到一个静态资源服务器中,这样可以让用户最快的去访问到

12. 为文件头指定 Expires 或 Cache-Control

这个就是将该缓存的东西在浏览器中缓存起来,这样的话下次访问时如果请求的资源没发生改变就会直接用缓存里的,不会再去重新的请求耗时了

13. Gzip 压缩文件内容

将 Gzip 组件压缩网站的 js css 文件的状态设置为 on,如果没有开启的话需要告诉后台让其开启

14. 配置 ETag

这个和上面提到的是一样的

15. 尽早刷新输出缓存

早一点刷新 buffer(尽早给浏览器数据)。

当用户请求一个页面,服务器一般要花 200-500ms 来拼凑整个页面。这段时间,浏览器是空闲的(等数据返回)。在 php,有个方法 flush()允许你传输部分准备好的 html 响应给浏览器。这样的话浏览器就可以开始下载组件,而同时后台可以继续生成页面剩下的部分。这种好处更多是在忙碌的后台或轻前端网站可以看到。

一个比较好的 flush 的位置是在 head 之后,因为浏览器可以加载其中的样式和脚本文件,而后台继续生成页面剩余部分。

//这个示例是用的 PHP 做的中间层
<!-- css, js -->
</head>
<?php flush(); ?>
<body>
<!-- content -->

16. 使用 GET 来完成 AJAX 请求

ajax 请求用 get。

Yahoo! Mail 团队发现当使用XMLHttpRequest,POST 被浏览器实现为两步:首先发送头部,然后发送数据。所以使用 GET 最好,仅用一个 TCP 包发送(除非 cookie 太多)。IE 的 url 长度限制是 2K。

POST 不提交任何数据跟 GET 行为类似,但从语义上讲,获取数据应该用 GET,提交数据到服务器用 POST。

17. 把样式表置于顶部

研究雅虎网页性能时发现把样式表移到<head>里会让页面更快。这是因为把样式表移到<head>里允许页面逐步渲染。

关注性能的前端工程师希望页面被逐步渲染,这时因为,我们希望浏览器尽早渲染获取到的任何内容。这对大页面和网速慢的用户很重要。给用户视觉反馈,比如进度条的重要性已经被大量研究和记录。在我们的情况中,HTML页面就是进度条。当浏览器逐步加载页面头部,导航条,logo 等等,这些都是给等待页面的用户的视觉反馈。这优化了整体用户体验。

把样式表放在文档底部的问题是它阻止了许多浏览器的逐步渲染,包括 IE。这些浏览器阻止渲染来避免在样式更改时需要重绘页面元素。所以用户会卡在白屏。

HTML 规范清楚表明样式应该在<head>里。

18. 避免使用 CSS 表达式

CSS 表达式是强大的(可能也是危险的)设置动态 CSS 属性的方法。IE5 开始支持,IE8 开始不赞成使用。例如,背景颜色可以设置成每小时轮换:

background-color: expression(
  (new Date()) .getHours() %2 ? '#B8D4FF': '#F08A00'
);

CSS 表达式的问题是它们可能比大多数人预期的计算的更频繁。它们不仅在页面载入和调整大小时重新计算,也在滚动页面甚至是用户在页面上移动鼠标时计算。比如在页面上移动鼠标可能轻易计算超过 10000 次。

要避免 CSS 表达式计算太多次,可以在它第一次计算后替换成确切值,或者用事件处理函数而不是 CSS 表达式。

19. 使用外部 JavaScript 和 CSS

尽量不要在 html 行内写 js 或者 css

20. 削减 JavaScript 和 CSS

使用一些工具将 js 和 css 分别进行压缩和大打包

21. 用 代替 @import

之前的一个最佳原则是说 CSS 应该在顶部来允许逐步渲染。
但是在 IE 用@import 和把 CSS 放到页面底部行为一致,所以最好别用。

22. 避免使用滤镜

这个是 IE 独有的东西,但是不到万不得已尽量不要使用,因为这个对渲染性能要求很高

23. 把脚本置于页面底部

24. 剔除重复脚本

25. 减少 DOM 访问

这个示例就是说你在 js 中使用了某个 DOM 元素,你可以先将其储存起来,这样的话下次再用的时候就会相应的快一点

26. 开发智能事件处理程序

有时候页面看起来不那么响应(响应速度慢),是因为绑定到不同元素的大量事件处理函数执行太多次。这是为什么使用事件委托是一种好方法,事件委托就是将事件绑定给相应的父级,多个子集可以根据相应的区别去执行不同的事件

另外,你不必等到 onload 事件来开始处理 DOM 树,DOMContentLoaded 更快。大多时候你需要的只是想访问的元素已在 DOM 树中,所以你不必等到所有图片被下载。

比如说在你每次在某个网站中的链接相互跳转的时候这些个 cookie 会把所有的 cookie 全部都带到服务器去然后服务器会把这些东西再带回了,相当的麻烦,所以若是不是特别必要的东西建议写在 local storage 里面

当浏览器请求静态图片并把 cookie 一起发送到服务器时,cookie 此时对服务器没什么用处。所以这些 cookie 只是增加了网络流量。所以你应该保证静态组件的请求是没有 cookie 的。可以创建一个子域名来托管所有静态组件。

比如说在页面中请求了一个图片,这个图片的域名需要使用不会记录到 cookie 中的(基本上是说和 cookie 中设置的 domain 域名不一样),这样的话就比较的轻,不会带来带去的了,这个图片使用的域名就是专门存放图片的地方

29. 优化图像

用一些工具把图像压缩

图片的背后是很多的二进制数据来构成的,你可以将一张图片拖进一个编辑器里查看会发现都是 01 组合成的二进制码,这里面会有比如说是哪个软件处理的、处理时间等等一些无用的东西,可以通过压缩来把它们都干掉,我目前在项目中使用的是 TinyPNG 在线压缩,你也可以将它扩展到 PhotoShop 软件中使用

30. 优化 CSS Spirite

31. 不要在 HTML 中缩放图像

不要因为你可以设置图片的宽高就去用比你需要的大得多的图片。如果你需要

<img width="100" height="100" src="mycat.jpg" alt="My Cat" />

那么,就用 100x100px 的图片,而不是 500x500px 的。

32. favicon.ico 要小而且可缓存

favicon.ico 是在你服务器根路径的图片。邪恶的是即使你不关心它,浏览器仍然会请求它。所以最好不要响应 404。另外由于在同一服务器,每次请求 favicon.ico 时也会带上 cookie。这个图片还会影响下载顺序,比如在 IE,如果你在 onload 时下载额外的组件,fcvicon 会在这些组件之前被下载。

怎么减轻 favicon.ico 的缺点?

  • 小,最好 1K 以下
  • 设置 Expires 头部。也许可以安全地设置为几个月。

33. 保持单个内容小于 25K

这个限制与 iPhone 不缓存大于 25K 的组件相关。注意,这是非压缩(uncompressed)的文件大小。在这里 minification(压缩,不要与 compress 混淆)很重要,因为 gzip 无法满足(iPhone)。

34. 打包组件成复合文本

这个的意思就是建议将 js 和 css 打包到一起,然后再通过其他的一些方法将他们区分开,现在已经有很多前端自动化构建工具可以实现了 比如 webpack