Vue项目优化

一、代码层面优化 (1)v-if 和 v-show 区分使用场景v-if和v-show的区别区别v-ifv-show手段 动态的向DOM树内添加或者删除DOM

一、代码层面优化

(1)v-if 和 v-show 区分使用场景

  • v-if和v-show的区别
区别v-ifv-show
手段 动态的向DOM树内添加或者删除DOM元素 通过设置DOM元素的display样式属性控制显隐
编译过程 有一个局部编译/卸载的过程 是简单的基于css切换
编译条件 初始条件为假,则什么也不做 在条件第一次变为真时才开始局部编译 任何条件下,都被编译,被缓存,而且DOM元素保留
性能消耗 更高的切换消耗 有更高的初始渲染消耗
使用场景 适合运营条件不大可能的改变 适合频繁切换

(2)computed 和 watch 区分使用场景

  • computed和watch的区别

    1、Computed:计算属性,依赖其他属性计算值,可以设置 getter 和 setter。

    2、Watch:监听到值的变化就会执行回调,在回调中可以进行一些逻辑操作

 ComputedWatch
功能 通过所依赖的属性的变化计算属性值 监听一个值的变化,然后执行对应的回调
使用场景 一个数据受多个数据影响 【购物车商品结算】 一个数据影响多个数据 【搜索框】
调用缓存 支持缓存:数据无变化,缓存读取 数据变化,重新计算 不支持缓存:数据变化,触发响应操作
异步监听 不支持异步:异步就无法监听数据变化 支持异步监听
  属性值是函数使用computed,返回值属性值 在computed中,属性有get方法和set方法 当数据发生变化时,会调用set方法。 监听的函数接收两个参数 第一个参数是最新的值 第二个是变化之前的值

(3)v-for 遍历必须为 item 添加 key,且避免同时使用 v-if

  • Vue中key的作用

  【key 是为 Vue 中 虚拟节点 的唯一标记,通过这个 key,diff 操作可以更准确、更快速】

    (1)第一种情况是 v-if 中使用 key。
    • 由于 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。

    • 因此当使用 v-if 来实现元素切换的时候,如果切换前后含有相同类型的元素,那么这个元素就会被复用。

    • 如果是相同的 input 元素,那么切换前后用户的输入不会被清除掉,这样是不符合需求的。

    • 因此可以通过使用 key 来唯一的标识一个元素,这个情况下,使用 key 的元素不会被复用

    • 这个时候 key 的作用是用来标识一个独立的元素。

    (2)第二种情况是 v-for 中使用 key。
    • 用 v-for 更新已渲染过的元素列表时,它默认使用“就地复用”的策略。

    • 数据项的顺序发生了改变,Vue 不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处的每个元素。

    • 因此通过为每个列表项提供一个 key 值,来以便 Vue 跟踪元素的身份,从而高效的实现复用。

    • 这个时候 key 的作用是为了高效的更新渲染虚拟 DOM

  • 为什么不建议用index作为key?

    使用index 作为 key和没写基本上没区别,因为不管数组的顺序怎么颠倒,index 都是 0, 1, 2...这样排列

    导致 Vue会复用错误的旧子节点,做很多额外的工作。

(4)长列表性能优化

(5)事件的销毁

事件会占用系统资源,为了提高系统效率,我们有时会销毁不需要的事件响应

  DOM节点事件属性销毁:

const button_0 = document.querySelector('.button_0');
button_0.onclick = function(){
  alert('你点击了我');
}
button_0.onclick = null;
//使用后面的事件可以覆盖前面的事件原理进行销毁

  removeEventListener方式事件销毁:

const button_0 = document.querySelector('.button_0');
const clickFunc_0 = function(){
  alert('你点击了我');
}
button_0.addEventListener('click',clickFunc_0);
button_0.removeEventListener('click',clickFunc_0);
//该方式销毁需要保持参数保持一致,否则会销毁失败。

