前端性能优化

衡量网站的性能的指标有很多,其中有项重要的指标就是网站的首屏时间,为此前端工程师们都是绞尽脑汁想尽办法进行优化自己的应用,诸如像服务端渲染,懒加载,CDN 加速,ServiceWorker 等等方法。

性能优化应该从哪些角度去考虑优化?

1.减少资源的大小(压缩资源)
2.减少请求资源的次数(使用缓存)
3.优化资源的加载方式(异步加载)
4.优化资源的加载时机(懒加载)

一、压缩、合并资源

压缩资源就是把文件中存在的空格、换行符、制表符、注释等全部删除,从而减少了各个文件的大小,有利于请求速度优化。

压缩的资源包括html文件、css文件、js文件。
压缩方法:html-minifier工具(Node.js中提供)、uglifyjs2压缩工具。
gzip 压缩:即将需要传输的内容压缩后传输到客户端再解压,这样在网络上传输的 数据量会大幅减小。通常在服务器上的Apache、Nginx可以直接开启这个设置,也可以从代码角度直接设置传输文件头,增加gzip的设置,也可以从 负载均衡设备直接设置。不过需要留意的是,这个设置会略微增加服务器的负担。

对css和js的压缩收益要高于html的压缩,因为css和js代码量相对html多出很多,所以有些大公司会选择忽视html的压缩。

文件合并:

多个css合并为一个文件、多个js文件合并为一个文件可以减少网站http请求的次数,但合并文件可能会带来问题:首屏渲染(多个文件合并导致一个http请求过大,请求时间过长)和缓存失效问题(合并后任何一个文件的修改都会导致缓存失效)。
如何进行文件合并?
使用在线网站进行文件合并
使用nodejs实现文件合并(gulp、fis3)

二、异步加载

https://www.jianshu.com/writer#/notebooks/45991390/notes/77270682

三、使用浏览器缓存

https://www.jianshu.com/writer#/notebooks/45991390/notes/77279680

四、使用CDN

现在国内做CDN加速业务的公司很多,简单讲,就是将你的图片、视频扩散到CDN网络所能到达之处,让用户访问时能就近下载到这些文件,从而达到网络提速的目的,这样做,同时能减轻你自己网站的负载。

五、资源预加载

不同的资源加载的时间点可能不一样,有的资源在当前页面需要加载使用,有的资源可能在后面加载其它页面的时候要用到。而如果我们通过某种技术提前告诉浏览器,后面会用到哪些资源,这些资源需要你提前加载好。这种技术就是资源的预加载。

资源预加载又可以拆分为不同的点:dns预解析preloadprefetchprerenderpreconnect

dns预解析:
我们知道通过域名访问站点,都要进行DNS解析,而一次DNS解析大概在20-120ms之间。每次访问新的地址,如果都进行dns解析,花的时间就多。而使用dns-prefetch这个技术就能提高访问速度,减少访问时间。此技术可以让当前网页中设置了dns-prefetch属性的域名在后台进行预解析,并缓存解析结果,当点击网页中的链接时,就不需要每个链接再进行dns的解析,可以节省解析时间。
默认情况下浏览器会对与当前域名(正在浏览网页的域名)不在同一个域的域名进行预获取,并且缓存结果,这就是隐式的 DNS Prefetch。如果想对页面中没有出现的域进行预获取,那么就要使用显示的 DNS Prefetch了。
预解析的实现:在文档的标签内加上下面的代码:




...
隐式预解析:浏览器默认会对与当前网页域名不一致的域名进行预解析,并缓存解析结果。
显示预解析:对当前页面中没有出现的域名进行预解析。
需要注意的是,虽然使用 DNS Prefetch 能够加快页面的解析速度,但是也不能滥用,如果想禁止隐式的预解析,可以这样写,


此技术浏览器的支持情况:
Firefox: 3.5+
Chrome: Supported
Safari 5+
Opera: Unknown

