前端性能优化(一)用一张图说明加载优化

本文从加载的角度写一下前端性能优化。

需要说明的是下面这种脑暴图是按照从第一象限和第四象限的顺序来看的。

一、加载体积优化

我们无法控制用户的网络状况,既然想加载速度快,那当然是能不加载就不加载,能少加载就少加载啦。

  • 在http1.1时代合并代码是很重要的一件事儿。
  • uglify和压缩无论什么时候都重要。gzip大家都耳熟能详,brotli有可能会有些陌生,brotli有着更高的压缩率,Chrome早已支持(浏览器支持情况可查看http://caniuse.com),国内的一些云存储也支持。 如果浏览器支持你会在Accept-Encoding请求头中看到br的字样。返回的是brotli压缩的消息其Content-Encoding为br。
  • 图片压缩,以及是否做有损压缩要结合业务实际情况来决定。
  • 图片懒加载,http1.1很明显,再说全加载也浪费服务器资源。基本做法是先用一个占位的图片(也可做成背景图),当滚动到可视区域时再加载图片。
  • 为不同分别率提供提供不同尺寸图片,需要图片服务器支持裁切做起来才比较爽。
  • 如果能使用css实现优先使用css实现,一般来说这样是对的,但不绝对。
  • 减少cookie传输,大部分时候图片、css、js这些资源是不需要cookie的,所以将这些资源放在一个独立的域名下会带来减少cookie传输的好处。
  • 选择合适的图片,这个请看脑暴图。webp作为新格式在各方面都有优势,但存在浏览器兼容问题。在图片服务器支持转格式的情况下可以在前端用js判断是否支持webp并将相应参数拼接到图片url上,实现同一图片url根据前端需求加载不同格式。

二、缓存优化

  • http协议层面的优化,请看脑暴图,主要是一些请求头响应头,这些头信息可控制浏览器新鲜度验证行为。
  • 工程化角度,将不容易变的资源单独打包,有助于这类资源的长期缓存。
    Service Worker,好吧,PWA这些日子挺热的。

三、加载距离

值得说的是,这里不是物理上的距离,而是网络拓扑层面的距离。可能你和你邻居的网络距离是3000公里。

  • CDN,现在大家都在用,思考一个问题,CDN一定快吗? 答案是否定的,有可能你的宽带运营商特别坑,你在北京访问的是西藏的CDN节点,但是绝大部分是没问题的。
  • 如果你的页面是在自己公司的app内使用,那么app来帮你做预加载是很爽的,当需要打开页面的时候可以直接在本地拿到页面并打开,那会非常快。

四、加载顺序

  • 网页现在越来越庞大了,但是优先看到的一定是首屏,如果能让首屏非常快的出来其他资源慢慢加载是极好的。
  • bigpipe,这是响应优先级优化,用到了http层面的transfer-encoding: chunked,最早Facebook提出,适合的场景是页面分成很多块,每一块的数据都单独获取。为啥不用js在前端主动请求?js单线程,会阻塞住。bigpipe得提一下
    @i5ting
    ,江湖人称狼叔,来自金刚狼,他在github上有一个项目叫做bigview,是Node.js base的bigpipe封装,非常棒。
    @蒲小花
    贡献了大量代码。

五、加载链路优化

主要是httpdns,我们知道dns解释是一个很繁琐的过程,可能要与远端服务器进行很多次信息交换才能拿到IP,如果其中一个环节慢都会严重影响页面打开速速。另外,如果宽带运营商的DNS服务器很坑,你就惨了,可能根本打不开页面。更惨的是被劫持了,你都不知道用户打开的是个什么鬼东西。

针对自家app接入httpdns可以做到的是一次http请求就可以拿到IP,而且可以在app侧做缓存,这样就可以将dns解析时间缩减到0,这是一个非常爽的事儿。这也是为啥我来推动app端接入httpdns的原因。

如果各浏览器端都能接入httpdns,前端又幸福了很多。抛个问题,谁能推动这事儿?

六、http1.1与http2的差异

在加载方面http2有一个多路复用,很多云存储厂商已经支持HTTP2。

在http1.1时代我们希望请求数少,而且浏览器会对同一个域名所建立的链接数有一个限制,所以我们希望把资源分散在多台机器上。

在http2时代,请求数不是问题了,但是只有同一个域名下的资源才能使用到多路复用,所以域名要适当的做收敛。附带的好处是,由于复用同一个链接,所以http慢启动的问题就一定程度上规避了。

小结

不当以及遗漏之处欢迎指出和交流。

推荐文章