vue - 일반적인 성능 최적화

여기에 이미지 설명 삽입

vue 사용 시 일반적인 성능 최적화


1, v-if를 동시에 사용하지 않도록 v-for traversal

Vue2에서는 v-for우선 순위가 높기 때문에 컴파일 과정에서 모든 목록 요소를 순회하여 가상 DOM을 생성한 다음 v-if로 판단하여 렌더링하면 불필요한 논리적 판단과 성능 낭비가 발생합니다. 가장 중요한 것은 조건에 맞지 않는 가상 DOM을 생성해서는 안된다는 것입니다.

1, 목록의 항목을 필터링하기 위해( 比如 v-for="user in users" v-if="user.isActive"). 이 경우 사용자는 필터링된 목록을 반환하는 계산된 속성 또는 메서드(예: activeUsers)로 대체될 수 있습니다.

<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {
    
    {
    
     user.name }}
  </li>
</ul>

methods:{
    
    
	// 方法
	activeUsers(){
    
    
		//在这里面处理需要显示的数据  然后返回筛选过的列表
	}
}

2. 숨겨야 하는 목록을 렌더링하지 않으려면( 比如 v-for="user in users" v-if="shouldShowUsers"). 이 경우 v-if를 컨테이너 요소(예: ul, ol)로 이동합니다.

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {
    
    {
    
     user.name }}
  </li>
</ul>

Vue3 v-if의 우선 순위가 더 높습니다. 즉, 판단 조건이 v-for가 통과하는 목록의 속성인 경우 v-if를 얻을 수 없습니다.

注意: 동일한 요소에 대해 v-if와 v-for를 동시에 사용하지 마십시오.

2. 이벤트를 각 요소에 바인딩하기 위해 v-for를 사용해야 하는 경우 이벤트 프록시**를 사용할 수 있습니다.

이벤트 위임의 본질은 부모 요소에 이벤트 버블링 기능을 사용하는 것입니다. 이렇게 하면 다음과 같이 루프의 각 노드에 이벤트를 추가할 필요가 없습니다.

상위 요소 ul에 클릭 이벤트를 추가합니다. 매개변수를 전달해야 하는 경우 아래 id 속성과 같은 사용자 정의 속성만 추가하면 됩니다.

  <!--  使用事件委托进行处理和传参 添加自定义属性id -->
    <ul class="weekdays" @click="debounce($event)">
      <li v-for="(item, index) in dayList" :key="index" :id="index" >{
    
    {
    
     item.day }}</li>
    </ul>

	// 事件委托处理
    debounce(event) {
    
    
      if (event.target && event.target.nodeName == "LI") {
    
    
        // 现在就可以拿到当前的节点 所以就能拿到里面的属性和数据
          console.log("我点击的是:", event.target);
      }
    },

이벤트 프록시에는 두 가지 이점이 있습니다
.

3. 일부 데이터가 응답하지 않음

회원 목록, 제품 목록 등과 같은 일부 데이터는 응답하지 않지만 순수한 데이터 표시입니다.동적 변경이 없는 시나리오에서는 데이터에 대한 응답 처리를 수행할 필요가 없으므로 크게 향상될 수 있습니다. 렌더링 속도;

방법을 사용하여 Object.freeze()개체를 고정할 수 있으며 이 방법으로 고정된 개체는 수정할 수 없습니다. 즉, 이 개체에 새 속성을 추가하거나 기존 속성을 삭제하거나 기존 속성의 열거 가능성, 구성 가능성 및 쓰기 가능성을 수정할 수 없습니다. 개체 속성의 기존 속성 값을 수정할 수 없으며 개체의 프로토타입을 수정할 수 없습니다.

export default {
    
    
  data: () => ({
    
    
    userList: []
  }),
  async created() {
    
    
    const users = await axios.get("/api/users");
    this.userList = Object.freeze(users);
  }
};

Vue2의 반응형 소스 코드 주소: src/core/observer/index.js - 144行다음과 같습니다.

