如果不是不可能,你也很难拒绝承认性能目前已是任何正规网站项目的最关键方面之一,无论它是一个小型的网站组合,一个移动优先的web应用,一直到一个大规模的商业项目。研究,论文和个人体验都告诉我们快速是最好的。
性能不仅仅是非常重要,它也相当的有趣,而且这也是我越来越投入的事,不仅在工作方面(我一直在烦我们的首席性能工程师),也在项目与CSS魔法网站方面(我一直在烦Andy Davies)。
在这篇长文章中,我将分享收获,关于快速,简单且非常有趣的性能知识的点点滴滴,以便使你的行为可以像一个初级的网页设计师和前端开发者;希望对任何想开始学习性能的人,这篇文章可以成为一个正规的介绍,并使它们的前端变得超快。这些技巧是你能非常容易实现的。它只需要一点小技巧,以及一些浏览器怎样工作的基础知识,你就能开始玩转系统了!
这篇长帖子不会讲到模糊图像的加载和数据处理,取而代之的是有关理论与第一手的性能方面的技术资料,这些技术是我通过阅读,观察,搜集和整理获得的(我花费了许多时间沉浸于CSS魔法的瀑布图)。我也会链接到其它相似话题的文章,以便帮助强化一些关键要点。享受吧!
注意 本文需要预先知晓一些基础的性能知识,如果有任何你不熟悉的就Google搜索一下好了!
关于性能,有一些知识在所有的设计师和前端开发者中广为传播。例如,尽可能少的请求,优化图片,把样式表(stylesheets)放在<head>, 把JS放在</body>之前, 最小化(minifying) JS 和 CSS 等等。这些基础知识已经被用来加快用户响应了,但还有更多更多需要学习。
虽然在我们每天的工作生活中,浏览器给我们制造麻烦,使我们头疼,但请记住,他们也是很聪明的; 它们为我们做了很多性能优化工作, 所以大量的性能调优知识不但要知道浏览器在哪里给我们做了优化,还要知道怎么更好的挖掘它们。大量性能调优诀窍只是理解,利用和操纵浏览器已经替我们做好的优化工作。
其它翻译版本 (1) 加载中这真的是一条基本规则,每个人都能非常容易的在大多数时间遵守,但为什么它重要?简短的说:
CSS块渲染是因为浏览器总是试图渐进式的渲染页面;它们想在元素到达的时候顺序的渲染它。如果style在距离很远的页面下部,浏览器在获得它之前没有办法渲染那个CSS。因为这个原因,如果浏览器在渲染文档过程中,改变了之前渲染的东西,它们可以避免style的重绘。浏览器在它获得所有需要的style信息之前不会渲染页面,如果你将style放在文档底部,你就是在使浏览器等待,阻塞了渲染。
所以,只要你将CSS放在页面的顶部,那么浏览器就可以立刻开始渲染。
JavaScript块下载是由于好几个原因(这又是浏览器聪明之处),但首先我们需要知道浏览器里的资源下载是如何实际发生的;简单的说,浏览器会从一个单一的域名并行的尽可能多的下载资源。它从越多的域名下载,就能在一瞬间并行的获得更多的资源。
JavaScript中断了这个过程,阻塞了从任何一个域名的并行的下载,因为:
所以,由于浏览器在获取JavaScript的时候停止了所有其他下载,将你的JavaScript脚本放在文档中尽可能晚加载的地方是一个好主意。我相信你们都看到过页面中的空白片段,在那里第三方的JS脚本被花时间加载,并且它还阻止了页面其他资源的获取和渲染;这就是JavaScript的阻塞在作用了。
但是显然,现代浏览器还是变得聪明了。我将给你一个Andy Davies寄给我的电子邮件的摘录,因为他解释的比我清楚:
现代浏览器将并行下载JS,只有在脚本被执行的时候阻塞渲染(显然脚本必须也被下载了)。
脚本下载常常被浏览器的预加载器所完成。
当浏览器页面渲染被阻塞,即等待CSS,或JS被执行,预分析器将扫描页面剩余部分,寻找它能下载的资源。
有些浏览器如 Chrome, 将分先后下载资源,例如,如果脚本与图片同时在等待下载,它将先下载脚本。
漂亮的内容!
所以,要使页面被尽可能快的渲染,将styles放在顶部。为了阻止JS的阻塞影响到渲染,将scripts放在底部。
另一个明显而基本的性能优化方法是少下载。页面需要的每一个资源就是一次额外的HTTP请求;浏览器不得不停下来去获取每一个用于渲染页面所需的资源。每一次HTTP请求都可能引发DNS查询,重定向,404,等等。每一次HTTP请求,无论为了样式表,图片,web字体,JS文件还是其它你能想到的,都可能是一次非常昂贵的操作。尽量减少这些请求是你可以做的最快的优化方法中的一种.
再谈到浏览器和并行;大多数浏览器一次只从每个引用的域下载一些资源,而JS会阻塞这些下载。所以,你做的每一个HTTP请求都应该仔细考虑,而不是随便随便做的。
为了让浏览器能并行的下载更多资源,你可以由不同的域名提供服务。如果说,浏览器只能一次从一个域名获取两个资源,那么由两个域名提供服务意味着它可以一次性获取四个资源;三个域名意味着六个并行下载。
许多网站有静态/资源 域名;你可以发现, Twitter, 用 si0.twimg.com 来做静态资源:
<link rel="stylesheet" href="https://si0.twimg.com/a/1358386289/t1/css/t1_core.bundle.css" type="text/css" media="screen">
Facebook 用fbstatic-a.akamaihd.net:
<link rel="stylesheet" href="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yi/r/76f893pcD3j.css">
通过这些静态的资源域名, Twitter与Facebook能提供更多的并行资源服务;来自twitter.com和si0.twimg.com的资源可以协作方式下载。这真的是使你的页面上获得更多并发下载的简单方法,如果再加上实际的CDN技术就会更好,CDN技术通过从一个更加合适的物理位置提供资源服务的方法来减少延迟。
这全部都很好,但后面我们将讨论在特定环境下,怎样从子域名提供服务却会实际上对性能有害。
因此,现在有了我们关于性能的基础知识:
每当你从任何域名请求一个资源,会发出一个带有相关头部,被访问资源的 HTTP请求,并且会返回一个响应。这是对该过程的一个极端简化,但它基本就是事实上你需要知道的。这是一个HTTP请求,而且所有涉及的资源都从属于这个往返的旅行。当提到前端性能,这些请求正是主要的瓶颈所在,因为如我们谈到的,浏览器受限于有多少请求可以并行发生。这也是为什么我们经常要使用子域名;以便允许这些请求在数个域名上发生,允许同时发生多得多数量的请求。
然而关于这还有个问题,DNS查询。每次(从一个空缓存)一个新的域名被引用,HTTP请求会受制于一个耗时的DNS查询(某个介于20到120毫秒之间的值),在DNS查询中,发出的请求会查询资源实际存在的地点;互联网通过IP地址被绑定在一起,这些地址由DNS管理的主机名引用。
如果每个引用的新域名具有DNS查询的前端代价,你必须确保这个代价确实是值得的。如果是一个小网站(例如像CSS魔法),那么由子域名提供资源可能并不值得;相比执行多个域名的DNS查询并将其并行化来说,从一个域名非并行的获取若干资源,浏览器可能更快。
如果你或许有一打资源,你可能会考虑从一个子域名提供它们的资源服务;为了更好的并行化那许多资源,额外的DNS查询可能是值得的。如果说你有40个资源,可能将那些资源切分到两个子域名是值得的;为了由总数为三个的域名提供你的网站服务,两个额外的DNS查询会是值得的。
DNS查询代价很高,因此你需要决定什么才是对你的网站更合适的;承担查询的消耗或者只是由一个域名提供所有服务。
很重要的需要记得的是,比方说一旦HTML被请求于foo.com,对那个主机的DNS查询就立即发生了,所以后续的任何对foo.com的请求不再受制于DNS查询。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务