前端优化之 Http 相关优化总结

Http 优化方式是前端性能优化的重要部分,也是前端必备的知识点之一。javascript

减小静态资源文件大小

这个是最根本的途径,假设真的有个 10 几兆以上的静态资源文件,不减小大小的状况下,即便优化作到了极致,用户体验也好不了哪里去。css

若是整个网页就 2KB 大小的资源文件,不优化都很快。html

代码层优化

  • 只打包用到的依赖包,目前 webpack tree shaking 功能已经自动处理了,还有尽可能少使用第三方依赖包(固然看状况啦)。
  • 代码分割(code splitting),不一样页面加载本身用到的代码,不加载其余页面的代码(其实也属于懒加载)。

传输层优化

Http 传承启用压缩传输方式。前端

通常咱们开启 gzip,基本都能压缩 6 倍左右(通常都是文件越大,字符串类似率越大,压缩率越大)。java

首先通过服务器压缩后,而后 Http 响应头 Content-Encoding 设置为相应的压缩方式,浏览器会自动解压的。webpack

Content-Encoding: gzip
复制代码

固然还有其余的压缩方式,如 compress、deflate 等等,目前使用最广的仍是 gzip。web

适当合并或者分散请求

合并请求或者分散请求须要看实际状况的。算法

合并请求

http 1.1 (包括 http1.1)以前的版本,浏览器存在同域名并发限制,谷歌目前是同域名并发如今为6 个请求,其余的浏览器或多或少,但也差不了多少。segmentfault

若是是使用的是 http1.1 web 服务,那么咱们首次加载的资源要基本保证在 4 个之内,因此静态资源请求数过多就要看状况进行合并请求了。浏览器

分散请求

Http2.0 没有同域名并发的问题,咱们能够适当分散请求。固然若是在 Http1.1 一个资源文件过大,而后并发并无达到限制,也能够拆分资源文件达到分散请求的目的。

使用预加载

预加载某些状况下能够大大提高加载速度进而提示用户体验。

预加载须要了解 preloadprefetch 的知识。

预加载 DNS

dns 解析也是须要时间的,特别在移动端的时候更明显,咱们能够预解析 dns 减小不通域名 dns 解析时间。

<link rel="dns-prefetch" href="//example.com">
复制代码

其实还有个 preconnectpreconnect 不只完成 DNS 预解析,同时还将进行 TCP 握手和创建传输层协议,可是浏览器有兼容性,目前用不上。

<link rel="preconnect" href="http://example.com">
复制代码

预加载静态资源

使用 preload

经过 preload 通常是预加载当前页面要用到的图片、字体、js 脚本、css 文件等静态资源文件。

场景一

若是须要,你能够彻底以脚本化的方式来执行这些预加载操做。例如,咱们在这里建立一个HTMLLinkElement 实例,而后将他们附加到 DOM 上:

var preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);
复制代码

这意味着浏览器将预加载这个JavaScript文件,但并不实际执行它。

若是要对其加以执行,在须要的时候,你能够执行:

var preloadedScript = document.createElement("script");
preloadedScript.src = "myscript.js";
document.body.appendChild(preloadedScript);
复制代码

当你须要预加载一个脚本,但须要推迟到须要的时候才令其执行时,这种方式会特别有用。

场景二

字体是要使用到的时候才会去加载字体的(若是字体是自定义的字体,会发起 Http 请求加载字体)。

因为这个特性,咱们能够预加载字体,待使用到字体的时候,字体已经加载完毕,无需等待加载。

以下咱们没有 preload 的时候,代码也是能够运行的,可是字体加载是须要等待页面 JS、CSS 资源加载完毕后,当前页面使用到字体才会去加载的:

<style> @font-face { font-family: Test-Number-Medium; src: url(./static/font/Test-Number-Medium.otf); } </style>
复制代码

咱们加上:

<link rel="preload" href="./static/font/Test-Number-Medium.otf">
复制代码

就能够提交加载,节省大部分甚至所有的字体加载时间,通常都是所有的时间,由于 JS 资源文件比字体大多了(并行下载,最长的资源加载时间,决定了最大加载时间)。

使用 prefech

prefetch 通常是预加载非当前页面的资源,prefetch 是一个低优先级的资源提示,容许浏览器在后台(空闲时)获取未来可能用获得的资源,而且将他们存储在浏览器的缓存中。当前页面加载完毕,才会开始下载 d带有 prefetch 标记的资源,而后当用户进入另一个页面,已经 prefetched 的资源能够马上从缓存中加载。

不过 prefech 的应用场景比较少。

<link rel="prefetch" href="/uploads/images/pic.png">
复制代码

采用懒加载

图片懒加载

这种作法通常都是在用户滚动到响应位置(固然从用户体验式来讲,须要提早一点加载),才会加载响应的图片,图片特别多的网上基本都会作这个优化(如视频网站)。

或者幻灯片查看图片的时候,用户即将查查下一张图片的时候再加载,而不是一次性加载所有的图片。

JS 懒加载

须要用到相关 JS 时,经过动态建立 <script> 标签进行 JS 文件懒加载,如 Webpack 的 code splitting

合理使用 defer 和 async

带有 deferasync 属性的 script 资源都会并行下载,并且不会影响页面的解析,从而达到了节省脚本下载时间

两种的不一样的在于:

带有 defer 属性的资源会按照顺序在页面出现的属性,资源加载完后,会在 DOMContentLoaded事件调用以前依次执行。

带有 async 属性的资源则是下载完当即执行,可能在 DOMContentLoaded 事件以前或者以后执行,多个带有 async 属性的资源无执行顺序,谁先加载完成,谁先执行。

