白屏原因:
vue首页白屏的原因是打包后的js和css文件过大,浏览器初始访问网站时,会先加载该项目的js和css文件,加载完成后才会进行页面渲染。如果打包的文件过大,加载时间就会变长,出现视觉上的页面白屏.
白屏时间(FP)
白屏时间(First paint):指浏览器从响应用户输入网址地址,到浏览器开始显示内容的时间。
- 白屏时间= 页面开始展示的时间点——开始请求的时间点
首屏时间(FCP)
首屏时间(First Contentful Paint):指浏览器从响应用户输入网络地址,到首屏内容渲染完成的时间。
- 首屏时间= 首屏内容渲染结束时间点——开始请求的时间点
最基本、简单解决方法
首页添加一个loading,在index.html里加一个loadingcss效果,当页面加载完成后消失。
代码解决方案:
路由懒加载
- 未使用路由懒加载的写法
import HelloWorld from '@/components/HelloWorld'
routes:[{
path:'/',
name:'HelloWorld',
component:HelloWorld
}]
使用路由懒加载
routes:[{
path:'/index',
name:'index',
component:() => import('@/views/index')
}]
总结:使用懒加载,打包后才根据路由生成多个js和css文件,当访问到对应的路由时,才加载对应的文件
在移动端页面的首页时,先加载可视区域的内容,剩下的内容等它进入可视区域后再按需加载
CDN资源优化
随着项目越做越大,需要依赖的第三方npm包也越多,构建后的文件也越大。
- 将vue、vue-router、vuex、axios等vue的全家桶资源,全部改为通过CDN链接获取,在index.html里插入相应的链接
<body>
<div id="app"></div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.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/element-ui/2.6.1/index.js"></script>
</body>
- 在vue.config.js中配置externals属性
module.exports = {
...
externals:{
'vue':'Vue',
'vuex':'Vuex',
'vue-router':'VueRouter',
'axios':'axios'
}
}
- 卸载相关依赖的npm包
npm uninstall vue vue-router vuex axios
缓存
- 接口缓存
- 端内所有请求都走Native,实现接口缓存
- 静态资源缓存
- 静态资源长期不需要修改的,使用强缓存,设置Cache-Control实现,设置Cache-Control:max-age=31536000,浏览器在一年内直接使用本地缓存文件,不向服务器发送请求。
- 资源随时变动,设置ETag实现协商缓存,初次请求资源时,设置ETag,并返回200,之后请求时带上If-none-match字段,询问服务器当前版本是否可用。
并行化处理
利用HTTP2.0多路复用的特点,单个文件可以单独上线,不需要再做JS文件合并了。采用二进制数据帧和流的方式进行传输。
搭建性能平台(埋点)
目的:为了能获取到一部分上报数据。 例如:页面访问次数,那些位置、入口点击数最高等
- 手动埋点
原理:调用埋点SDK的函数,在需要埋点的业务逻辑功能位置调用接口上报埋点数据
- 手动埋点的技术本质是,能获取到那些内容:
- 域名:document.domainURLdomcument.URl
- 页面标题:document.title
- 分辨率:window.screen.height & window.screen.width
- 颜色深度:window.screen.colorDepth
- Referrer:cocument.referrer
- 埋点做法
// 命令式埋点 ()=>{ //...逻辑代码 sendData(params);//这里是发送埋点数据,params是封装的埋点数据 } // 声明式埋点 <div data-spm-data="{name:'点击',event:'touch',agent:'...'}">Touch</div> - 手动埋点的技术本质是,能获取到那些内容:
利用window.Performance(API)
可以拿到DNS解析时间、TCP建立连接时间、首页白屏时间、DOM渲染完成时间、页面load时间等
SSR
服务端渲染,在服务端将渲染逻辑处理好,然后将处理好的HTML直接返回给前端展示,可以解决白屏问题。
预渲染
- 利用webpack的插件prerender-spa-plugin做预渲染 配置如下
const path = require('path')
const PrerenderSPAPlugin = require('prerender-spa-plugin') const Renderer = PrerenderSPAPlugin.PuppeteerRenderer module.exports = {
configureWebpack: config => {
let plugins = []
plugins.push(new PrerenderSPAPlugin({
staticDir: path.resolve(__dirname, 'dist'),
routes: ['/', '/about'],
minify: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
decodeEntities: true,
keepClosingSlash: true,
sortAttributes: true
},
renderer: new Renderer({
renderAfterDocumentEvent: 'custom-render-trigger'
})
}))
config.plugins = [
...config.plugins, ...plugins ]
}
}
staticDir:预渲染输出的文件地址 routes:要做预渲染的路由 minify:压缩相关的配置 renderer 渲染引擎相关的配置 总结:最后的结果是预渲染插件在编译阶段就将对应的路由编译好插入到app节点,这样就能在js文件解析过程中有内容展示,js解析完成后,Vue会将app节点内的内容替换成Vue渲染好的内容。
Chrome Dev Tools计算性能指标
可以使用Chrome Dev Tools计算性能指标
- Network:页面中各种资源请求的情况(资源名称、状态、协议、资源类型和大小)等
- Performance:页面各项性能指标的火焰图,(白屏时间、FPS、资源加载时间线)
骨架屏
意义:骨架屏就是在页面尚未加载之前先给用户展示页面的大致结构,在骨架页面中,图片、文字、图标都将通过灰色矩形块或圆形块显示,直到页面请求数据后渲染页面。
原理: 通过puppeteer在服务端操控headless Chrome打开开发中的需要生成骨架页面的页面,在等待页面加载渲染完成之后,保留页面布局样式的前提下,通过对页面中元素进行删减或增添,通过样式覆盖,使其展示为灰色块。
element-plus中有骨架屏
<el-skeleton>