Vue前端面试题

1 Vue 生命周期

vue生命周期就是vue实例从创建到销毁的过程,也就是从开始创建、初始化数据、编译模板、挂载Dom->渲染、更新->渲染、销毁等一系列过程。

vue生命周期大致可以分为三个阶段:

  1. 创建阶段
    beforeCreate->Created->beforeMount->Mounted
  2. 更新阶段
    beforeUpdate->Updated
  3. 销毁阶段
    beforeDestroy->destroyed

在项目中,常用的生命周期函数有:

  1. Created:发起异步请求获取数据,此时还不能操作 Dom
  2. Mounted:这时 Dom 已被创建,可以基于 ref 获取 Dom,还可以在这里设置定时器、绑定自定义事件
  3. beforeDestroy:在Vue实例销毁之前,清除定时器、解绑自定义事件

Vue3相对于Vue2来说有一些变化,比如:

  1. beforeCreateCreated生命周期函数被setUp函数替换了
  2. 其他周期函数改成以on开头,例如Mounted改成了onMounted
  3. 销毁的周期函数改成了onBeforeUnmountonUnmounted

2 Vue 组件通信方式有哪些

  1. props$emit / $on 适用于父子组件通信
    父组件在子组件上绑定需要传递的数据和事件方法
    子组件通过 props 接收父组件传递过来的数据,并且通过绑定事件的方式调用 $emit 触发父组件的自定义事件,实现父组件数据的更新

  2. ref$parent / $children 适用于父子组件通信
    ref:获取 DOM 元素或者子组件实例的属性和方法
    $parent / $children:访问父 / 子组件实例

  3. EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信
    EventBus主要是用到发布者-订阅者的设计模式,这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件

  4. provide / inject 适用于隔代组件通信
    多层级嵌套的组件,通过 props 逐级传递数据比较麻烦。祖先组件中通过 provider 来提供数据/方法,然后在子孙组件中通过 inject 来注入数据/方法。

  5. $attrs / $listeners 适用于隔代组件通信
    $attrs: 用于传递非 props 属性 v-bind=“$attrs”
    $listeners:用于传递非原生事件方法 v-on=“$listeners”

  6. Vuex 适用于任意组件之间传值,实现数据共享

3 v-show 和 v-if区别

v-show / v-if:都是用来控制元素的显示和隐藏的
区别:
v-show:本质是通过设置css中display属性为none来控制隐藏
v-if:是动态添加或者移除DOM元素

编译区别:
v-show:只会编译一次,本质就是控制css
v-if:初始值为false时,就不会编译;v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件

性能比较:
v-show:适用于频繁操作某个节点时使用(初始开销大,切换开销较小)
v-if:适用于少次操作某个节点时使用(因为懒加载,初始化时不会渲染,v-if 是不停地创建和销毁DOM元素,初始开销小,切换开销较大)

4 v-if 和 v-for为什么不能一起使用

v-if 和 v-for 应该避免在同一个元素上同时使用,因为会造成不必要的内存消耗,影响性能

vue2: v-for 的优先级比 v-if的优先级高,如果嵌套使用的话,每次v-for 都会执行一次v-if,会造成重复计算的问题,影响性能

vue3:v-if 的优先级高于v-for,会导致 for循环的索引还没拿到,控制台会报错,且什么都不渲染

如何避免渲染应该被隐藏的项?
外层嵌套template(页面渲染不生成DOM节点),先进行 v-if 判断,然后在内部进行 v-for 循环

如何过滤列表中的项?
如果条件出现在循环内部,则通过 computed 计算属性提前过滤掉那些不需要显示的项

5 computed 和 watch区别

