一、编码阶段
-
尽量减少
data
中的数据,data
中的数据都会增加getter
和setter
,会收集对应的watcher
-
Getter(获取器) :Getter是一个用于获取数据值的函数。在Vue.js中,当你在模板中 访问数据属性时,实际上是在调用这些属性的Getter函数。
-
Setter(设置器) :Setter是一个用于设置数据值的函数。在Vue.js中,当你尝试更改数据属性时,实际上是在调用这些属性的Setter函数。Setter允许你在写入数据时执行一些逻辑,例如验证或触发其他操作。
-
Watcher(观察者) :Watcher是Vue.js内部的机制,用于监听数据的变化并响应它们。当数据发生变化时,Watcher会触发相应的回调函数,例如重新渲染视图。Vue.js会自动创建和管理Watcher,但你也可以显式创建自定义的Watcher来观察特定数据。
使用简单的 计算属性
应该把复杂计算属性分割为尽可能多的更简单的 property。
-
易于测试
当每个计算属性都包含一个非常简单且很少依赖的表达式时,撰写测试以确保其正确工作就会更加容易。
-
易于阅读
简化计算属性要求你为每一个值都起一个描述性的名称,即便它不可复用。这使得其他开发者 (以及未来的你) 更容易专注在他们关心的代码上并搞清楚发生了什么。
-
更好的"拥抱变化"
任何能够命名的值都可能用在视图上。举个例子,我们可能打算展示一个信息,告诉用户他们存了多少钱;也可能打算计算税费,但是可能会分开展现,而不是作为总价的一部分。
小的、专注的计算属性减少了信息使用时的假设性限制,所以需求变更时也用不着那么多重构了。
computed 大家后很熟悉, 它会在其表达式中依赖的响应式数据发送变化时重新计算。如果我们在一个计算属性中书写了比较复杂的表达式,那么其依赖的响应式数据也任意变得更多。当其中任何一个依赖项变化时整个表达式都需要重新计算
inilet price = computed(()=>{ let basePrice = manufactureCost / (1 - profitMargin) return ( basePrice - basePrice * (discountPercent || 0) ) })
当 manufactureCost、profitMargin、discountPercent 中任何一个变化时都会重新计算整个 price。
但是如果我们改成下面这样
scsslet basePrice = computed(() => manufactureCost / (1 - profitMargin)) let discount = computed(() => basePrice * (discountPercent || 0)) let finalPrice = computed(() => basePrice - discount)
如果当 discountPercent 变化时,只会 重新计算 discount 和 finalPrice,由于
computed
的缓存特性
,不会重新计算 basePrice -
-
v-if
和v-for
不能连用, v-for的优先级比v-if高,一起使用会造成性能浪费v-if
通过直接操作 DOM 的删除和添加来控制元素的显示和隐藏,v-if
来移除 DOM 可以节约掉浏览器渲染这个的一部分DOM需要的资源v-show
是通过控制 DOM 的display
CSS熟悉来控制元素的显示和隐藏,频繁的 显示/隐藏 变化时,我们使用v-show
来提高性能。
-
SPA 页面采用 keep-alive 缓存组件
-
key 保证唯一:对虚拟Dom,diff算法得优化
-
使用路由懒加载、异步组件、函数式组件
- 异步组件通过defineAsyncComponent方法来导入组件就可以实现。异步组件 | Vue.js (vuejs.org)
- 函数式组件:
- ![]( "产研中心 > vue2项目性能优化 > image2023-9-25_18-0-24.png")
-
防抖、节流
-
第三方模块按需导入
-
长列表滚动到可视区域动态加载
-
图片懒加载
二、SEO 优化
-
预渲染
- prerender-spa-plugin 插件实现
-
服务端渲染 SSR
三、打包优化
-
压缩代码
-
Tree Shaking/Scope Hoisting(作用域提升)
- 作用域提升(Scope Hoisting)是一种优化技术,通常在JavaScript的模块系统中使用,以减小最终打包文件的体积并提高应用性能。该技术的主要思想是将模块之间的依赖关系重新组织,以减少不必要的函数调用和模块引入,从而降低运行时的开销
- 树摇(Tree Shaking)是一种用于优化JavaScript代码的技术,通常用于移除未被使用的代码,以减小最终打包文件的大小。它是现代前端构建工具中常见的一个优化步骤,特别是在使用模块系统(如ES6模块或CommonJS)的项目中。
-
使用 cdn 加载第三方模块
-
多线程打包 happypack:HappyPack 是一个用于在 Webpack 构建过程中实现多线程并行处理的工具,它可以加速打包过程,特别是对于大型项目来说效果显著。
- 需要注意的是,虽然 HappyPack 可以提高构建速度,但也可能引入一些额外的复杂性和潜在的问题。在配置 HappyPack 时,确保了解你的项目需求和构建过程,并进行适当的测试和优化。另外,Webpack 5 后的版本在内部已经实现了一些多线程构建的优化,因此可以考虑直接使用 Webpack 5 的多线程功能,而不依赖于 HappyPack。
-
splitChunks 抽离公共文件:是 Webpack 的一个功能,用于将公共的代码或库从不同的入口点中抽离出来,以便减小生成的 bundle 文件的大小,提高加载性能。通过配置
splitChunks
,你可以将重复的代码合并为单独的文件,以便多个入口点共享这些代码。 -
sourceMap 优化:Source Map(源映射)是一个非常有用的工具,它可以将编译后的代码映射回原始的源代码,从而方便开发者在调试时定位问题。然而,Source Map 也会增加打包文件的大小,因此需要进行一些优化来在开发和生产环境中合理使用它。
- 在开发环境启用详细的 Source Map: 在开发环境中,启用详细的 Source Map 是非常有帮助的,因为它可以提供准确的源代码映射,方便开发者调试。
- 在生产环境中启用压缩的 Source Map: 在生产环境中,你可以启用压缩的 Source Map,以减小打包文件的大小。
四、用户体验
-
骨架屏
-
PWA:
渐进式 Web 应用程序(Progressive Web App,PWA)是一种具有渐进增强功能的现代 web 应用程序,它结合了 web 和本地应用程序的最佳特性,提供了更好的用户体验和性能。以下是关于 PWA 的一些关键特点和要点:
-
可离线访问:PWA 允许用户在离线或不稳定网络连接的情况下访问应用程序。通过使用 Service Worker 技术,PWA 可以缓存应用程序的资源,包括 HTML、CSS、JavaScript 和图像,使用户能够在没有网络连接的情况下浏览内容。
-
响应式设计:PWA 应具有响应式设计,能够在各种设备上提供一致的用户体验,包括桌面、平板和移动设备。
-
安装性:用户可以将 PWA 安装到其设备的主屏幕上,就像本地应用程序一样。这使得用户可以更轻松地访问应用程序,而不必通过浏览器。
-
自动更新:PWA 具有自动更新机制,当应用程序有新版本可用时,用户将会得到通知并自动更新,确保用户始终使用最新版本的应用程序。
-
推送通知:PWA 具备推送通知功能,可以向用户发送通知,提醒他们关注应用程序的重要信息或事件。
-
快速加载:PWA 应尽量减少启动时间和页面加载时间,以提供更快的用户体验。通过使用缓存和延迟加载技术,可以实现更快的页面加载。
-
安全性:PWA 应采用 HTTPS 协议,以确保数据传输的安全性和用户隐私的保护。
-
可发现性:PWA 应具有良好的搜索引擎可发现性,以便搜索引擎可以索引和排名应用程序的内容。
-
可分享性:PWA 应支持分享功能,允许用户轻松地分享应用程序或应用程序内的内容。
-
跨平台:PWA 不受特定平台的限制,可以在多种操作系统和浏览器上运行。
-
-
还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启 gzip 压缩等。
vue 中的 spa 应用如何优化首屏加载速度?
优化首屏加载可以从这几个方面开始:
请求优化 : CDN
将第三方的类库放到 CDN
上,能够大幅度减少生产环境中的项目体积,另外 CDN
能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。
缓存 :将长时间不会改变的第三方类库或者静态资源设置为强缓存,将 max-age
设置为一个非常长的时间,再将访问路径加上哈希达到哈希值变了以后保证获取到最新资源,好的缓存策略有助于减轻服务器的压力,并且显著的提升用户的体验
gzip :开启 gzip
压缩,通常开启 gzip
压缩能够有效的缩小传输资源的大小。
懒加载 :当 url
匹配到相应的路径时,通过 import
动态加载页面组件,这样首屏的代码量会大幅减少,webpack
会把动态加载的页面组件分离成单独的一个 chunk.js
文件
预渲染 :由于浏览器在渲染出页面之前,需要先加载和解析相应的 html
、css
和 js
文件,为此会有一段白屏的时间,可以添加 loading
,或者骨架屏幕
尽可能的减少白屏对用户的影响体积优化
合理使用第三方库 : 对于一些第三方 ui 框架、类库,尽量使用按需加载
,减少打包体积
使用可视化工具分析打包后的模块体积 :webpack-bundle- analyzer
这个插件在每次打包后能够更加直观的分析打包后模块的体积,再对其中比较大的模块进行优化
提高代码使用率 : 利用代码分割
,将脚本中无需立即调用的代码在代码构建时转变为异步加载的过程
封装 :构建良好的项目架构,按照项目需求就行全局组件,插件,过滤器,指令,utils
等做一些公共封装,可以有效减少我们的代码量,而且更容易维护资源优化
图片懒加载: 使用图片懒加载可以优化同一时间减少 http
请求开销,避免显示图片导致的画面抖动,提高用户体验
使用 svg 图标: 相对于用一张图片来表示图标,svg
拥有更好的图片质量,体积更小,并且不需要开启额外的 http
请求
压缩图片: 可以使用 image-webpack-loader
,在用户肉眼分辨不清的情况下一定程度上压缩图片