高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)

Posted 前端知识星球

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)相关的知识,希望对你有一定的参考价值。

编辑:念忧


前言

事实上, 只有10%-20%的最终用户响应时间是发在从Web服务器获取html文档并传送到浏览器中的。如果希望能够有效地减少页面的响应时间,就必须关注剩余80%-90%的最终用户体验。
--Steve Souders

在这篇博客中,我根据工作中的实际项目经验和一些测试的经验中总结出了前端页面在性能上优化方案。其中一些经验吸收自《高性能网站建设指南》Steve Souders 著 电子工业出版社。

一、 代码相关优化

1. 将样式表放在首部-使用link标签将样式表放在文档的HEAD中

  • 遵循HTML规范 ,将样式表放在头部,可以有效避免 白屏 无样式内容的闪烁
 
   
   
 
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<!-- 使用link标签将样式表放在文档的HEAD中 -->
<link rel="stylesheet" href="example.css">
</head>

<body></body>

</html>

2. 将脚本放在底部

  • 将脚本放在顶部会造成的影响:  脚本阻塞对其后面内容的显示 脚本会阻塞对其后面组件的下载 ;
  • 将脚本放在 底部</body> 标签之前, 类似于document.body.appendChild(yourScript), 不会阻塞页面内容的呈现,而且页面中的可视组件可以尽早下载。
 
   
   
 
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<link rel="stylesheet" href="example.css">
</head>

<body>
<!-- 将脚本放在底部 -->
<script src="example.js"></script>
</body>

</html>

3. 减少HTTP请求

1) CSS Sprites (雪碧图)

多个图片 合成 一张图片 ,通过background-position来定位所需要的图片。 每次请求的话 只需要请求一张图片 减少http请求。 (如果使用图标的话建议使用svg,也可以使用 iconfont )
  • 合成雪碧图的工具有很多
  • 本地工具: https://github.com/iwangx/sprite (国人写的)
  • 在线工具 https://www.toptal.com/develo...

本地工具:



在线工具:


高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)


2) 内联图片和脚本

  • 通过内联图片和脚本无需额外的HTTP请求,图片小于10K的可以设置内联为base64位。
 
   
   
 
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4SUJRXhpZgAATU>

3) 合并脚本和样式表

  • 一般来说,使用外部脚本和样式表对性能更有利,然而如果将模块化的代码分开放到 多个小文件 中,会 降低性能 ,每个文件都会导致一个 额外的 HTTP请求

4. 使用外部javascript和css

Good
 
   
   
 
<link rel="stylesheet" href="example.css">

<script src="example.js"></script>
bad
 
   
   
 
<style>
// code
</style>

<script>
// code

</script>
  • 使用外部Javascript和Css的主要作用有:  可以配置缓存   有利于组件重用

5. 使用CDN (内容分发网络 Content Delivery Network)

CDN是构建在网络之上的内容分发网络,依靠部署在 各地的边缘服务器 ,通过中心平台的 负载均衡 内容分发 调度 等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。 CDN的关键技术主要有 内容存储 分发技术 --摘自百度百科
  • 通过CDN引入的资源目前基本都是使用目前最新的 HTTP2协议 ,所以在性能上可以做到极致优化,感谢CDN。
  • BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务
  • UNPKG

6. 代码压缩

1) Gzip 压缩

gzip压缩可以节省 50%-70% 的网络开销
浏览器支持的压缩类型可以通过network的Accept-Encoding:  gzip deflate 来查看。 支持deflate的浏览器也支持gzip,但很多浏览器 支持gzip却不支持deflate ,因此gzip是最理想的压缩方法
  • node端 使用 compression 如果是 webpack 项目可以看下面的 Vue首屏加载时间优化 方案里的gzip压缩
 
   
   
 
// npm install compression --save-dev
const compression = require('compression')

2) 代码压缩

前端打包压缩的有grunt,gulp,webpack,可以对HTML,CSS,Javascript代码压缩

二、 服务器相关优化

本文中使用 nginx 服务器进行相关配置,使用 apache 同样可以做到相关优化,具体操作请另 Google

1. 开启gzip压缩

  • 服务端配置gzip压缩
 
   
   
 
gzip on; # 开启Gzip
gzip_static on; # 开启静态文件压缩
gzip_min_length 1k; # 不压缩临界值,大于1K的才压缩
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss; # 进行压缩的文件类型
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6].";
  • 我的服务器nginx相关的配置:


高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)


2. 开启HTTP2

HTTP2在前端性能上主要表现在: 请求和响应的多路复用、头部压缩
  • 感受下多路复用


高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)


nginx服务器配置HTTP2


高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)


  • 使用http2需要配合https使用
  • 使用https需要ca证书  阿里云https证书购买  (有免费的ca证书)

3. 开启缓存

添加Expires头(强缓存)

个人站点相关配置


高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)


nginx配置
 
   
   
 
location ~.*.(svg|woff|js|css){
root /yourFilePath;
expires 1d;
}
  • Web服务器使用 Expires 头来告诉Web客户端它可以使用一个组件的当前副本,直到指定的时间为止 HTTP规范中简要地称该头为“在这一日期时间之后,响应将被认为是无效的”。 它在HTTP响应中发送
 
   
   
 
expiresThu, 30 May 2019 20:51:42 GMT
  • 上面的Expires头告诉浏览器该响应的有效性持续到2019年5月30日为止。 如果为页面中的一个图片返回了这个头,浏览器在后续的页面浏览中会使用缓存的图片,将HTTP请求的数量减少一个