computed / watch:都是用来观察页面数据变化的
区别:

  1. 缓存功能
    computed :支持缓存,只有依赖的数据发生了变化,才会重新计算
    watch:不支持缓存,数据变化时,直接触发相应的操作
  2. 是否支持异步
    computed :不支持异步,当computed内有异步操作时,无法监听数据的变化
    watch:支持异步操作,适用于监听路由和定时器等
  3. 数据影响
    computed :一个属性是由其他属性计算而来的,其中任何一个属性发生变化时,该值能及时更新。所以computed属性不能与data属性命名冲突
    watch:一个属性影响其他属性,当这个值发生变化时,能及时更新所有依赖它值

总的来说
computed :更注重数据变化得出的结果,一定要有返回值
watch :更注重数据变化时执行的过程,可以没有返回值作为结果,,更适用于数据变化时的异步操作

6 vue-router作用

  1. vue-routervue.js 官方的路由插件,它和 vue.js 是深度集成的,适用于构建单页面应用
  2. vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,一般是通过超链接实现页面的切换和跳转
  3. vue-router 单页面应用中,则是路径之间的切换,也就是组件之间的切换。路由模块的本质就是建立起url和页面之间的映射关系
  4. vue路由主要有 hashhistory 两种模式,都能使视图更新而不需要重新加载页面

7 hash 和 history区别

原理:
hash:利用了window.onhashchange事件,监听url中#后面哈希值的变化,找到对应的页面进行加载
history:通过pushHash方法新增记录和replaceHash方法替换当前记录的方式改变url,然后监听popHash事件来监听url的变化,触发视图更新

区别:

  1. hash 模式地址栏后面有#符号,history模式没有
  2. hash 模式地址中#后的哈希值变化不会发起HTTP请求,对后端完全没有影响,所以改变哈希值不会重新加载页面;history模式斜杠后的路径变化会发起HTTP请求,如果前后端的路径不一致会返回404错误
  3. hash 模式兼容性比 history 好,可达到 IE8

8 路由导航守卫有哪些

路由导航守卫:是路由跳转过程中的生命周期函数,也称为钩子函数,可以帮助实现不同的业务需求或者处理不同的业务逻辑

路由导航守卫大致可以分为三种:

  1. 全局导航守卫
  • beforeEach 路由跳转之前做一些验证,比如登录验证
  • beforeResolve 路由解析守卫
  • afterEach 路由跳转之后,不能使用next
  1. 路由独享守卫
  • beforeEnter
  1. 组件路由守卫
  • beforeRouteEnter 组件实例还未创建,不能使用this,可以回调给next来访问组件实例
  • beforeRouteUpdate
  • beforeRouteLeave 离开路由之前执行操作,比如草稿箱的暂存

9 to from next 区别

to:即将进入的目标路由对象
from: 即将离开的路由对象
next

  • next():一定要调用next方法进行下一个钩子;否则直接中断当前导航,会导致路由组件无法渲染,页面出现空白
  • next(false):中断当前的导航
  • next('/...') 或者 next({ path: '/...' }):跳转到指定的路由地址
  • next(error):导航终止,router.onError()捕获处理异常

10 路由跳转方式有哪些

路由跳转方式有两种:

  1. 声明式导航
<router-link :to="需要跳转的页面路径" />
  1. 编程式导航
    有三种方式:
    • push(): 跳转到指定的页面路径,会向history中添加记录,点击回退返回上个页面
    • replace(): 替换当前页面路径,不会向history中添加记录,点击回退返回上上个页面
    • go(n):n可以是正数或者负数,表示向前或者向后跳转n个页面

11 路由传值方式有哪些

无论是声明式导航还是编程式导航,都可以通过字符串或者对象两种方式进行传值
字符串:直接传递路由路径,不能携带参数
对象:可以通过 query 或者 params 两种方式传递参数

12 query 和 params区别

  1. querypath 引入,paramsname 引入, params 一定不能和 path 一起使用
  2. query 刷新页面不会丢失参数,params 刷新页面会丢失参数,可以通过在路径斜杠后添加:参数名动态路由方式,使参数显示在url上
  3. 地址栏参数显示不同
    query路径?name=xxx&key=xxx
    params路径/参数1/参数2

