【腾讯云前端性能优化大赛】前端首屏性能优化实战

在现在的网络环境下,用户访问网页时,如果首屏在3S以内是可以接受的,但是如果首屏在10S以上,绝大部分用户都不会继续等待,这样就会导致用户的流失,对于个人或者企业来说都是不可接受的,所以首屏优化已经成为网页必不可少的一部分。

以下优化针对Vue 2.X框架进行

优化方法:

(1)路由懒加载

由于Vue是单页面应用,在首次加载的时候就会加载所有的资源,资源过于多就会导致下载速度慢,直接影响了页面的首屏时间,网络较差时会导致很久打不开页面,所有可以进行路由懒加载,路由懒加载就是可以先将当前路由下的资源先加载,等到切换别的路由时再去加载对应的资源,加载的资源少了速度也就快了。

(2)关闭ProductionSourceMap

productionSourceMap是用于开发环境下进行调试错误的,能够精确到具体哪行报错,是能够让我们开发过程中很好定位错误的一个好工具,但是生产环境下是不需要开启的,反而在生产环境下开启可能会导致我们的源码泄露,所以可以在vue的配置中关闭productionSourceMap,如下

代码语言:javascript
复制
productionSourceMap: false

(3)开启Gzip压缩

如果项目比较大,打包后生成的文件就会比较大,如果每次加载页面都需要读取比较大的文件,那么就会让加载时候变得更长,所以需要将打包后的文件进行压缩:

代码语言:javascript
复制
//在vue配置中设置
productionGzip: true,
//在nodejs项目的 app.js 代码中引入
var compression = require('compression')
var app = express();
// 启用gzip
app.use(compression());

//还需要nginx的配合
#gzip
gzip on; #开启或关闭gzip on off
gzip_static on;
gzip_disable "msie6"; #不使用gzip IE6
gzip_min_length 1k; #gzip压缩最小文件大小,超出进行压缩(自行调节)
gzip_http_version 1.1;
gzip_buffers 4 16k; #buffer 不用修改
gzip_comp_level 7; #压缩级别:1-10,数字越大压缩的越好,时间也越长
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/javascript; # 压缩文件类型
gzip_vary on; #跟Squid等缓存服务有关,on的话会在Header里增加 "Vary: Accept-Encoding"        
配置完成后文件大小能被压缩至源文件的一半,甚至更多,大幅度提升了网页的加载速度。

(4)开启http2

为了保证网站传输数据的安全性,我们需要配置将http升级为https(http+ssl),而https因为安全验证等各种问题所以建立连接速度会不如http,所以我们可以将http1.1升级为http2,http2的加载速度能够提升50%以上

(5)CND加速

CDN的全称是Content Delivery Network,即内容分发网络,能够使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中。在做vue项目时可能会习惯性的在main.js中import所需的组件或插件,例如:

代码语言:javascript
复制
import Vue from 'vue'
import Vuex from 'vuex'
import element from 'element-ui'

这样所导入的组件或插件都是我们通过npm安装在项目里的,就会导致页面加载时速度十分缓慢,像elementUI这种导入了整个组件库是十分大的,我们可以将elementUI改为按需引入,例如:

代码语言:javascript
复制
import {
Card, Container, Header, Main, Aside,
Footer, Button, Menu, MenuItem, MenuItemGroup,
Submenu, Row, Col, Tag,Link,Icon,Drawer,Avatar,
Progress,Dialog,Input,Form,FormItem,Tooltip,Pagination,
Timeline,TimelineItem,Message,Dropdown,DropdownItem,DropdownMenu,
Upload,MessageBox,Alert,Breadcrumb,BreadcrumbItem,Backtop,Badge,
Tabs,TabPane,Popover
} from 'element-ui'

按需引入后文件大小能够有效的减少,但是访问起来的速度还不是理想速度,不太能满足需求,这个时候就可以将这些import全部替换为CDN连接的形式,例如:

代码语言:javascript
复制
index.html中引入
<!-- vue2 -->
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.5.0/vue.min.js"></script>
<!-- vuex -->
<script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.6.2/vuex.js"></script>
<!-- 引入elementUI组件库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.14.1/index.js"></script>
/将main.js中的import给去掉,不然打包的时候还会将引入的组件或插件进行打包
除此之外还需要在vue配置文件中配置externals
/
externals: {
'vue': 'Vue',

'vue-router': 'VueRouter',

'ElementUI': 'ELEMENT',

'axios': 'axios',

}

需要注意的是vue必须在最上方,换成CDN形式引入后访问速度提升不少,除此之外,像一些图片、JS、CSS等静态资源我们可以上传到第三方(如七牛云、腾讯云),然后通过CDN的形式进行访问,速度也能提升不少。

(6)js导入的位置问题

页面加载页面是从上往下加载的,当加载js时,会阻塞其他资源的加载直到js加载完成,所以可以将js放到最后加载,保证dom能够成功被渲染,如下:

代码语言:javascript
复制
<body>
<div id="app" ></div>
<!-- 引入Vue -->
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.5.0/vue.min.js"></script>
<!-- 引入Vuex -->
<script src="https://xwjblog.cn/cdn/vuex/3.6.2/vuex.js"></script>
</body>

如果需要将script放在head的话,可以给script加上异步async或defer:

代码语言:javascript
复制
<head>
<!-- 引入Vue -->
<script defer src="https://cdn.bootcdn.net/ajax/libs/vue/2.5.0/vue.min.js"></script>
<!-- 引入Vuex -->
<script defer src="https://xwjblog.cn/cdn/vuex/3.6.2/vuex.js"></script>
</head>

(7)图片懒加载

图片懒加载也就是图片延时加载,当访问一个页面的时候优先加载可视区域的图片,剩下的图片有需要时再进行加载,这样能减少网络请求,避免打开页面时请求过多的资源。

(8)图片优化

经过测试,带有数张图片和文本的页面明显比纯文本的页面加载速度要慢,所以当图片比较大或者数量比较多时,请求需要的时间也就长了,我们第一步可以进行图片的大小优化,在不影响图片的清晰度的前提下,尽量把图片压缩到最小。

除了压缩大小以外,我们可以选择png或者webp格式的图片:

  • png是便携式网络图片,是一种无损数据压缩位图文件格式,它的优点是压缩比高,色彩好,大部分地方都能够使用。
  • webp是谷歌推出的图片格式,它的优点是压缩率只有jpg的三分之二,大小比png小了45%,缺点是压缩时间长,兼容性不太好。

(9)预解析DNS

解析时间过长也会影响网页的首屏时间,预解析的实现:

代码语言:javascript
复制
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<!-- 用meta信息来告知浏览器, 当前页面要做DNS预解析 -->
<meta http-equiv="x-dns-prefetch-control" content="on" />
<!-- 在页面header中使用link标签来强制对DNS预解析 -->
<link rel="dns-prefetch" href="https://cdn.bootcdn.net">