Max-Age和mod_expires

  • 个人站点的css文件使用 强缓存cache-control: max-age


高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)


  • nginx配置
 
   
   
 
server {
add_header Cache-Control max-age=72000;
}
  • 在解释缓存如何很好地改善传输性能之前,需要提及除了Expires 头之外的另一种选择。 HTTP 1.1引入了Cache-Control头来克服Expires头的限制
  • 因为Expires头使用一个特定的时间,它 要求服务器和客户端的时钟严格同步 另外,过期日期需要经常检查,并且一旦未来这天到来了,还需要在服务器配置中提供个新的日期。
  • Cache-Control使用max-age指令指定组件被缓存多久, 如果从组件被请求开始过去的秒数少于max-age,浏览器就使用缓存的版本,这就避免了额外的HTTP请求。 一个长久的max-age头可以将刷新窗设置为未来10年
 
   
   
 
Cache-Control: max-age=315360000
  • Expires 和Cache-Control max-age.如果两者同时出现,HTTP规范规定max-age指令将 重写Expires头
  • 建议使用 Cache-Control max-age ,如果使用expires你需要担心它带来的 时钟同步 配置维护 问题。

配置ETag(协商缓存)

Vue官方文档的Expires相关配置
高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)
浏览器必须产生这个HTTP请求,执行有效性检查, 但这仍 比简单地下载所有已过期的组件效率要高 ( 对比强缓存 )。 如果浏览器缓存中的组件是有效的(即它能够和原始服务器上的组件相匹配),原始服务器不会返回整个内容,而是返回一个 304 Not Modifed 状态码。

附:Vue首屏加载时间过长详细优化方案

  • 首先附一张优化过后的图
  • 首屏加载时间 从原来的 10s 2s ,测试的 个人站点


高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)





注: 我在优化vue项目的时候使用的是 vue@2.6.6 vue-cli@3.4 如果是cli2的项目影响也不大,优化的方案是结合服务端和webpack的。
vue-cli脚手架默认配置已经大幅度优化了前端整体的性能,在此基础上,我又使用了三个优化项增加了大幅度提升

1. gzip压缩

  • 结合 服务器相关优化第一条:开启gzip压缩
  • 下面是前端项目中 vue.config.js 中的配置
 
   
   
 
// 需要 npm install compression-webpack-plugin --save-dev
const CompressionWebpackPlugin = require('compression-webpack-plugin')

// 定义当前环境
const ENV = process.env.NODE_ENV || 'development'

module.exports = {
configureWebpack: config => {
// 如果是开发环境的话,开启压缩
if (ENV === 'production') {
// 参数配置文档: https://www.webpackjs.com/plugins/compression-webpack-plugin/
config.plugins.push(new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /.(js|css|html)$/,
threshold: 10240,
minRatio: 0.8
}))
}
}
}

2. 使用CDN内容分发网络

index.html 文件中通过环境来判断是否引入cdn文件,在 vue.config.js 文件中webpack通过环境判断是否使用cdn引入文件的全局变量
  • 使用CDN需要在 webpack index.html 进行相关配置
第一步 配置 vue.config.js ,只需要在刚才 配置Gzip压缩的基础上再加一段代码
 
   
   
 
const CompressionWebpackPlugin = require('compression-webpack-plugin')

const ENV = process.env.NODE_ENV || 'development'

module.exports = {
configureWebpack: config => {
if (ENV === 'production') {
config.plugins.push(new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /.(js|css|html)$/,
threshold: 10240,
minRatio: 0.8
}))
// 配置externals就是当使用CDN进入的js文件在当前项目中可以引用
// 比如在开发环境引入的vue是import Vue from 'vue', 这个大写的Vue就是对应的下面的大写的Vue
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'axios': 'axios'
}
}
}
}
第二步 配置 index.html ,在body里使用 EJS语法 判断是否为生产环境
 
   
   
 
<body>
<div id="app"></div>
<% if (NODE_ENV === 'production') { %>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
<% } %>
</body>

3. 配置sourceMap

  • devtool | webpack中文网  你可以根据官网来对开发环境和生产环境进行详细配置
  • 当然也可以像我一样直接 productionSourceMap: false 干掉生产环境的sourceMap
 
   
   
 
const CompressionWebpackPlugin = require('compression-webpack-plugin')

const ENV = process.env.NODE_ENV || 'development'

module.exports = {
configureWebpack: config => {
if (ENV === 'production') {
config.plugins.push(new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /.(js|css|html)$/,
threshold: 10240,
minRatio: 0.8
}))
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'axios': 'axios'
}
}
},
// 禁用生产环境的sourceMap
productionSourceMap: false
}

4. 使用HTTP2

请参考服务端优化第二条
前端性能优化至关重要,文中提及的是我认为比较重要的几点,以后遇到更好的方案会补充进来。当然你也可以在评论区留言我们一起探讨,有错误的地方欢迎指出。


原文地址:
https://segmentfault.com/a/1190000019355672

以上是关于高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)的主要内容,如果未能解决你的问题,请参考以下文章

vue项目性能优化,优化项目加载慢的问题

前端性能优化之Gzip

提升首屏加载速度:vue-cli的首屏性能优化

前端Vue项目打包性能优化方案

Vue之性能优化

Vue之性能优化