前端优化法则

做 WEB 前端开发有一个很重要的东西,我想大家多多少少都有听说过。就是雅虎军规,也叫做前端性能优化 35 法则。那么到底有哪些呢?

  1. 减少 http 请求次数

    1.1 打包文件

    使用构建工具将多个文件打包成一个,如使用 gulp,grunt 打包多个 js 和 css 为一个 js 和 css 文件,这样可以大大的减少请求数量;

    1.2 CSS Sprites

    就是我们常说的雪碧图,他的原理是将多个小图片合成一个图片。通过控制对应图片的背景位置来得到对应的图像。可以有效的减少请求数量。

    这里也给大家推荐一个在线雪碧图生成网站:http://alloyteam.github.io/gopng/

    1.3 Inline images

    字面上的意思是行内图片。通俗来讲,就是讲图片进行 base64 编码,将图片转换为 base64 的编码格式,因为文本的压缩比比图片的大得多。

  2. 减少 DNS 查询次数

    DNS 查询也会消耗响应时间,如果我们的网页来自不同的域名(比如嵌入了开放广告,引用了外部的图片或者脚本),那么客户端首次解析这些域名也消耗时间。DNS 查询结果缓存在本地系统和浏览器中一段时间,所以 DNS 查询一般是对首次访问响应速度有所影响。

  3. 避免页面跳转(重定向)

    我不赞同这是前端的工作范畴,这更倾向于后端的工作。

    当客户端收到服务器的跳转回复时,客户端可以根据服务器回复中的 location 指定的地址再次发送请求,如:

    1
    2
    3
    HTTP/1.1 301 Moved Permanently
    Location: http://example.com/newurl
    Content-Type: text/html

    这个时候,客户端就会根据服务器端的指定的 location 地址再次请求。

  4. 缓存 AJAX

    Ajax 的异步操作是非常人性化的一个东西,需要注意的是,即使这些内容是异步的,但用户还在等待它的返回结果。所以我们要尽量应用一下规则提高 aj 的响应速度:

    4.1 添加 Expires 或 Cache-Control 报头使回复可以被客户端缓存

    4.2 压缩回复内容

    4.3 减少 DNS 查询

    4.4 精简 javascript

    4.5 避免跳转

    4.6 配置 Etags

  5. 延迟加载

    这里讨论延迟加载需要知道我们的网页运行需要的最小内容集是什么,剩下的内容就可以推到延迟加载的合集当中了。

    当然,不仅仅是这样,如果你有使用过 require.js,那么你一定知道按需加载,这样的话,有的东西如果一直都用不到,那就永远都不会加载了。

  6. 提前加载

    与延迟加载刚好相反,提前加载时为了提前加载接下来网页中访问的资源,下面是提前加载的类型。

    6.1 无条件提前加载:当前网页加载完成后,马上就去下载一些其他的内容供后面使用。

    6.2 有条件加载:根据不同的用户推送不同的内容,常见的淘宝京东广告。

    6.3 有预期的加载:这种情况一般发生在网页重新设计时,由于用户经常访问旧网页,本地对旧的网页内容缓存充分从而显得旧网页速度很快,而新的内容却没有缓存,设计者可以在旧网页的内容中预先加载一些新网页中可能用到的内容,这样新的网页就会生下来一些需要下载的资源

  7. 减少 DOM 元素的数量

    网页中过多的 DOM 元素对网页的加载和脚本来说都很不友好。所以尽可能的减少 DOM 元素并使用语义化标签。

    1
    document.getElementsByTagName("*").length; //控制台可以计算出你当前网页的标签数量。
  8. 将资源放到不同的域名或服务器上

    浏览器一般对同一个域下在连接数有所限制,可以将不同的资源放到不同的域名和服务器上,可以增大并行下载连接,也可以减轻服务器端的压力。

  9. 减少 iframe 数量

    现在使用 iframe 的常见已经很少了,也不推荐使用 iframe,这里不做讲解。

  10. 避免 404

    404 代表没有找到相应的资源,这样客户的时间就被浪费掉了而没有得到有用的信息。

