몇일 전, Vue 프로젝트가 커질수록 최적화가 어려워지고 많은 고통을 겪는다고 다들 말하는 것을 봤습니다. 이 문제는 결국에는 해결되어야 할 문제입니다. 모든 주요 테스트 웹사이트에는 관련 데이터가 있습니다. 본론으로 들어가죠
소위 기본 최적화는 모든 웹 프로젝트에 필요하며 문제의 근원입니다. HTML, CSS, JS는 .vue 파일, <p style="margin-top:1.5em; margin-bottom:1.5em; color:rgb(51,51,51); font-size:14px">을 최적화하는 첫 번째 단계입니다. -size:0.93em; padding:2px 4px; color:rgb(199,37,78) background-color:rgb(249,242,244)"></p>
<template>,<style>,<script>
,下面逐个谈下 vue 项目里都有哪些值得优化的点
语义化标签,避免乱嵌套,合理命名属性等等标准推荐的东西就不谈了。
模板部分帮助我们展示结构化数据,vue 通过数据驱动视图,主要注意一下几点
v-show,v-if 用哪个?在我来看要分两个维度去思考问题,第一个维度是权限问题,只要涉及到权限相关的展示无疑要用 v-if
,第二个维度在没有权限限制下根据用户点击的频次选择,频繁切换的使用 v-show
,不频繁切换的使用 v-if
,这里要说的优化点在于减少页面中
dom 总数,我比较倾向于使用 v-if
,因为减少了 dom 数量,加快首屏渲染,至于性能方面我感觉肉眼看不出来切换的渲染过程,也不会影响用户的体验。
不要在模板里面写过多的表达式与判断 v-if="isShow
&& isAdmin && (a || b)"
const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo') const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo') const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')
, vue 프로젝트에서 최적화할 만한 포인트를 하나씩 이야기해보겠습니다v-show, v-if 어느 것을 사용할 것인가? 제 생각에는 이 문제를 두 가지 차원에서 생각해 볼 필요가 있습니다. 첫 번째 차원은 권한 관련 표시가 포함되는 한 v-if
, 두 번째 차원은 권한 제한 없이 사용자 클릭 빈도를 기준으로 선택되며 빈번한 전환에 사용됩니다. v-show
v-if
, 여기서 최적화 포인트는
총 돔 수에 대해서는 v-if
, 이는 DOM 수를 줄이고 첫 번째 화면 렌더링 속도를 높이기 때문입니다. 전환 렌더링은 육안으로 볼 수 없다고 생각합니다. 이 프로세스는 사용자 경험에 영향을 미치지 않습니다. 🎜
템플릿 v -if="is쇼
&& isAdmin && (a || b)"
, 이 표현식은 인식 가능하지만 장기적인 해결책은 아닙니다. 불편해 보일 때는 메소드에 적절하게 작성하고 계산하여 메소드에 캡슐화하고, 그래서 장점은 여러 곳에서 동일한 표현을 판단하는 것이 편리하고, 동일한 권한을 가진 다른 요소는 판단하고 표시할 때 동일한 메소드를 호출할 수 있다는 것입니다.
루프에서 하위 구성 요소를 호출할 때 키를 추가하세요. 예를 들어 item.id
키, 배열 데이터가 다음과 같은 경우 ['a', 'b', 'c', 'a']
, :key="item"
은 분명히 의미가 없습니다. 더 좋은 방법은 (항목,
index) arr
에서 :key="index"
키의 고유성을 보장합니다. item.id
作为
key,假如数组数据是这样的 ['a' , 'b', 'c', 'a']
,使用 :key="item"
显然没有意义,更好的办法就是在循环的时候 (item,
index) in arr
,然后 :key="index"
来确保 key 的唯一性。
将样式文件放在 vue 文件内还是外?讨论起来没有意义,重点是按模块划分,我的习惯是放在 vue 文件内部,方便写代码是在同一个文件里跳转上下对照,无论内外建议加上 <style
scoped>
将样式文件锁住,目的很简单,再好用的标准也避免不了多人开发的麻烦,约定命名规则也可能会冲突,锁定区域后尽量采用简短的命名规则,不需要 .header-title__text
之类的
class,直接 .title
搞定。
为了和上一条作区分,说下全局的样式文件,全局的样式文件,尽量抽象化,既然不在每一个组件里重复写,就尽量通用,这部分抽象做的越好说明你的样式文件体积越小,复用率越高。建议将复写组件库如 Element 样式的代码也放到全局中去。
不使用 float 布局,之前看到很多人封装了 .fl --
float: left
到全局文件里去,然后又要 .clear
,现在的浏览器还不至于弱到非要用 float
.header-title__text
등
클래스, 직접 .title
완료되었습니다. .fl
float: 왼쪽
을 전역 파일로 가져온 다음 .clear
, 현재 브라우저는 float
이 호환되므로 완전히 괜찮습니다.
Flex와 Grid의 호환성은 보통 수준입니다. 실제로 Flex 레이아웃에서 기능을 구현할 수 있습니다. Float를 사용하면 레이아웃에 문제가 발생할 수 있습니다. 🎜🎜🎜🎜기타 일반적인 사양에 대해서는 여기서 자세히 다루지 않겠습니다. 🎜🎜script🎜🎜이 부분이 최적화하기 가장 어려운 부분이기도 한데 개인적인 의견을 말씀드리겠습니다. 🎜여러 사람과 함께 개발할 때는 각 구성 요소를 export default {}
메소드의 순서가 동일하므로 해당 메소드를 쉽게 찾을 수 있습니다. 내 개인적인 습관
데이터, 소품, 후크, 시계, 계산, 구성 요소. export default {}
内的方法顺序一致,方便查找对应的方法。我个人习惯
data、props、钩子、watch、computed、components。
data 里要说的就是初始化数据的结构尽量详细,命名清晰,简单易懂,避免无用的变量,isEditing 实际可以代表两个状态,true 或 false,不要再去定义 notEditing 来控制展示,完全可以在模板里 {{
isEditing ? 编辑中 : 保存 }}
props 父子组件传值时尽量 :width="" :heigth=""
不要 :option={}
,细化的好处是只传需要修改的参数,在子组件
props 里加数据类型,是否必传,以及默认值,便于排查错误,让传值更严谨。
钩子理解好生命周期的含义就好,什么时间应该请求,什么时间注销方法,哪些方法需要注销。简单易懂,官网都有写。
metheds 中每一个方法一定要简单,只做一件事,尽量封装可复用的简短的方法,参数不易过多。如果十分依赖 lodash 开发,methed 看着会简洁许多,代价就是整体的 bundle 体积会大,假如项目仅仅用到小部分方法可以局部引入 loadsh,不想用 lodash 的话可以自己封装一个 util.js 文件
watch 和 computed 用哪个的问题看官网的例子,计算属性主要是做一层 filter 转换,切忌加一些调用方法进去,watch 的作用就是监听数据变化去改变数据或触发事件如 this.$store.dispatch('update',
{ ... })
{
isEditing ? 편집: 저장}}
props 상위 구성 요소와 하위 구성 요소 간에 값을 전달할 때 :width="" :heigth=""
< code style="font-family:"Source Code Pro",Consolas,Menlo,Monaco,"Courier New",monospace; 글꼴 크기:0.93em; padding:2px 4px; color:rgb (199,37,78); background-color:rgb(249,242,244)">:option={}, 개선의 장점은 수정해야 하는 매개변수만 하위 구성 요소에 전달된다는 것입니다.
props에 데이터 유형을 추가하고, 전달해야 하는지 여부와 기본값을 추가하여 오류 문제 해결을 용이하게 하고 값 전송을 더욱 엄격하게 만듭니다. 어떤 것을 사용할지에 대한 질문은 공식 웹사이트의 예를 참조하세요. 계산된 속성은 주로 필터 변환 레이어입니다. 일부 호출 방법을 추가하지 마십시오. watch의 기능은 데이터 변경을 모니터링하여
this.$store.dispatch('update',
{ ... })
中午官网链接如上,例子如下
const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo') const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo') const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')
这段代码将 Foo, Bar, Baz 三个组件打包进了名为 group-foo
的 chunk 文件,当然啦是 js 文件
其余部分正常写就可以,在网站加载时会自动解析需要加载哪个 chunk,虽然分别打包的总体积会变大,但是单看请求首屏速度的话,快了好多。
vuex 面临的问题和解决方案有几点
当网站足够大时,一个状态树下,根的部分字段繁多,解决这个问题就要模块化 vuex,官网提供了模块化方案,允许我们在初始化 vuex 的时候配置 modules。每一个 module 里面又分别包含 state 、action 等,看似是多个状态树,其实还是基于 rootState 的子树。细分后整个 state 结构就清晰了,管理起来也方便许多。
由于 vuex 的灵活性,带来了编码不统一的情况,完整的闭环是 store.dispatch('action') -> action -> commit -> mutation -> getter -> computed,实际上中间的环节有的可以省略,因为 API 文档提供了以下几个方法 mapState、mapGetters、mapActions、mapMutations,然后在组件里可以直接调取任何一步,还是项目小想怎么调用都可以,项目大的时候,就要考虑 vuex 使用的统一性,我的建议是不论多简单的流程都跑完整个闭环,形成代码的统一,方便后期管理,在我的组件里只允许出现 dispatch 和 mapGetters,其余的流程都在名为 store 的 vuex 文件夹里进行。
基于上面一条,说下每个过程里面要做什么,前后端数据一定会有不一致的地方,或是数据结构,或是字段命名,那么究竟应该在哪一步处理数据转换的逻辑呢?有人会说其实哪一步都可以实现,其实不然,我的建议如下
在发 dispatch 之前就处理好组件内需要传的参数的数据结构和字段名
到了 action 允许我们做的事情很多,因为这部支持异步,支持 state, rootState, commit, dispatch, getters,由此可见责任重大,首先如果后端需要部分其他 module 里面的数据,要通过 rootState 取值再整合到原有数据上,下一步发出请求,建议(async await + axios),拿到数据后进行筛选转换,再发送 commit 到 mutation
这一步是将转换后的数据更新到 state 里,可能会有数据分发的过程(传进一个 object 改变多个 state 中 key 的 value),可以转换数据结构,但是尽量不做字段转换,在上一步做
此时的 store 已经更新,使用 getter 方法来取值,token:
state => state.token
,单单的取值,尽量不要做数据转换,需要转换的点在于多个地方用相同的字段,但是结构不同的情况(很少出现)。
在组件里用 mapGetters 拿到对应的 getter 值。
上面说了代码方面的规范和优化,下面说下重点的打包优化,前段时间打包的 vender bundle 足足 1.4M,app bundle 也有 270K,app bundle 可以通过组件懒加载解决,vender 包该怎么解决?
有人会质疑是不是没压缩或依赖包没去重,其实都做了就是看到的 1.4M。
解决方法很简单,打包 vender 时不打包 vue、vuex、vue-router、axios 等,换用国内的 bootcdn 直接引入到根目录的 index.html 中。
例如:
<script src="//cdn.bootcss.com/vue/2.2.5/vue.min.js"></script> <script src="//cdn.bootcss.com/vue-router/2.3.0/vue-router.min.js"></script> <script src="//cdn.bootcss.com/vuex/2.2.1/vuex.min.js"></script> <script src="//cdn.bootcss.com/axios/0.15.3/axios.min.js"></script>
在 webpack 里有个 externals,可以忽略不需要打包的库
externals: { 'vue': 'Vue', 'vue-router': 'VueRouter', 'vuex': 'Vuex', 'axios': 'axios' }
此时的 vender 包会非常小,如果不够小还可以拆分其他的库,此时增加了请求的数量,但是远比加载一个 1.4M 的 bundle 快的多。
위 내용은 Vue 프로젝트를 최적화하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!