## 2. webpack3.x优化首屏加载速度
首先要说明一下,首屏加载速度优化针对的是打包后dist文件。我们如果要在本地进行测试的话,需要本地有个服务器,我们在这里使用nginx。
### 2.1 本地安装nginx
> 下载地址: http://nginx.org/en/download.html
在官网上找到自己系统适合的nginx版本,下载到本地
#### 2.1.1 window安装
1. 解压文件
2. 双击运行nginx.exe,在任务管理器中出现nginx的进程,则表示安装成功
#### 2.1.2 mac/linux安装
```js
#1.解压文件
tar -xzf nginx-1.14.0.tar.gz #mac可以使用解压缩工具解压,不必用命令行
#2. 配置安装路径 --prefix指定安装路径 假设我要装到/usr/local/nginx文件夹中
./configure --prefix=/Users/best9/local/nginx
#编译
make
##安装
make install
```
安装完成后进入到`—prefix`指定的文件夹中,执行``ll``,会发现文件夹下有以下目录
![image-20190308144717721](https://ws3.sinaimg.cn/large/006tKfTcgy1g0vdxqhlucj30o106ijt9.jpg)
我们要关心就是我上面标出来的三个目录
进到sbin目录中,启动nginx程序
![image-20190308145219037](https://ws2.sinaimg.cn/large/006tKfTcgy1g0ve2yl4dpj30nc02n74x.jpg)
```shell
cd sbin
#需要使用root权限,否则会报错 报错信息可以在日志中查看到,错误日志目录 /logs/error.log
sudo ./nginx
```
正常的话,nginx会默认在localhost:80端口启动,在浏览器访问`localhost`,就会显示默认界面
![image-20190308145304691](https://ws3.sinaimg.cn/large/006tKfTcgy1g0ve3qpbxwj317w08tmz3.jpg)
如果电脑的80端口被占用的话,在`conf/nginx.conf`文件中修改端口
### 2.2 nginx常用命令
nginx使用-s发送信号操作运行中的进程,常用命令如下:
注意:使用命令需要在`sbin`目录下
```shell
#启动nginx
./nginx
#立即停止服务 -s stop
./nginx -s stop
#优雅地停止服务 -s quit
./nginx -s quit
#重启服务 -s reload
./nginx -s reload
```
### 2.3 nginx配置静态文件服务器
> 我们在这里使用nginx配置一个最简单的静态文件服务器,更复杂的配置稍后再讲
nginx的配置文件地址:`conf/nginx.conf`
使用vim或者其他编辑器打开该文件,修改配置文件第43-45行:
`vim conf/nginx.conf`
![image-20190308150902046](https://ws1.sinaimg.cn/large/006tKfTcgy1g0vekd2vjqj30sw070myh.jpg)
```js
location / {
alias /Users/best9/github/vue2_template/dist; #访问/相当于访问alias配置的目录
}
```
配置完成后保存,然后重启服务
`sudo ./sbin/nginx -s reload` 要使用root权限重启
打开浏览器访问localhost
![image-20190308151058193](https://ws4.sinaimg.cn/large/006tKfTcgy1g0vemd5s6kj31fa0bmq4j.jpg)
因为没有登录,会自动跳转到登录界面
到这里静态文件服务器就配置好了,但我们刷新下页面,会报错404
![image-20190308151213416](https://ws4.sinaimg.cn/large/006tKfTcgy1g0veno2zb1j3102068t9i.jpg)
这是因为我们使用了vue router的history模式,我们需要在nginx中加入以下配置
![image-20190308151523068](https://ws4.sinaimg.cn/large/006tKfTcgy1g0veqyg70ij30ry0390ta.jpg)
```nginx
location / {
try_files $uri $uri/ /index.html;
}
```
然后重启nginx,再刷新页面就没问题了
### 2.4 优化首屏加载速度
以上步骤就绪后,我们就可以来优化加载速度了
打开chrome的devTools面板,切换到`Network`,禁用浏览器缓存,刷新测试下加载速度,发现整个应用加载大约需要1.97s,如下图:
![image-20190308152853851](https://ws4.sinaimg.cn/large/006tKfTcgy1g0vf50s2ioj31g70et43b.jpg)
把网络环境切换到`Fast 3G`,再测试一次,发现加载用了7.56s,白屏时间6.89s
![image-20190308165101522](https://ws2.sinaimg.cn/large/006tKfTcgy1g0vhihond1j31uy0pq477.jpg)
我们使用预渲染插件进行优化
#### 2.4.1 预渲染
> 使用插件:prerender-spa-plugin
>
> 参考链接:https://juejin.im/post/59d49d976fb9a00a571d651d
首先,安装 `prerender-spa-plugin`,安装时件略长,因为其依赖了 `phantomjs`
```
cnpm install prerender-spa-plugin --save-dev
```
我们只在生产环境中进行预渲染,修改` build/webpack.prod.conf.js`,在配置插件的地方加入如下代码。
```js
//引入 预渲染插件
const PrerenderSpaP=require('prerender-spa-plugin')
//在plugins中配置
new PrerenderSpaP(
// 输出目录的绝对路径
path.join(__dirname,'../dist'),
//预渲染路由
['/home','/login']
)
```
再次执行打包,然后再进行测试:
![image-20190308165347855](https://ws2.sinaimg.cn/large/006tKfTcgy1g0vhld1i5gj31r40noah7.jpg)
发现白屏时间为4.10s,在弱网环境下,使用预渲染,大约能缩减2.5秒的白屏时间
##### 预渲染注意事项
* 预渲染的路由不能是动态加载的,否则会报webpackJsonp is not define的错误,要想解决这个错误,可以看这里 https://juejin.im/entry/5911a487ac502e450284caf8
* 预渲染的路由不能是需要权限才能访问的页面。预渲染的机制是在本地跑一个chromium浏览器,然后去爬取你预渲染页面的Html,如果你的页面需要权限(登录)才能进入,就爬不到,也不会报错,最终只会渲染不需要权限的页面
举个例子:
插件配置如下:
```js
new PrerenderPlugin({
staticDir:path.join(__dirname,'../dist')
routes:['/','/about','/login']
})
```
路由配置如下:
![image-20190314164834830](https://ws1.sinaimg.cn/large/006tKfTcgy1g12f5temc6j31320u0wle.jpg)
#### 2.4.2 配置gzip压缩
> gzip官方文档 http://nginx.org/en/docs/http/ngx_http_gzip_module.html
nginx默认是关闭gzip的,我们需要自己打开,并进行一些配置:
![image-20190311103518953](https://ws4.sinaimg.cn/large/006tKfTcgy1g0ynif76hjj30rq02owf3.jpg)
```nginx
gzip:on; #打开gzip,关闭为off
gzip_min_length 1; #小于gzip_min_length,不进行压缩(默认单位为byte)
gzip_comp_level 2; #压缩级别
gzip_types text/plain text/css application/javascript text/javascript image/jpeg image/gif image/png;#指定类型进行gzip压缩
```
配置完成后,我们再测试一下加载速度:
![image-20190311103446777](https://ws1.sinaimg.cn/large/006tKfTcgy1g0ynhvifkjj31hc0b741l.jpg)
发现白屏时间为1.95s,加载文件的体积也变小了