那么为何能够节省下载时间?咱们来对比一下。

defer 资源加载相似于把 <script> 放在 </body> 前,可是 defer 资源能够和 <head> 的资源并行下载,那么就能够节省部分甚至所有的下载时间(看 <head> 资源和 defer 资源大小)。因此咱们何以适当的把 defer 资源放在 <head>,某些场景是能够提高必定的速度。

async 资源有点相似于 </body> 前的 script 资源加载完成后,动态建立 <script> 标签加载资源,可是却要等待页面 JS 文件执行以后才能够加载,而 async 资源无需等待便可提早加载,就能够节省必定的加载时间。因此比较适合加载如谷歌分析百度统计日志上报等类型的 js 资源,都是独立运做也不影响页面的辅助 js 资源。

利用缓存

缓存对于再次访问相同资源来讲,是个极大的优化,缓存是 http 优化的必经之道。对于 css 和 js 这些静态资源文件,咱们通常都是用强缓存(例如缓存30天),强缓存无需再次向服务请求静态资源。 可是强缓存若是使用不当,那么会对用户形成意想不到的 bug,如入口 html 文件就不能被强缓存了,不然版本更新后,用户在缓存期间是没法访问到新版的页面。

详细能够看下本人的另外一篇缓存相关的文章,浏览器之HTTP缓存的那些事

使用 Http2.0

Http2.0 多路复用解决了多域名并发如今问题,能够节省资源整体的下载时间,还有请求头压缩和差别传输也会提升传输效率。

多路复用

HTTP1.1 持久链接解决了链接复用问题,但仍是存在着一个问题,一个 TCP 没法并发处理请求:在一个 TCP 链接中,同一时间只可以发送一个请求,而且须要等响应完成才可以发送第二个请求。

HTTP2.0 使用了多路复用的技术,作到同一个链接并发处理多个请求,并且并发请求的数量比 HTTP1.1 大了好几个数量级。

固然 HTTP1.1 也能够多创建几个 TCP 链接,来支持处理更多并发的请求,可是建立TCP链接自己也是有开销的。

TCP 链接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。所以对应瞬时并发的链接,服务器的响应就会变慢。因此最好能使用一个创建好的链接,而且这个链接能够支持瞬时并发的请求。

多路复用能带来哪些优化呢?

有多路复用特性,那么浏览器对同一域名的连接数的限制也是不必的了(HTTP1.1 的谷歌对统一域名并发请求最多支持 6个 持久连接)。

那么咱们能够根据实际状况进行资源拆分,从而节省下载时间,无并发请求限制的状况下,下载的时间是根据并行下载的最长时间来算的,无需等待上一个资源下载,才能进行另一个资源的下载,在资源比较多的状况下,这将大大提高资源整体的下载速度。

之前的 CSS 的雪碧图 优化手段,在多路复用的特性下,已是不必的了。

多路复用还带来了,延迟低的优化,这也是速度提高的一方面。

二进制分帧

在应用层与传输层之间增长一个二进制分帧层,以此达到在不改动 HTTP 的语义,HTTP 方法、状态码、URI 及首部字段的状况下,突破 HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。

在二进制分帧层上,HTTP2.0 会将全部传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中HTTP1.x 的首部信息会被封装到 Headers 帧,而咱们的 request body 则封装到 Data 帧里面。

首部字段压缩

HTTP2.0 使用 **HPACK **算法对首部字段的数据进行压缩,这样数据体积小了,在网络上传输就会更快。

首部字段差别传输

HTTP2.0 规定了在客户端和服务器端会使用而且维护首部表来跟踪和存储以前发送的键值对,对于相同的头部,没必要再经过请求发送,只需发送一次。

事实上,若是请求中不包含首部字段(例如对同一资源的轮询请求),此时服务器自动使用以前请求发送的首部字段,那么首部字段开销就是零字节。

若是首部发生变化了,那么只须要发送变化了数据在 Headers 帧里面,新增或修改的首部帧会被追加到首部表首部表在 HTTP2.0 的链接存在期内始终存在,由客户端和服务器共同渐进地更新。

使用 CDN

严格意义上,CDN 不算 Http 优化,前端也没法直接处理这个事情,这是运维的事。CDN 节点能够解决跨运营商和跨地域访问的问题,提高访问速度。

CDN的全称是 Content Delivery Network,即内容分发网络。CDN 是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,经过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,下降网络拥塞,提升用户访问响应速度和命中率。CDN 的关键技术主要有内容存储和分发技术。—— 科学百科

CDN 有什么优点?

CDN 最大的优点在于提高用户资源访问速度,所以静态资源走 CDN 是一个很好的优化点。 分布式服务器,用户就近访问,CDN 节点能够解决跨运营商和跨地域访问的问题,同时分散源服务器访问压力。

还有一个而外的优势: 无 cookie 传输(其实这个不彻底算是优点)。静态资源通常无需 cookie,静态资源放在不一样域名能够减小必定程度的带宽和提高必定的访问速度,虽然单个请求不明显,可是量多了是会有质的区别的。

CDN 是如何分散源服务器的压力的?

CDN 的核心点有两个: 一个是缓存,一个是回源。

经过缓存和回源策略,达到分散源服务器的压力。首先将从根服务器请求来的资源按要求缓存。而后当有用户访问某个资源的时候,若是被解析到的那个 CDN 节点没有缓存响应的内容,或者是缓存已经到期,就会回源站去获取。

相关文章
相关标签/搜索