赞
踩
结合lighthouse查看各项数据,不断进行性能优化,可以从代码、项目打包、项目部署这三个层面来优化
computed:
watch:
methods:
优先级why:vue在编译模板时,会先检测模板中的指令,将模板解析成AST,再根据AST生成对应的render函数。它会先将v-for指令转换成一个生成Vnode的函数,并生成对应的Vnode数组,再会根据v-if的条件来决定是否渲染每个Vnode
diff算法目的是找出差异,最小化更新视图,发生在视图更新阶段,当数据发生变化的时候,diff就对比新旧虚拟DOM,只渲染有变化的部分。
1.对比是不是同类型标签,不是同类型直接替换
2.是同类型标签,就执行patchVnode方法,判断新旧vnode是否相等
3.相等就直接返回,不相等就要对比新旧节点,对比原则以新节点为主,主要分为以下几种:
why提高速度:
vue初始化时,会对数据进行劫持,将数据都转换成响应式的,但有的时候只是想单纯展示数据,就可以跳过数据劫持,大大提高初次渲染速度。
可以通过Object.freeze()将data某些数据冻结,也就是configurable设置为false,在defineReactive中会检测某个key对应的configurable是否为false,是则直接返回,不是就继续配置getter/setter。
export default {
data: () => ({
users: {}
}),
async created() {
const users = await axios.get("/api/users");
this.users = Object.freeze(users);
}
};
防抖和节流是针对用户操作的优化
可以自己手写实现防抖节流(一定要会 面试高频考点),具体可以看这篇:防抖与节流,在vuecli脚手架中也可以引用Lodash库里的防抖节流函数
缓存常见的组件(tab页、导航栏),避免在切换路由时重复渲染相同的组件,提高性能和用户体验
未出现在可视区域内的图片先不加载,等滚动到可视范围再加载,实现方法主要有以下三种:
IntersectionObserver专门来检测某个元素是否出现在可视窗口,出现后就设置src,再取消监听。可以将逻辑封装成可重用的指令,在懒加载的图片元素上使用该指令即可
移动端可以直接在img标签添加loading=“lazy”属性,浏览器自动处理图片的懒加载
vue中可以安装插件vue-lazyload,通过v-lazy写到对应的元素实现
插件是在main.js中引入的,不会被webpack编译,直接写相对地址是获取不到图片正确地址的
设置了翻页功能,且每页都是请求的数据进行渲染的,发现其他数据都会变,但是图片不变,解决办法就在后面加个key就行:
<img v-lazy="img.src" :key="img.src" >
IntersectionObserver(浏览器提供的API)实现图片懒加载原理:观察图片与视窗的交叉情况,从而判断是否出现在视窗中。实现图片懒加载步骤大概:
<!-- HTML --> <img class="lazy-load" data-src="lazy-image.jpg" alt="Lazy-loaded image"> <script> // JavaScript // 创建 IntersectionObserver 对象 const observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { // 判断目标元素是否进入视窗内 const lazyImage = entry.target; lazyImage.src = lazyImage.dataset.src; // 将真实图片地址赋给src属性 observer.unobserve(lazyImage); // 停止观察该目标元素 } }); }); // 获取所有带有 lazy-load 类的图片元素 const lazyImages = document.querySelectorAll('.lazy-load'); // 遍历所有图片元素,开始观察 lazyImages.forEach(image => { observer.observe(image); }); </script>
可以在webpack.base.conf.js中url-loader设置limit大小来处理图片,小于limit的图片转换成base64格式
将图片转成base64格式的原因:
对于一些较大的图片可以用image-webpack-loader压缩,具体配置如下:
module.exports = { module: { rules: [ { test: /.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, // 图片小于8KB时转换为base64 name: '[name].[ext]', outputPath: 'images/' // 输出到指定目录 } }, { loader: 'image-webpack-loader', options: { mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false, }, pngquant: { quality: [0.65, 0.90], speed: 4 }, gifsicle: { interlaced: false, }, webp: { quality: 75 } } } ] } ] } };
针对多个小图标可以利用雪碧图技术,将其合并成一张大图,减少HTTP请求次数
路由被访问才加载对应的组件,提高首屏显示速度
const Foo = () => import('./Foo.vue')
用babel-plugin-component只引入需要的组件,减小项目体积。安装包导入依赖即可,在main.js按需引入组件
安装分析工具webpack-bundle-analyzer,会生成可视化的文件链路图,根据需求做调整。
用CommonsChunkPlugin(webpack内置插件)去提取多个chunk的公共部分。
babel在每个输出文件中内嵌依赖的辅助函数代码,不让这些代码重复出现,可以用babel-plugin-transform-runtime插件,减小babel编译出来的代码大小。
安装包
修改.babelrc配置文件
"plugins": [
"transform-runtime"
]
使用OptimizeCssnanoPlugin插件来压缩和去重css样式文件,开启optimization.minimize来压缩js代码。
tree shaking只能处理ES6模块,消除未使用过的代码,减少文件大小。
使用生产模式,在config.js设置mode: ‘production’来启用生产模式,用usedExports: true来启用tree shaking
前后端都可以压缩,不管在nginx还是webpack压缩,在nginx都要开启gzip压缩,要不然浏览器加载的还是未压缩的资源。
识别gzip压缩是否开启,只需要看响应头部有没有Content-Encoding:gzip这个属性,有就表明开启了。
(1)在vue-cli初始化项目中,默认有这个配置:
先安装插件,再在config/index.js文件开启即可
build: {
// 其他代码
…………
productionGzip: true, // false不开启gizp,true开启
// 其他代码
}
(2)利用插件compression-webpack-plugin来实现:
用webpack会使打包时间变长,但用这个插件会有缓存,可以相对减少打包时间。
先安装好后,在vue.config.js配置支持gzip:
// vue.config.js 配置开启gzip
const CompressionPlugin = require('compression-webpack-plugin')
configureWebpack: (config) => {
const plugins=[
new CompressionPlugin({
algorithm: 'gzip',// 压缩格式
test: new RegExp(`.(${['js', 'css', 'json', 'html'].join('|')})$`),// 正则匹配文件后缀
threshold: 1024 * 5,// 压缩阀值超过5KB时才压缩
minRatio: 0.5//压缩比例缩小50%才采用
})]
return {
plugins
}
}
(3)在nginx上开启gzip
nginx压缩会占用服务器的CPU,浏览器每次请求资源,nginx都是实时压缩资源,资源很大再加上压缩级别很高(数字越大,压缩后的大小就越小)的话,返回资源的时间就会很长。
一般是nginx和webpack都开启压缩,并且在nginx加上gzip_static on配置, gzip_static启用后,浏览器请求资源时,nginx会先检查是否有该资源名称且后缀是.gz的文件,是就直接返回该gz文件内容,这样就可以避免nginx对该资源再进行压缩,浪费服务器的CPU。
在nginx/conf/nginx.conf中配置:
http {
gzip on;
gzip_min_length 1k;
gzip_comp_level 5;
gzip_types application/javascript image/png image/gif image/jpeg text/css text/plain;
gzip_buffers 4 4k;
gzip_http_version 1.1;
gzip_vary on;
}
大概的操作:
提高访问速度的原因:
通过设置HTTP响应头中cache-control字段来控制缓存策略,设置HTTP响应头expires字段(表示资源的过期时间),一般结合cache-control中的max-age使用,但expires是绝对的日期时间,max-age是相对于请求时间的秒数
项目附件:点此下载
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。