preload:顾名思义,浏览器渲染引擎渲染之前先提前加载的意思。向浏览器声明此资源需要提前加载,而不是在需要它的时候才去加载。提前加载的资源不会立即使用,而是等需要用到的时候再使用。一般,preload用来加载最重要的资源,css、js、图片、字体文件等。
使用方式:在link标签中使用rel='preload'或者动态创建一个link标签。如果预加载需要CORS跨域请求,需要加上crossorigin属性。

<--动态创建>
const link = document.createElement('link')
link.rel = 'preload'
link.href = 'css文件'
document.head.appendChild(link)
兼容性:根据 caniuse.com 上的介绍:IE 和 Firefox 都是不支持的,兼容性覆盖面达到 73%。
如何检测不同浏览器对rel='preload'的支持性?
const preloadSupport = () =>{
const link = document.createElement('link')
const relList = link.relList
if(!relList || !relList.supports){
return false
}
return relList.supports('preload')
}
preload的好处:
1.可以让前端开发者优化指定资源的加载,即使用了preload会提高资源被下载的优先级;
2.赋予浏览器决定资源类型的能力,因此它能分辨这个资源在以后是否可以重复利用。
3.浏览器可以通过指定 as 属性来决定这个请求是否符合 content security policy
4.浏览器可以基于资源的类型(比如 image/webp)来发送适当的 accept 头。

prefetch:提前告诉浏览器未来可能会使用某些资源,浏览器可以在空闲时间去加载这些资源,并将资源存储到浏览器的缓存中。当后面用户点击带有prefetch指令的链接时,就直接从缓存中拿取资源。
用法:

image.png

preload与prefetch的比较:前者是对当前页面所需资源的提前加载,后者是对其它页面所需资源的加载。
疑问:prefetch这种加载方式,是对整个项目所有的其它页面资源全部加载还是只加载部分其它页面资源?如果是只加载部分页面资源,浏览器是怎么知道要加载哪些其它资源的呢?

prerender:与prefetch类似,区别是prerender在后台把整个页面都渲染好了。
用法:
要小心的使用 prerender,因为它将会加载很多资源并且可能造成带宽的浪费,尤其是在移动设备上。还要注意的是,你无法在 Chrome DevTools 中进行测试,而是在 chrome://net-internals/#prerender 中看是否有页面被 prerendered 了,你也可以在 prerender-test.appspot.com 进行测试。

preconnect:在发送http请求的过程中,preconnect允许浏览器对DNS解析、TLS协商、TCP连接做一些处理,消除请求过程中往返路径,从而达到了减少请求时间的目的。

六、懒加载

对一些使用图片数量很大的页面,尽量使用懒加载。在图片进入可视区域后,才去加载图片。

七、预渲染

我们默认的开发方式是通过客户端渲染,但是客户端渲染页面内容,关键链路较长,首屏渲染会有一定延迟.
简单说,就是将需要通过浏览器解析 javascript 动态渲染生成页面的这部分工作,webpack 通过使用 prerender-spa-plugin 插件在打包阶段生成静态结构的 html,最后直接输出HTML页面给浏览器,浏览器再进行渲染。

服务端渲染(SSR):是在接受客户端请求后,解析执行相应的js代码,生成HTML页面,最后发给客户端,由客户端进行解析渲染。事实上,在前后端还没分离的年代,在服务器端渲染 HTML,才是最普遍的做法。

八、Service Worker

ServiceWorker 是运行在浏览器后台进程里的一段 JS,它可以做许多事情,比如拦截客户端的请求、向客户端发送消息、向服务器发起请求等等,其中最重要的作用之一就是离线资源缓存。

参考资料:
https://juejin.im/post/6844903608253693960#heading-17
https://juejin.im/post/6844904195707895816#heading-9
https://juejin.im/entry/6844903704152244238
https://juejin.im/post/6844903562070196237#heading-5
什么是preload?https://www.keycdn.com/support/preload-directive
什么是prefetch?https://www.keycdn.com/support/prefetching
什么是preconnect?https://www.keycdn.com/support/preconnect

你可能感兴趣的:(前端性能优化)