服务器

  1. 使用 CDN

    再次强调第一条黄金定律,减少网页内容的下载时间。提高下载速度还可以通过 CDN(内容分发网来提升。CDN 通过部署在不同地区的服务器来提高客户的下载速度。我们自己的网站可以先通过免费的 CDN 供应商来分发网页资源。

  2. 添加添加 Expires 或 Cache-Control 报文头

    对于静态内容添加 Expires,将静态内容设为永不过期,或者很长时间以后。

    对于动态内容应用合适的 Cache-Control,让浏览器根据条件来发送请求。

  3. Gzip 压缩传输文件

    Gzip 通常可以减少 70%网页内容的大小,包括脚本、样式表、图片等文件。Gzip 比 deflate 更高效,主流服务器都有相应的压缩支持模块。需要注意的是 pdf 文件可以从需要被压缩的类型中剔除,因为 pdf 文件本身已经压缩,gzip 对其效果不大,而且会浪费 CPU。**

  4. 配置 ETags

    虽然标题叫配制 ETags,但是这里你要根据具体情况进行一些判断。首先 Etag 简单来说是通过一个文件版本标识使得服务器可以轻松判断该请求的内容有所更新,如果没有就回复 304 (not modified),从而避免下载整个文件。

  5. 尽早 flush 输出

    网页后台程序中我们知道有个方法叫 Response.Flush,一般我们调用它都是在程序末尾,但注意这个方法可以被调用多次。目的是可以将现有的缓存中的回复内容先发给客户端,让客户端“有活干”。

    那在什么时候调用这个方法比较好呢?一般情况下我们可以在对于需要加载比较多外部脚本或者样式表时可以提前调用一次,客户端收到了关于脚本或外部资源的链接可以并行的先发请求去下载,服务器接下来把后续的处理结果发给客户端。

  6. 使用 GET AJAX 请求

    浏览器在实现 XMLHttpRequest POST 的时候分成两步,先发 header,然后发送数据。而 GET 却可以用一个 TCP 报文完成请求。另外 GET 从语义上来讲是去服取数据,而 POST 则是向服务器发送数据,所以我们使用 Ajax 请求数据的时候尽量通过 GET 来完成。

  7. 避免空的图片 src

    空的图片 src 仍然会使浏览器发送请求到服务器,这样完全是浪费时间,而且浪费服务器的资源。尤其是你的网站每天被很多人访问的时候,这种空请成的伤害不容忽略。

  1. 减少 cookie 大小

    1.1 去除没有必要的 cookie,如果网页不需要 cookie 就完全禁掉

    1.2 将 cookie 的大小减到最小

    1.3 注意 cookie 设置的 domain 级别,没有必要情况下不要影响到 sub-domain

    1.4 设置合适的过期时间,比较长的过期时间可以提高响应速度。

  2. 页面使用无 cookie 域名

    大多数网站的静态资源都没必要 cookie,我们可以采用不同的 domain 来单独存放这些静态文件,这样做不仅可以减少 cookie 大小从而提高响应速度,还个好处是有些 proxy 拒绝缓存带有 cookie 的内容,如果能将这些静态资源 cookie 去除,那就可以得到这些 proxy 的缓存支持。

CSS

  1. 样式表置顶

    这个没什么好说的,如果将样式表放在底部,浏览器会拒绝渲染已经下载的网页,因为大多数浏览器在实现时都努力避免重绘,样式表中的内容是绘制的关键信息,没有下载下来之前只好对不起观众了。

  2. 避免 CSS 表达式

    2.1 CSS 表达式的问题在于它被重新计算的次数远比我们想象的要多,不仅在网页绘制或大小改变时计算,即使我们滚动屏幕或者移动鼠标的时候也在,因此我们还是尽量避免使用它来防止使用不当而造成的性能损耗。

    2.2 如果有不可避免的情况,可以使用 js 脚本代替。

JAVASCRIPT

  1. 将脚本置底

    几乎所有的手册都这么讲,但是我还是认为要把有的脚本放在头部加载。

  2. 使用外部 js 和 css

    这没有什么争议,使用外部 Javascript 和 CSS 文件可以使这些文件被浏览器缓存,从而在不同的请求内容之间重用。
    同时将 Javascript 和 CSS 从 inline 变为 external 也减小了网页内容的大小。

  3. 精简 js 和 css

    精简就是将 Javascript 或 CSS 中的空格和注释全去掉,还有就是提高你 js 和 css 的复用率。

  4. 去除重复脚本,减少 DOM 访问。

    通过 Javascript 访问 DOM 元素没有我们想象中快,元素多的网页尤其慢,对于 Javascript 对 DOM 的访问我们要注意

    4.1 缓存已经访问过的元素

    4.2 Offline 更新节点然后再加回 DOM Tree

    4.3 避免通过 Javascript 修复 layout

图片

  1. 图片优化

    简单点就是压缩图片

  2. 优化 CSS Sprites

    2.1 Spirite 中水平排列图片,垂直排列会增加文件大小;

    2.2 Spirite 中把颜色较近的组合在一起可以降低颜色数,理想状况是低于 256 色以便适用 PNG8 格式;

    2.3 不要在 Spirite 的图像中间留有较大空隙。这虽然不大会增加文件大小,但对于用户代理来说它需要更少的内存来把图片解压为像素地图。100×100 片为 1 万像素,1000×1000 就是 100 万像素。

    PS:最近有看到 svg sprites,改天写一下。

  3. 不要在 HTML 中缩放图片

    不要通过图片缩放来适应页面,如果你需要小图片,就直接使用小图片吧。

  4. 使用小且可缓存的 favicon.ico

    网站图标文件 favicon.ico,不管你服务器有还是没有,浏览器都会去尝试请求这个图标。所以我们要确保这个图标存在、文件尽量小,最好小于 1k、一个长的过期时间

移动端的一些需要注意的地方

参考H5 移动端的一些事件

以上就是全部了,当然加入了一些个人看法。

参考文章:前端性能优化—-yahoo 前端性能团队总结的 35 条黄金定律

[越努力,越幸运!]