前端优化-渲染速度的优化

web前端优化–其二

继接篇一,在页面上渲染内容有几个必要条件

  • 完成html页面的下载
  • 部分完成或者完整完成dom树的构建
  • 完整的构建cssom树

如果我们想更快的让页面上显示内容,那么我们可能需要

  • 加快html页面的下载
  • 尽快的完成部分的dom树
  • 尽快的构建完成的cssom树

假如我们有一个demo

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link type="text/css" rel="stylesheet" href="a.css">
<link rel="stylesheet" href="b.css">
<script src="home.js" type="javascript/text"></script>
<title>demo</title>
</head>
<body>
<p>hello world</p>
</body>
</html>

把script放在合适的地方

在构建dom树的过程中,浏览器碰到script标签会暂停dom树的构建,并(发起下载)执行js脚本。如果可能这个时候浏览器已经构建好了完成的cssom树,并且js脚本比较复杂的话,你的页面可能会是一片空白或者是渲染出半张页面。如果你不希望这种事情发生,最好让script标签靠下,并在 < /body>标签之前

内联

demo中的css文件以外链的形式放在link标签里,这在我们的项目里也很常见。但是发起一个http请求往往会消耗十几ms或几十ms(假定Http协议为1.1或以下)的连接消耗。把css内联到html文件里或许是一个不错的选择,除了不用发起http请求之后,cssom也可以更快的构建完成。
不建议内联的css(或Js)文件太大,毕竟内联意味着无法被缓存。当然,js文件也适用于这个规则。

web几乎所有文件都存储在互联网上。每一次请求,都可能需要从千里之外的去下载他们。这并不容易,也很耗时。有必要找点方法来缩减一下他们的大小。

使用压缩工具
  • 未压缩过的文本资源可能会有点大。有很多流行工具可以帮我们去完成压缩工作,压缩后的文本资源往往只有原来的20%~30%。这已经是一个非常大的进步了,常见的压缩工具
  • html –> html-webpack-plugin
  • javascript –> UglifyJs
  • css –> optimize-css-assets-webpack-plugin
    gzip
    gzip是一项流行的压缩技术,往往能帮我们减少60%~80%的文件大小。虽然他可能会使用掉我们一点点cpu,在现在的cpu处理能力下往往不会是什么负担。现在,拥有了压缩工具和gzip的利器之下,假如原文件有1000kb,那么他现在只有(1000 0.3) 0.3 ≈ 100kb。只有原来的十分之一左右的大小,这是很可观的优化了。
字体

字体也是可以被压缩的,在我们生成字体文件的时候或者使用字体文件的时候,应该要压缩他们。并且,部分字体是支持gzip的。

另外,我们大部分情况下可能并不需要使用到字体库中全部的字。这种情况下我们就可以使用诛如 字蛛 这些子的工具来截取我们用到的字,并生成新的字体文件。这种优化在汉字库的时候往往非常明显,因为一个汉字库往往可以达到几m或十几m的大小。

css

生成cssom是比较消耗资源的,我们在chrome devtools中很容易看出来。需要注意的是

  • css 解析一半的消耗在于匹配css规则
  • 另一半时间用于从匹配的规则中构建 RenderStyle

如果你的css解析时间比较久,请注意是否使用了多过的、过于复杂的 css规则,或者你的css样式绘制时比较消耗性能,如 font-shadow。如果需要样式计算的dom元素太多,也会消耗比较久的时间。

media

我们常常会使用media,或者是 Print,或者是响应式布局。如下面的demo,如果浏览器还是会下载a、b、c三个文件,但是如果你是在pc端打开这个页面,浏览器只会解析c.css,省掉了另外两个文件的解析。
如果css里有比较多的类似规则,可以试试将他们分开。

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo</title>
<link rel="stylesheet" href="a.css" media="print">
<link rel="stylesheet" href="b.css" media="screen and (max-width:320px)">
<link rel="stylesheet" href="c.css">
</head>
<body>

</body>
</html>

js

和css一样,解析js也是需要消耗大量的资源的,如果你的js太多复杂。
虽然我们可以压缩文件大小,但是压缩文件大小并不能减少解析时间。
尽量不要让js太过复杂,或者可以分割它们。

pre-*

我们还可以在head中添加 link标记来优化一下我们的资源加载

  • preload 浏览器在看到preload 的时候会发起异步请求下载资源,以便让资源尽快可以使用。如果你使用了自定义的字体,那么使用preload可能是一个不错的选择。另外,如果你下载的资源3秒内没有被使用,会被浏览器红牌警告噢。
  • prefetch 浏览器发现 prefetch标识,但会在浏览器认为自己空闲的时候去下载。如果prefetch下载了一半,另外一个href或者src发起了请求,那么很可能会造成两次下载。
  • dns-prefetch 浏览器发现 dns-prefetch,预先去解析域名并缓存,这样浏览器在请求同域名其他资源的时候,就能省去域名解析的步骤。因为dns-prefetch和http2的存在,不建议在网站中使用太多的资源域名

  • preconnet。 dns-prefetch 的升级版, dns-prefetch只预先解析域名,preconnet会预先打开整个链接。不过浏览器支持比dns-prefetch差很多。

Pre家族往往都是很实用的功能,特别是dns-prefetch,你几乎可以在任何主流网站里看到他。

defer/async

之前我建议把javascript往向靠,或者放在合适的地方。还有另外一种解决方案,在script标签中添加 defer 标识。浏览器会延迟下载 脚本,不过会保证在 < /body> 之前完成js的下载与解析。
事实上我们的网页里可能还会有一些js、他们可能并不重要,或者并不依赖其他脚本,那么强烈建议加上async。加上async意味着这个script他不阻止我们的dom构建,意味着我们的首屏渲染更快了。

升级http2

http2协议在传输方面做了很大的修改提升,详见http2篇

图片的优化

今天先到这里。