前端性能优化
整体思路
加载性能
- 体量维度(工程化、代码设计):资源压缩;分包 splitChunk;externals+cdn;模块化;路由懒加载;组件化,加载最小依赖等等
- 网络维度:较少 tcp 连接次数;较少 http 请求数量;开 gzip;缓存;http-dns;
- 浏览器维度:http 缓存协议(强弱缓存)、service worker;PC 端域名发散,移动端域名收敛等等
- 业务维度:首屏 SSR,次屏浏览器渲染;懒加载,预加载;loading 无感知等等
体验性能
- 计算线程不阻塞主线程(web worker);最小局部渲染,不回流(动画 绝对定位等)
首屏 SSR,次屏浏览器渲染
首屏服务器渲染(Server Side Rendering,简称 SSR)意味着网页的首屏内容是由服务器生成的 HTML,这个过程发生在用户请求网页时。服务器渲染的主要优点是可以提升首屏加载速度,提高 SEO 效果,因为搜索引擎可以直接抓取渲染后的页面。
次屏浏览器渲染(Client Side Rendering,简称 CSR)则是指在用户滚动页面,浏览非首屏内容时,内容是通过浏览器动态生成的。这种方式的优点是可以减轻服务器压力,提升用户体验,因为用户在滚动页面时,浏览器可以立即渲染出内容,无需再次向服务器请求。
如果我们有一个新闻网站,我们可能会将新闻列表的首屏通过服务器渲染,然后将用户滚动加载的其他新闻通过浏览器渲染。
在服务器端,我们可能会有类似下面的代码:
|
在客户端,我们可能会有类似下面的代码:
|
这只是一个非常简化的示例,实际的应用会更复杂。包括错误处理、缓存、性能优化等都需要考虑。
基础优化
像代码优化,避免使用复杂的 js css 代码,善用 keep-alive,减少重复沉余操作等等基础的优化这里就不详细说啦,但同样重要!
今天主要讲一下几种优化项目的方式。
减少 HTTP 请求
不影响需求的前提下,尽可能减少 http 请求
改善响应时间最简单,最直接的途径当是较少 http 请求啦,有一些一个链接能搞定的就不要分几个链接来请求,也可以用巧用一些缓存来避免重复的 http 请求。
路由懒加载(很重要)
配置路由各位前端得伙伴应该不陌生吧,但配置路由假如用的时一般加载,如果项目得模块少还好,要是十几个,再大点几十个上百个,一下子把所有组件都加载一遍,估计等项目加载完用户都怀疑是不是网络出问题了,自己开发预览也会很难受吧。
|
其实项目编译打包后,会把每个路由组件的代码分割成一一个 js 文件,初始化时不会加载这些 js 文件,只有当激活路由组件才会去加载对应的 js 文件。
gzip 静态资源压缩
有些文件确实不能再优化了,那我们是不是可以考虑把它压缩了呢。
其实原理很简单,开启 gzip 压缩把那些大得 js,css 文件进行压缩,压缩比率在 3 到 10 倍左右,这样从服务器获取数据的时候(需要服务器配置),再由浏览器去解压加载,这样可以大大节省服务器的网络带宽,提高资源获取的速度。
因为vue中一些小的静态资源文件是会打包成 base64 的文件存在 css 中的或者 js 中,这里就是控制需要转换的大小,这样减少了 js 的大小
不同的脚手架可能配置不太一样,但都大同小异,我这里用的是 webpack,大家可以参考一下。
打开 config/index.js 文件
|
然后安装依赖:
|
打开/build/webpack.base.config.js 文件,找到 module.exports 的 module 中的 rules,把 limit 从 10000 改小一点,这里改成 1000
|
为什么要改这里呢?
因为vue中一些小的静态资源文件是会打包成 base64 的文件存在 css 中的或者 js 中,这里就是控制需要转换的大小,这样减少了 js 的大小。
服务器端(下面以 Nginx 为例)
打开配置文件
一般都会默认开启 gzip 的,但是 gzip_static 是没有开启的,所有需要加上 gzip_static on;
如果没有开启 gzip 的话可以在手动在 http{}里添加
|
webpack 的 Gzip 和服务端的 Gzip
其实服务端配置好 Gzip 就可以实现用户向服务器请求,服务器把资源压缩发送了,那为什么 webpack 也要设置呢?主要是为了减轻服务器压缩资源的负担,如果我们生产环境的资源本身就是压缩了的,那么服务器就不用压缩啦,自然就减轻了服务端的压力。建议两边都配置一下。
使用 CDN
如果应用程序 web 服务器离用户更近,那么一个 HTTP 请求的响应时间将缩短。另一方面,如果组件 web 服务器离用户更近,则多个 HTTP 请求的响应时间将缩短。
CDN(内容发布网络)是一组分布在多个不同地理位置的 Web 服务器,用于更加有效地向用户发布内容。在优化性能时,向特定用户发布内容的服务器的选择基于对网络慕课拥堵的测量。例如,CDN 可能选择网络阶跃数最小的服务器,或者具有最短响应时间的服务器。
CDN 还可以进行数据备份、扩展存储能力,进行缓存,同时有助于缓和 Web 流量峰值压力。
CDN 的缺点:
1、响应时间可能会受到其他网站流量的影响。CDN 服务提供商在其所有客户之间共享 Web 服务器组。
2、如果 CDN 服务质量下降了,那么你的工作质量也将下降
3、无法直接控制组件服务器
按需加载第三方库
有时候我们开发的页面白屏时间长,打开开发者工具,看 network 那里,一般都是 vender.js 这个资源获取时间长达几 s,第三方库一般都会打包到 vender.js ,就像我们常用到的 element.ui ,其实它的库是很大的,一般不设置都是整个库加载上来,自然加载慢了。我们可以把第三方库通过 CDN 的方式引入第三方库,这样 vendor.js 会减少,大大提升首屏加载速度,可以使用 Externals 技术,具体怎么使用大家可以搜一下,这里就不详细介绍啦。
图片压缩
这个是我自己以身示范的一个坑,在一个项目的登录界面我用了一张照片做背景,后来发现每次加载登录的界面都是超级慢,细究才发现,我这张照片 10 几 m….加载时间自然短不了,所以照片压缩很必要。