13 route 和 router区别

route:路由信息对象,可以获取querynameparamspath等路由信息参数
router:路由实例对象,可以调用路由跳转方式、钩子函数等

14 介绍一下keep-alive

keep-alive:是 Vue 内置的一个组件,用来实现组件缓存,可以使被包含的组件保留状态,避免重新渲染

有三个属性:
include:表示只有匹配的组件会被缓存
exclude:表示匹配的组件不会被缓存
max:定义组件最大的缓存个数

有两个钩子函数(生命周期函数)
activated:缓存的组件被激活时触发
deactivated:缓存的组件被移除时触发

执行顺序:

  • 不使用keep-alive:beforeRouteEnter -> created -> mounted -> destroyed
  • 使用keep-alive,首次进入:beforeRouteEnter -> created -> mounted -> activated -> deactivated
  • 使用keep-alive,缓存进入:beforeRouteEnter ->activated -> deactivated

15 介绍一下Vuex

Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。

特点:

  • 存储在Vuex中的数据都是响应式的,能够实时保持数据与页面的同步
  • Vuex能够集中管理组件之间的数据,实现数据共享,易于开发和维护

大致有五个模块:

State:用于存放组件之间共享的数据
Getter:相当于 state 的计算属性,用于对 Store 中的数据进行加工处理形成新的数据,当 Store 中数据发生变化,getter 的数据也会跟着变化
Mutation:用于改变 store 中状态的方法,且必须是同步函数。
Action:用于提交 mutation,而不是直接修改state中的数据,可以处理任意异步操作。
Module:允许将store分割成模块 (Module),且每个模块都有自己的state、getters、mutation、action等,甚至是嵌套子模块

16 介绍一下插槽

插槽:相当于组件模板中的占位符,父组件通过插槽向子组件内部指定位置传递内容。插槽分为三种:匿名插槽、具名插槽、作用域插槽

匿名插槽:默认情况下,提供的内容都会被填充到名字为 default (或默认不写) 的插槽之中,一个组件只能有一个匿名插槽

具名插槽:将提供的内容填充到具体名称的插槽之中

使用方法:<template v-slot:插槽名></template>

  1. 需要使用 v-slot: 这个指令
  2. v-slot: 后面要跟上插槽的名字
  3. v-slot: 不能直接用在元素上,必须使用template标签包裹
  4. template 标签只起到包裹作用,不会被渲染为html元素
  5. v-slot: 可简写为 #

作用域插槽:能够把⼦组件的数据传递给⽗组件使⽤,子组件在 <slot> 元素上通过v-bind绑定数据,父组件通过 v-slot: 或者 # 获取子组件传递过来的数据

17 介绍一下Mixin混入

Mixin混入:能够将多个组件的公共代码,包括数据对象、钩子函数、方法等抽离出来,减少代码冗余,达到复用效果。Mixin混入方式有两种:全局混入、局部混入。

全局混入:只需要把mixin.js文件引入到main.js中,然后将mixin放入到Vue.mixin()方法中,在需要的使用的页面直接使用,不需要再引入

局部混入:新建mixin.js文件,注册一个mixin对象,里面定义公共数据和方法,在需要的页面引入,使用mixins混入,数组可以接收多个mixin

选项冲突处理

  1. 生命周期钩子函数同名:
    都会触发,但是mixin会先触发
    同名钩子函数将合并为一个数组,因此都将被调用,但是混入对象的钩子函数优先执行。
  2. 数据对象data同名:
    data对象的内部会进行递归合并,当发生冲突时,以组件为主。
  3. 对象类型的选项(methods、components、computed、directives、watch等)同名:
    当发生冲突时,组件会覆盖mixin。

Mixin混入和Vuex的区别

  • Vuex:用来做状态管理的,Vuex中的所有变量和方法都是可以使用和更改并且会相互影响。
  • Mixins:用来定义公共变量,在不同组件中各个变量是相互独立的,值的修改在组件中不会相互影响。