export function defineReactive (...){
    
    
	// getOwnPropertyDescriptor 返回指定对象上一个自有属性对应的属性描述符
	// 也就是直接赋予该对象的属性,不需要从原型链上进行查找的属性
    const property = Object.getOwnPropertyDescriptor(obj, key)
    
	判断configurable``false`不做处理
    if (property && property.configurable === false) {
    
    
        return
    }
    ...
}

초기에 판단한 직접 반품은 반응 처리를 하지 않는 configurable것을 알 수 있습니다.false

configurable``false` 表示这个属性是不能被修改的,而冻结的对象的 `configurable` 就是为 `false

이것은 Vue가 일반적으로 데이터에서 정의하는 데이터이며, 자동으로 get 및 set 속성을 다음의 모든 속성에 최대한 많이 추가합니다.

여기에 이미지 설명 삽입

开始冻结对象

freList는 요청 백엔드의 목록 데이터입니다.

  created() {
    
    
    this.dayList = Object.freeze(freList)
    console.log("daylist:",this.dayList);
  },

get 및 set 속성이 없음을 알 수 있지만 동시에 이러한 데이터는 응답하지 않습니다.

여기에 이미지 설명 삽입

4. 일부 페이지는 keep-alive캐싱 구성 요소를 사용합니다.

列表页>详情页>列表页예를 들어, 양식 입력 페이지가 다음 단계로 들어간 후 이전 단계로 양식 페이지로 돌아온 후 앞뒤로 점프하는 장면 과 같이 양식 입력 내용을 유지해야 합니다.

기본 사용:

	如果需要缓存整个项目,则如下设置(直接包裹根router-view即可)<keep-alive>
    	<router-view> </router-view>
	</keep-alive>

	缓存部分页面或者组件,使用route.meta属性
	<keep-alive>
    	<router-view v-if="$route.meta.keepAlive"></router-view>
	</keep-alive>
    	<router-view v-if="!$route.meta.keepAlive"></router-view>


	注:<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
	<keep-alive>
    	<component :is="view"></component>
	</keep-alive> 

참고: keepAlive로 구성된 페이지는 다시 들어갈 때 다시 렌더링되지 않으며(처음 들어갈 때 모든 후크 기능이 트리거됨) 이 페이지의 구성 요소는 동일한 방식으로 다시 렌더링되지 않습니다.

이로 인해 구성 요소의 관련 작업(부모 구성 요소와 자식 구성 요소 간에 값을 전달하는 것과 같이 매번 페이지를 다시 렌더링해야 하는 작업)이 더 이상 적용되지 않을 수 있습니다. 이로 인해 설명할 수 없고 확인할 수 없는 버그가 발생할 수 있습니다.

Vue2.1.0은 구성 요소의 조건부 캐싱을 허용하는 포함 및 제외 특성을 추가했습니다. 둘 다 쉼표로 구분된 문자열, 정규식 또는 배열로 나타낼 수 있습니다.

    <!-- 逗号分隔字符串 -->
    <keep-alive include="a,b">
        <component :is="view"></component>
    </keep-alive>
 
    <!-- 正则表达式 (需要 `v-bind`绑定) -->
	<keep-alive :include="/a|b/">
    	<component :is="view"></component>
	</keep-alive>
 
    <!-- 数组 (需要 `v-bind`绑定) -->
	<keep-alive :include="['a', 'b']">
    	<component :is="view"></component>
	</keep-alive>

참고: 매칭은 먼저 컴포넌트 자체의 이름 옵션을 확인하고, 이름 옵션을 사용할 수 없는 경우 로컬에 등록된 이름(상위 컴포넌트 컴포넌트 옵션의 키 값)을 매칭합니다. 익명 구성 요소는 일치시킬 수 없습니다.

동적 판단, v-bind:include 사용

<keep-alive :include="includedComponents">
    <router-view></router-view>
</keep-alive>

includedComponents动态设置即可  

가로채기 처리를 위해 beforeRouteLeave 또는 afterEach 사용

如在项目在Category组件中的设置:
beforeRouteLeave(to,from,next){
    
    
    if(to.name=='DemoIndex'){
    
    
        if(!from.meta.keepAlive){
    
    
            from.meta.keepAlive=true
        }
        next()
    }else{
    
    
        from.meta.keepAlive=false
        to.meta.keepAlive=false
        next()
    }
},
在beforeRouteLeave中to.name根据具体的路由进行动态缓存设置

keepAlive 사용 후 수명 주기 변경(중요):

처음으로 캐시 페이지에 들어가십시오: beforeRouteEnter --> 생성됨 --> 마운트됨 --> 활성화됨 --> 비활성화
됨 캐시 페이지에 다시 들어가십시오: beforeRouteEnter --> 활성화됨 --> 비활성화됨

참고:
1. 여기에서 활성화는 페이지가 캐시될 때 생성, 마운트 및 기타 수명 주기가 유효하지 않기 때문에 매우 유용합니다.일부 작업을 수행하려면 활성화에서 완료할 수 있습니다(다음은 밤을 줄 것입니다. 목록 페이지가 맨 위로 돌아갑니다. 두 번째 브라우징 위치)
2. 활성화된 keep-alive 구성 요소는 활성화될 때 호출되며 이 후크는 서버 측 렌더링 중에 호출되지 않습니다.
3. 비활성화된 keep-alive 구성 요소는 비활성화될 때 호출되며 이 후크는 서버 측 렌더링 중에 호출되지 않습니다.

5. 필요에 따라 타사 UI 라이브러리 가져오기

예를 들어 element-ui 라이브러리의 주문형 도입인 vantUi는 이 문서를 참조하세요 .

6. 목록 데이터의 레이지 로딩 및 페이징 데이터의 슬라이딩 로딩

목록 데이터의 지연 로딩 스크롤바는 스크롤바가 아래로 스크롤될 때 다음 페이지의 데이터를 요청하기 시작하므로, 순간적으로 너무 많은 요청을 방지하기 위해 흔들림 방지 기능과 함께 사용해보세요.

如下代码

여기서는 vue3을 사용하여 작성합니다. vue2는 노드를 가져오는 다른 방법일 뿐이며 다른 모든 것은 동일합니다.

onMounted(() => {
    
    
   // 获取滚动容器的节点
  let containerEle = showContentEl.value;
  if (!containerEle) return;
  
  // 监听滚动条
  containerEle.addEventListener("scroll", function () {
    
    
    const clientHeight = containerEle.clientHeight;
    const scrollTop = parseInt(containerEle.scrollTop);
    const scrollHeight = containerEle.scrollHeight;
    // 判断是否滚动条是否滚动到底  (-1是为了控制误差)
    if (clientHeight + scrollTop >= scrollHeight - 1) {
    
    
      // 开始防抖请求数据
      debounceLoadMaterialList();
    }
  });
});

<template>
  <div class="container">
    <div class="list">
      	展示的列表数据
    </div>
  </div>
</template>

인터페이스 흔들림 방지 설정:

import * as _ from "lodash";
// 设置接口防抖
const debounceLoadMaterialList = _.debounce(loadMaterialList, 500);

7. 변수 현지화

this.xx간단히 말해서 에 접근할 때마다 반응형 객체이기 때문에 매번 촉발되기 때문에 여러 번 참조될 변수를 저장한 getter후 컬렉션에 의존하는 관련 코드를 실행하는 것이다. 더 많은 변수를 사용하면 성능이 자연스럽게 향상됩니다.

요구 사항 측면에서 함수의 변수에 대한 종속성 수집을 수행하는 것으로 충분하지만 많은 사람들이 습관적으로 프로젝트에서 많은 것을 작성하고 백그라운드에서 수행되는 작업을 this.xx무시하면 성능 문제가 발생합니다.this.xx

比如下面vue2的例子

<template>
  <div :style="{ opacity: number / 100 }"> {
    
    {
    
     result }}</div>
</template>
<script>
import {
    
     someThing } from '@/utils'
export default {
    
    
  props: ['number'],
  computed: {
    
    
    base () {
    
     return 100 },
    result () {
    
    
    
      let base = this.base, number = this.number // 保存起来  -- 变量本地化
      for (let i = 0; i < 1000; i++) {
    
    
        number += someThing(base) // 避免频繁引用 this.xx
      }
      return number
    }
  }
}
</script>

8. 이벤트의 파기

Vue 구성 요소가 소멸되면 모든 지침과 이벤트 리스너가 자동으로 바인딩 해제되지만 구성 요소 자체의 이벤트에만 제한됩니다.

定时器등록된 리스너 등 의 경우 addEventListener메모리 누수를 방지하기 위해 구성 요소 소멸의 수명 주기 후크에서 수동으로 소멸하거나 바인딩을 해제해야 합니다.

<script>
export default {
    
    
    created() {
    
    
      this.timer = setInterval(this.refresh, 2000)
      addEventListener('touchmove', this.touchmove, false)
    },
    beforeDestroy() {
    
    
      clearInterval(this.timer)
      this.timer = null
      removeEventListener('touchmove', this.touchmove, false)
    }
}
</script>

Supongo que te gusta

Origin blog.csdn.net/qq_43886365/article/details/131766043
Recomendado
Clasificación