(6)图片资源懒加载(电商)

   显示在屏幕之外的图片默认不加载,随着页面的滚动,图片进入了显示的范围,则触发图片的加载显示

   缺点:需要监听图片是否显示;图片是显示时才去加载

  •  步骤:
    • 1.加载loading图片
    • 2.判断哪些图片要加载【重点】
    • 3.隐形加载图片
    • 4.替换真图片

【所以当图片距离顶部的距离top-height等于可视区域h和滚动区域高度s之和时说明图片马上就要进入可视区了,就是说当top-height<=s+h时,图片在可视区】

 

页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;
网页可见区域宽: document.body.offsetWidth (包括边线的宽);
网页可见区域高: document.body.offsetHeight (包括边线的宽);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;
HTMLElement.offsetTop 为只读属性,它返回当前元素相对于其 offsetParent 元素的顶部的距离。
window.innerHeight:浏览器窗口的视口(viewport)高度(以像素为单位);如果有水平滚动条,也包括滚动条高度。

// onload是等所有的资源文件加载完毕以后再绑定事件
window.onload = function(){
    // 获取图片列表,即img标签列表
    var imgs = document.querySelectorAll('img');

    // 获取到浏览器顶部的距离
    function getTop(e){
        return e.offsetTop;
    }

    // 懒加载实现
    function lazyload(imgs){
        // 可视区域高度
        var h = window.innerHeight;
        //滚动区域高度
        var s = document.documentElement.scrollTop || document.body.scrollTop;
        for(var i=0;i<imgs.length;i++){
            //图片距离顶部的距离大于可视区域和滚动区域之和时懒加载
            if ((h+s)>getTop(imgs[i])) {
                // 真实情况是页面开始有2秒空白,所以使用setTimeout定时2s
                (function(i){
                    setTimeout(function(){
                        // 不加立即执行函数i会等于9
                        // 隐形加载图片或其他资源,
                        //创建一个临时图片,这个图片在内存中不会到页面上去。实现隐形加载
                        var temp = new Image();
                        temp.src = imgs[i].getAttribute('data-src');//只会请求一次
                        // onload判断图片加载完毕,真是图片加载完毕,再赋值给dom节点
                        temp.onload = function(){
                            // 获取自定义属性data-src,用真图片替换假图片
                            imgs[i].src = imgs[i].getAttribute('data-src')
                        }
                    },2000)
                })(i)
            }
        }
    }
    lazyload(imgs);

    // 滚屏函数
    window.onscroll =function(){
        lazyload(imgs);
    }
}

(7)路由懒加载

 概念: 打包部署时将资源按照对应的页面进行划分,需要的时候加载对应的页面资源,而不是把所有的页面资源打包部署到一块。避免不必要资源加载。

 方法:

1. vue异步组件

2. 使用import

3. webpack提供的require.ensure()

(8)第三方插件的按需引入(Element-UI)

 

// main.js
import Element3 from "plugins/element3";
Vue.use(Element3)

// element3.js
// 完整引入
import element3 from "element3";
import "element3/lib/theme-chalk/index.css";

// 按需引入
// import "element3/lib/theme-chalk/button.css";
// ...
// import { 
// ElButton, 
// ElRow, 
// ElCol, 
// ElMain, 
// .....
// } from "element3";

export default function (app) { 
// 完整引入 
app.use(element3)  

// 按需引入 
// app.use(ElButton);
}

(9)优化无限列表性能

 (10)服务端渲染 SSR or 预渲染

二、Webpack层面优化

(1)Webpack 对图片进行压缩

(2)减少 ES6 转为 ES5 的冗余代码

(3)提取公共代码

(4)模板预编译

(5)提取组件的 CSS

(6)优化 SourceMap

(7)构建结果输出分析

(8)Vue 项目的编译优化

三、HTTP的优化

(1)开启 gzip 压缩

(2)浏览器缓存

(3)CDN 的使用

(4)使用 Chrome Performance 查找性能瓶颈

标签: 网页 列表 优化