提升前端性能的黄金法则

前端近几年变化很大,各类工具,库,框架并发。虽然如此,可是网站前端性能优化的思路基本没变。
为何前端性能如此重要?数据显示:前端

  • 只有 10%~20% 的最终用户响应时间花在了下载 HTML 文档上。其他的 80%~90% 时间花在了下载页面中的全部组件中;express

  • 另一点是,优化后台须要花费比较大的成本,优化前端只须要适当地遵循一些法则会有较大的提高,相对低成本高收益。segmentfault

最近读了 Steve Souders 的《高性能网站建设指南》,以为很不错在此作一下总结。Steve 是 Firebug 和 Yslow 的做者,相信你们都使用过。虽然书中的不少手段都已通过时了,可是思路基本没变,取其精华就好。浏览器

本书提出了一套性能黄金法则,优先级越高排名越前,一共14则:缓存

1. 减小HTTP请求
2. 使用内容发布网络(CDN)
3. 添加Expires头
4. 压缩组件
5. 将样式表放在顶部
6. 将脚本放在底部
7. 避免使用CSS表达式
8. 使用外部JavaScript和CSS
9. 减小DNS查找
10. 精简JavaScript
11. 避免重定向
12. 删除重复的脚本
13. 配置ETag
14. 使Ajax可缓存

如下分别简单介绍每条法则的原因:性能优化


1. 减小HTTP请求

通常来讲,使用外链的脚本和样式表更加有利。分别把外链脚本和样式表进行合并会减小HTTP请求,以节省客户端和服务器之间的通信次数来加快页面打开速度。可是出于开发的便利,开发的时候通常会采起模块化的方式;这时候能够在部署前采用一些前端构建工具把这些模块文件合并起来再发布。服务器


2. 使用内容发布网络(CDN)

CDN是一组分布在多个不一样地理位置的Web服务器,因为距离用户 物理距离比较短,因此可以更加有利于用户获取到静态资源;这种服务一般须要购买,也有一些免费、通用的CDN可以使用,国内的可使用 BootCDN网络


3. 添加Expires头

Expires头是用来告诉浏览器该相应的有效期,能够理解为该资源的“保质期”,在期限内可使用该资源的缓存不须要从新请求。因为浏览器与服务器存在时钟同步问题,HTTP1.1还添加胡了Cache-Control和max-age来弥补Expires头的不足。一般用于脚本,样式表、图片等静态资源。并发

使用这种策略可能会遇到一个问题是,开发者可能想要在资源过时前这段时间更新它们。这时候,因为浏览器的缓存还没失效,这就须要经过更改文件名来令静态资源 强制失效。有不少种方式给静态资源打上版本号,能够一本正经地打上数字版本号,根据内容生成哈希码也行,甚至有人用π来给本身的资源打版本号(每次。框架


4. 压缩组件

本书介绍的是gzip的方式压缩静态资源,实际上,这种方式会消耗额外的CPU资源。这种手段一般可以使文件大小减小70%。


5. 将样式表放在顶部

若是把样式表放在底部时,浏览器会延迟显示任何可视化组件。另外,使用 CSS 的@import 等同于把想要加载的样式放在底部,因此不建议使用。对于浏览器的渲染机制,本书并无过多说起,只是对现象作出了描述以及提供了解决办法。

若是样式表仍然在加载,构建呈现树就是一种浪费,由于在全部样式表加载并解析完毕以前无需绘制任何东西。不然,在其准备好以前显示内容会遇到 FOUC(无样式内容的闪烁,Flash of Unstyled Content)问题。

就是说,若是不把样式表放在 <head> 中,当遇到样式时,浏览器就会阻止页面呈现,等待样式表下载完毕。

若是把样式表放在底部,在 IE 中还会产生白屏现象。总之,把样式表放进 <head> 就能避免这些问题。


6. 将脚本放在底部

脚本对页面的影响是:

  1. 阻塞对齐后面内容的呈现

  2. 阻塞后面组件的下载

浏览器会在下载脚本的时候阻塞并行下载,由于须要确保脚本可以顺序执行。

关于这点,这里有一篇讲解的比较深刻的文章:
JS 必定要放在 Body 的最底部么?聊聊浏览器的渲染机制

可是,实际开发中有时候很难彻底遵照这条准则,那只能把可以放在最后的都放在最后。


7. 避免使用CSS表达式

使用CSS 的expression()一般会形成屡次运算。实际上,须要用到CSS 表达式的地方,一般可以找到其余替代方案,因此避免使用CSS表达式。


8. 使用外部JavaScript和CSS

使用外部静态文件的优势有:

  1. 能够被浏览器缓存起来

  2. 组件能够重用

  3. 可模块化

  4. 可以被构建(合并压缩打版本)

  5. ...

缺点:

  1. 须要额外建立HTTP 请求

  2. ...


9. 减小DNS查找

简单来讲,DNS 查找就是输入域名对服务器IP 地址的查找过程。DNS 缓存又分为浏览器DNS 缓存、操做系统DNS 缓存。当你输入 www.google.com 的时候,浏览器会先去自身的 DNS 缓存里面查找有没有 google 服务器的 IP 地址;若是找不到则继续到操做系统的 DNS 缓存查找;若是浏览器在这两个容器都没有找到 google 的IP 地址记录,则会向广域域名体系查找。


10. 精简JavaScript

减小JavaScript 文件大小的有几种手段,一般被普遍使用的是 精简。精简就是去除JavaScript 代码中的空格、注释等多余的字符,这种方式基本上没有什么缺点。
另一种方式是 混淆。混淆是在精简的基础上,把函数、变量名都用较短小的字符来替换,从而达到减小文件大小的效果。可是混淆会产生很多麻烦,颇有可能会引入错误,虽然有利于防止逆向工程,当同时也增长了本身在线上环境调试的难度。

如今广泛的作法是发布前利用 Gulp、Grunt 等自动化构建工具对资源进行压缩。


11. 避免重定向

如下是一个重定向的过程:

浏览器发送请求  --  服务器返回302  --  服务器返回200  -- 浏览器开始呈现

就是说,在发送请求到返回200这段时间,页面彻底是空白的;对比普通的请求多了一段空白时间。


12. 删除重复的脚本

重复的脚本对增长HTTP 请求次数和脚本执行的时间。


13. 配置ETag

这个规则应该过期了,如今比较好的实践是直接根据内容给静态资源打上哈希版本号。


14. 使Ajax可缓存

适用于以上的优化,大部分一样适用于Ajax请求。


总结:

总的来讲,前端优化的整体思路是提升浏览器与服务器沟通的效率。

前端性能优化一味奉行“最佳实践”有时候反而过而不及,因此针对项目的实际状况来优化才是明智的选择。

相关文章
相关标签/搜索