性能优化原因:
- 渲染速度慢
- 请求时间长
基础优化(通用版)
1.将样式表放在首部-使用link标签将样式表放在文档的HEAD中
// 遵循HTML规范,将样式表放在头部,可以有效避免白屏和无样式内容的闪烁。
<head>
<link rel="stylesheet" href="example.css">
</head>
2.将脚本放在底部
//将脚本放在顶部会造成的影响: 脚本阻塞对其后面内容的显示; 脚本会阻塞对其后面组件的下载;
// 将脚本放在底部</body>标签之前, 不会阻塞页面内容的呈现,而且页面中的可视组件可以尽早下载。
<body>
<!-- 将脚本放在底部 -->
<script src="example.js"></script>
</body>
3.使用字体图标(iconfont)
阿里矢量图标库。它只是往 HTML 里插入字符和 CSS 样式而已,和图片请求比起来资源占用完全不在一个数量级,如果你的项目里有小图标,就是用矢量图吧。
Vue项目优化
PC端优化(引入elementUI 框架)
背景:项目开发完成后,用webpack打包,编译后,app.js过大,导致页面初始化加载慢。
思路:引入elementUI框架,由于本身的包有几百kb,所以对UI框架的修改(按需加载)。
解决办法1(路由懒加载):把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,利用vue的异步组件和webpack的代码分割功能,实现路由组件的懒加载。
- 首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身)
const Foo = () => Promise.resolve({ /* 组件定义对象 */ })
- 在 Webpack 2 中,我们可以使用动态 import语法来定义代码分块点 (split point)
import('./Foo.vue') // 返回 Promise
综合:
const Foo = () => import('./Foo.vue')
解决方法2(组件懒加载):
// const方法
<template>
<One></One>
</template>
<script>
const One = ()=>import("./one");
export default {
components:{
"One-com":One
},
}
</script>
// 异步方法
<template>
<One></One>
</template>
<script>
export default {
components:{
"One":resolve=>(['./one'],resolve)
},
}
</script>
解决办法3:利用webpack-bundle-analyzer 分析器,分析项目依赖关系
// 文件路径 build --> webpack.prod.conf.js
//增加以下配置
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
...
plugins: [
...
new BundleAnalyzerPlugin(),
...
]
添加上述代码后,执行打包命令npm run build,会自动弹出127.0.0.1:8888,找到项目中,那些文件所占的内存大,对此优化。依赖优化(使用CDN)
例子:
- 针对体积比较大的一些钢需依赖,选择CDN加速的方式(以 echarts 来举例)
// index.html
<script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js"></script>
- 配置webpack 来分离 echarts
//文件路径 build --> webpack.base.conf.js
module.exports = {
externals: { //externals 里的库不会被webpack打包
echarts: 'echarts',
},
}
- 在需要使用依赖的地方 import 进来就可以 。
使用CDN内容分发
- 配置vue.config.js
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>
移动端性能优化
预渲染模式
前端渲染领域,主要有以下几种方式选择:
- CSR:
- 优点:不依赖数据FP 时间最快客户端用户体验好内存数据共享
- 缺点:SEO 不友好FCP 、FMP 慢
- 预渲染:
- 优点:不依赖数据FCP 时间比 CSR 快客户端用户体验好内存数据共享
- 缺点:SEO 不友好FMP 慢
- SSR
- 优点:SEO 友好首屏性能高,FMP 比 CSR 和预渲染快
- 缺点:客户端数据共享成本高模板维护成本高
- 同构
- 优点:SEO 友好首屏性能高,FMP 比 CSR 和预渲染快客户端用户体验好内存数据共享客户端与服务端代码公用,开发效率高
- 缺点:Node 容易形成性能瓶颈
在User-centric Performance Metrics一文中,共提到了4个页面渲染的关键指标:
- FP:First Paint (仅有一个 div 根节点。)
- FCP:First Contentful Paint(包含页面的基本框架,但没有数据内容。)
- FMP:First Meaningful Paint(包含页面所有元素及数据。)
- TTI:Time To Interactive