vue3.0中已经将mixin作为备选方案,推荐使用hook,也是复用的。因为mixin覆盖容易产生冲突、滥用的话后期维护比较麻烦。

18 介绍一下Hook

Hook:类似于 mixin ,能够实现代码复用,自定义的 hooks 一定要是 use 开头。

Hook 和 Mixin 的区别
mixin 缺点:

  • mixin中的变量和方法是隐式引入,变量来源不明确,不利于代码维护
  • 一个组件中引入多个mixin,容易出现变量和方法重名,就会导致冲突或覆盖现象

Hook 优点:

  • Hook函数的变量和方法是显示传入,数据来源明确
  • 自定义Hook可以在引入的时候对同名变量重命名,代码易维护

19 Vue 常用的修饰符有哪些

v-on:

  • .prevent: 调用 event.preventDefault() ,阻止提交事件重载页面
  • .stop:调用 event.stopPropagation() ,阻止单击事件冒泡
  • .self:只触发元素本身的事件,不会触发子元素的事件
  • .capture: 与事件冒泡相反,事件捕获由外向内
  • .once:事件只会触发一次
  • .native:监听组件根元素的原生事件

v-model:

  • .lazy:让光标离开输入框再同步数据
  • .number:输入字符串转为有效的数字
  • .trim:输入首尾空格过滤

v-bind:

  • .sync:语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器

20 Vue 常用指令有哪些

  • v-model:多用于表单元素实现数据双向绑定
  • v-bind:动态绑定属性、样式
  • v-on:绑定事件
  • v-show:元素显示与隐藏
  • v-if:元素显示与隐藏
  • v-for:循环遍历生成元素
  • v-text:解析文本
  • v-html:解析html标签
  • v-once:只渲染一次,后续不再更新
  • v-pre:原位输出标签内部的元素
  • v-clock:防止闪烁

21 怎么理解 Vue 的单向数据流

  1. 数据从父组件传递给子组件,只能单向绑定
  2. 子组件内部不能直接修改从父级传递过来的数据
  3. 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
  4. 父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值
  5. 子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改

22 Vue 中为什么data是个函数

  1. 因为每个组件都是 Vue 实例, Vue组件是用来复用的,且 JS 里对象是引用关系,如果组件中 data 是一个对象,那么这样作用域没有隔离,子组件中的 data 属性值就会相互影响
  2. 如果组件中 data 选项是一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回新的 data ,类似于给每个 Vue 组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据,组件实例之间的 data 属性值就不会互相影响

为什么 new Vue 实例里,data 可以直接是一个对象?
因为 new Vue 的实例不会被复用,它只会 new 一次,因此不存在引用对象的问题

23 说说你对 SPA 单页面的理解,它的优缺点分别是什么?

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制动态的变换 HTML 内容,从而实现 UI 与用户的交互,避免页面的重新加载。

优点:

  • 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染
  • 前后端分离,分工更明确,前端进行交互逻辑,后端负责数据处理

缺点:

  • 首次渲染速度相对较慢
  • 不利于搜索引擎的抓取

24 MVC 和 MVVM区别

MVC:就是 Model-View-Controller 对应模型-视图-控制层,Controller控制层,负责接收视图发送过来的数据,同时控制 Model 数据;思想就是Controller 将 Model 的数据展示在 View 上

MVVC:就是 Model-View-ViewModel 对应模型-视图-视图模型,ViewModel 是 Model 和 View之间的桥梁,通过双向数据绑定把 View 层和 Model 层连接起来,使 View 数据的变化会同步到Model,Model 数据的变化也会反应到 View 上;思想是 View 和 Model 实现数据同步,不需要手动更新

区别:

  1. MVC是单向的,而MVVC是双向,并且是自动的,监听到数据发生改变会让视图重新渲染,监听到视图发生改变会让对应数据变化
  2. MVVM解决了MVC中大量的DOM操作使页面渲染性能降低的问题,在数据频繁更新的时候,采用了虚拟DOM,减少页面过度渲染,从而提高性能

