一. SPA
1、定义
SPA即single-page-application,只有一个HTML页面,通过路由实现页面内的局部替换,公共资源只加载一次。
2、优缺点
优点:
a、用户体验好,加载速度快,内容改变不需要重新加载整个页面
b、前后端分离
c、页面效果比较炫酷,能制作页面切换动画等
缺点:
a、不利于seo
b、导航不可用,如果一定要导航需要自行实现前进后退功能
c、不支持低版本浏览器。最低只支持到IE9
d、初次加载耗时多,白屏时间长
e、页面复杂度高
3、加载过程
拉取HTML --> 加载静态资源(css, js) --> 解析js,生成HTML --> 请求数据 --> 解析数据,渲染页面
二. FP、FCP、FMP
1、指标解释
FP First Paint 渲染出第一个像素的时间
FCP First Contentful Paint 首次内容绘制时间,包括文本、图片、非空canvas、svg
FMP First Meaningful Paint 首次有意义绘制时间
2、白屏和首屏
白屏时间:地址栏输入网址后回车 到 浏览器出现第一个元素 的时间
首屏时间:地址栏输入网址后回车 到 浏览器第一屏渲染完成 的时间
白屏结束时间 = FP指标触发时间
首屏结束时间 = FCP指标触发时间
3、各指标所对应的SPA加载过程
FP -- HTML拉取完毕
FCP -- 静态资源(css, js)加载完毕
FMP -- 数据请求完毕
首屏优化操作主要集中在FMP阶段,FCP阶段次之。
FP阶段的优化操作作用不大。
三. 首屏优化操作方法
1、路由动态加载
@babel/plugin-syntax-dynamic-import 解析识别import()动态导入语法。并非转换,而是解析识别
在根目录新建babel.config.js,配置如下:
module.exports = {
... ,
"plugins": ['@babel/plugin-syntax-dynamic-import']
}
实际应用
const routes = [
{
path: '/',
component: () => import('@/xxx')
}, {
path: '/A',
component: () => import('@/xxx/A')
}
]
2、提取公共库
optimization.splitChunks设置
optimization: {
splitChunks: {
chunks: "all", //async异步代码分割 initial同步代码分割 all同步异步分割都开启
minSize: 30000, //引入的文件大于30kb才进行分割
//maxSize: 50000, //尝试将大于50kb的文件拆分成n个50kb的文件
minChunks: 1, //模块至少使用次数
maxAsyncRequests: 5, //同时加载的模块数量最多5个,只分割出同时引入的前5个文件
maxInitialRequests: 3, //首页加载的时候引入的文件最多3个
automaticNameDelimiter: '~', //缓存组和生成文件名称之间的连接符
name: true, //缓存组里面的filename生效,覆盖默认命名
cacheGroups: { //缓存组,将所有加载模块放在缓存里面一起分割打包
vendors: { //自定义打包模块
test: /[\\/]node_modules[\\/]/,
priority: -10, //优先级,先打包到哪个组里面,值越大,优先级越高
filename: 'vendors.js',
},
default: { //默认打包模块
priority: -20,
reuseExistingChunk: true, //模块嵌套引入时,判断是否复用已经被打包的模块
filename: 'common.js'
}
}
}
}
3、SSR、预渲染、同构
SSR 服务端渲染
通过vue-server-renderer插件将.vue文件转化为json文件,并通过index.html的注解插槽<!--vue-ssr-outlet-->将json文件内容插入到index.html模板中
同构渲染
一套代码多端使用
预渲染 即 预先渲染
使用webpack将vue打包出来的项目通过无头浏览器获取预渲染页面的html内容并渲染到index.html,然后储存到CDN上,用户请求时直接获取CDN上的index.html
4、loading
1)、添加loading图或进度条。
2)、制作首屏骨架图,作为特殊的loading图
5、骨架屏
骨架屏就是在页面内容未加载完成的时候,先使用一些图形或简单样式进行占位,待内容加载完成之后再把它替换掉。
在FP阶段注入骨架屏。
Vue中骨架屏实现方式:
1)、在模板中实现
在index.html中的div#app实现骨架屏,程序渲染后就会替换掉div#app中的骨架屏内容
2)、结合 [SSR] (Vue:结合SSR实现骨架屏 - 掘金 (juejin.cn))
3)、自动生成并自动插入静态骨架屏
使用 page-skeleton-webpack-plugin 或 vue-skeleton-webpack-plugin 插件
6、webpack entry 单页改多页
module.exports = {
... ,
entry: {
app: './xxxx/index.js',
aJs: './xxxx/a.js',
bJs: './xxxx/b.js'
}
}
7、资源请求时间片的处理
8、CDN 服务端处理
9、quickLink 在浏览器空闲的时候去解析预加载可能要跳转的页面
preload
<link rel="preload" href="/css/mystyles.css" as="style">
prefetch
link prefetch
<link rel='next' href='xxx.html'>
dns移动端优化多
<link rel='dns-prefetch' href='xxx.html'>
prerendering
<link rel="prerender" href="http://www.cmcm.com">
preconnect
DNS TLS协商 TCP握手