25 Vue 数据双向绑定原理?(响应式原理)

Vue2:采用数据劫持结合发布订阅者模式的方式,通过Object.defineProperty() 数据劫持,来劫持各个属性的 getter、setter ,在数据更新时发布消息给 getter、setter,触发相应的监听回调,从而使关联的组件重新渲染
优点:

  • 兼容性好,支持 IE9

缺点:

  • 对象直接添加属性或者删除已有属性,页面不会更新(可通过 $set$delete$forceUpdate() 的方法解决)
  • 数组通过直接索引下标替换元素,页面不会更新(可通过数据的七个方法解决:pushpopshiftunshiftsplicesortreserve

Vue3:用 Proxy 代理监听劫持对象的操作,然后通过 Reflect 动态的对被代理对象进行相应操作
优点:

  • Proxy 可以直接监听对象而非属性,可以直接监听数组的变化
  • Proxy 有多达 13 种拦截方法,例如:applyownKeysdeletePropertyhas 等是 Object.defineProperty() 不具备的
  • Proxy 返回的是一个新对象,可以只操作新的对象达到目的,而Object.defineProperty 只能遍历对象属性直接修改

缺点:

  • 浏览器兼容性较差,而且无法用 polyfill 磨平

26 Vue 是如何实现数据双向绑定的?

Vue 数据双向绑定主要是指:数据变化更新视图,视图变化更新数据。
在这里插入图片描述
Vue 主要通过以下 4 个步骤来实现数据双向绑定的:

  • 实现一个监听器 Observer:用来监听劫持数据对象的所有属性,在数据变动时可以拿到最新值并通知订阅者。
  • 实现一个解析器 Compile:用来对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦监听到数据有变动,就会通知更新视图。
  • 实现一个订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。
  • 实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。

27 v-model 的原理

在 vue 项目中主要使用 v-model 指令在表单 inputtextareaselect 等元素上创建双向数据绑定,v-model 本质上就是一个、
语法糖,能够在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 元素使用 value 属性和 input 事件;
  • checkbox 和 radio 使用 checked 属性和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

28 Vue 中 key 的作用

  • 当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。
  • 如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
  • key 的作用是为 Vue 中 vnode 添加唯一标记,通过 key 可以更快找到新旧 vnode 的变化,从而更高效地更新虚拟DOM。

29 VNode 是什么?虚拟 DOM 是什么?

  • VNode的全称是Virtual Node,表示虚拟节点,VNode的本质是一个JavaScript的对象,用来描述如何创建真实的DOM节点,而虚拟DOM就是多个VNode形成的树结构。
  • 在vue.js中,渲染视图的过程是先创建VNode,然后使用VNode生成真实的DOM元素,最后插入到页面渲染视图。
  • 在数据频繁更新的时候,利用虚拟DOM通过一定的算法优化后快速渲染页面,能够有效避免真实DOM频繁更新,减少页面的回流和重绘,提高性能。

30 Diff 算法是什么?

Diff算法是一种对比算法。对比两者是旧虚拟DOM和新虚拟DOM,对比出是哪个虚拟节点更改了,找出并更新这个虚拟节点所对应的真实节点,而不用更新其他数据没发生改变的节点,实现精准地更新真实DOM,从而提高效率。

  1. vue 在内部通过一个叫做 patch 的函数来完成新旧虚拟DOM比对过程。vue 采用深度优先遍历,只比较同一层级,不跨层级比较,如果标签名不同,直接删除,不会继续深度比较;如果标签名相同,key相同,则认为是相同节点,不继续深度比较。
  2. 当数据发生变化时,会触发setter方法,并通知所有订阅者watcher调用patch方法,给真实DOM打补丁,更新相应的视图。

31 Vue 的 nextTick 的原理是什么?

作用:
nextTick 是Vue 提供的一个全局API,用于处理DOM 更新的操作。 Vue 采用异步更新策略,当监听到数据发生变化的时候不会立即去更新DOM,而是将这些操作都缓存在一个任务队列,在事件循环结束之后,刷新队列,统一执行DOM更新操作。
nextTick 接收一个回调函数作为参数,并将这个回调函数延迟到DOM更新之后再执行。

原理:

  • 将传入的回调函数包装成异步任务,异步任务又分为宏任务和微任务,为了尽快执行所以优先选择微任务
  • nextTick 提供了四种异步方法 Promise.thenMutationObserversetImmediatesetTimeout(fn,0)

使用场景:

  1. 想要操作基于最新数据生成的DOM时,就将这个操作放在nextTick 的回调中。
  2. 想要在created() 生命周期的created() 操作DOM,一定要放在nextTick 的回调函数中,因为此时模板还没有被渲染,无法进行DOM操作。

32 如何对 Vue 组件进行封装的?

组件封装能够把页面抽象成多个相对独立的模块,实现代码复用,提高开发效率。

  • 分析需求:确定业务需求,把页面中可以复用的结构、样式以及功能,单独抽离成一个文件,实现复用。
  • 具体步骤:
    1. 使用 Vue.component 方法注册组件,子组件需要数据,可以在 props 中接收定义,而子组件修改好数据后,想把数据传递给父组件,可以采用$emit 方法向外抛数据。
    2. 如果需要给组件传入模板,可以使用 slot 插槽 。

33 Vue3 和 Vue2 的区别

  1. 响应式原理
  2. 生命周期
  3. Vue3 支持多个根节点,Vue2 不支持
  4. Vue3 是组合式API (Composition API),Vue2 是选项API(Options API)
  5. 新增组件:<Teleport> 传送门、<Suspense> 异步组件
  6. 更好的支持TypeScript
  7. 打包优化:引入 tree-shaking 技术打包时移除无用的代码。

34 说一下 Composition API

Composition API 是 vue3 新增的功能,比 mixin 更强大。它可以把各个功能模块独立开来,提高代码逻辑的可复用性,同时代码也更容易压缩。Composition Api将某个逻辑关注点相关的代码全都放在一个函数里,这样,当需要修改一个功能时,就不再需要在文件中跳来跳去。

setup
setup() 函数是一个新的组件选项, 替代了 Vue2中 beforeCreated()created() 生命周期函数,Vue3 中定义的 methods、watch、computed、data数据等都放在了 setup() 函数中。

ref
ref 函数用来创建响应式数据,可以接收原始数据类型与引用数据类型。模板中可直接使用,JS中需要通过 .value 的形式才能使用。

reactive
reactive 函数只能接收引用数据类型,模板和JS中可直接使用

readonly
readonly 用来接收一个只读对象

computed

  • 传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象
  • 传入一个拥有 get 和 set 函数的对象,创建一个可手动修改的计算状态

watch
watch监听器,需要监听指定的数据,默认情况是懒执行的,只有监听的数据发生改变才执行回调

watchEffect
watchEffect是一个副作用函数,会立即执行,不需要指定监听的数据,依赖项发生改变就会执行回调。

35 Vue 项目优化的解决方案都有哪些?

  • 路由懒加载。有效拆分应用大小,访问时才异步加载。
  • keep-alive缓存页面。避免重复创建组件实例,且能保留缓存组件状态。
  • 事件销毁。组件销毁后把全局变量和定时器销毁。
  • 图片懒加载,小图片使用 base64
  • 子组件分割。较重的状态组件适合拆分。
  • 使用 mini-css-extract-plugin 插件抽离 css
  • 配置 optimization 把公共的 js 代码抽离出来
  • 通过 webpack 处理文件压缩
  • 不打包框架、库文件,通过 cdn 的方式引入
  • 开启 Gzip 压缩
  • 长列表性能优化,可采用虚拟列表。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值