theme: smartblue
12.2
1.闭包
是指有权访问另一个函数作用域中的变量的函数。简单来说,就是一个函数能够访问其外部函数中定义的变量。
function outerFunction() {
var outerVariable = "I am an outer variable";
function innerFunction() {
console.log(outerVariable);
}
return innerFunction;
}
var closure = outerFunction();
console.log(closure)
- Vue 的响应式原理
主要是通过使用 ES5 的Object.defineProperty()方法来实现的。当一个 Vue 实例被创建时,Vue 会遍历 data 对象的所有属性,并使用Object.defineProperty()将这些属性转换为 getter/setter。这样,当这些属性被访问或修改时,Vue 可以触发相应的更新操作。
具体来说,Vue 会在组件渲染过程中收集依赖,当数据发生变化时,通知依赖这些数据的组件进行更新
3.在 React 中,setState在某些情况下是异步的,在某些情况下是同步的。
在事件处理函数中,setState是异步的。这是因为 React 为了提高性能,会将多个setState调用合并成一个批次进行处理。 在生命周期方法和原生事件处理函数中,setState是同步的。
4.懒加载的原理
延迟加载资源:
-
懒加载的核心思想是在页面初始加载时,只加载当前视口(viewport)内或即将进入视口的资源,而不是一次性加载所有资源。
-
这样可以减少初始页面加载时间,提高用户体验,特别是对于包含大量图片、视频或其他大型资源的页面。MDN Web Docs - 懒加载
监听滚动事件:
-
通过监听浏览器的滚动事件,判断资源是否即将进入视口。
-
当用户滚动页面时,不断检查资源与视口的位置关系。如果某个资源进入视口范围,就触发加载该资源的操作。
判断资源位置:
- 通常使用元素的位置信息来判断资源是否在视口内。可以通过获取元素的
getBoundingClientRect()方法来获取元素相对于视口的位置和大小信息。 - 如果元素的顶部或底部与视口有交集,就可以认为该元素即将进入视口或已经在视口内。
加载资源:
- 当判断资源需要加载时,可以使用各种方式加载资源。对于图片,可以设置
src属性来加载图片;对于视频,可以设置src属性或使用其他视频加载技术。 - 加载资源后,可以根据需要进行一些后续处理,如显示加载完成的提示、更新页面布局等。
例如,在实现图片懒加载时,可以先将图片的 src 属性设置为一个占位图片或空白路径,然后在判断图片进入视口时,将 src 属性设置为真正的图片地址来加载图片。
总之,懒加载通过延迟加载资源和根据用户行为动态加载资源的方式,提高了页面的加载速度和性能,为用户提供更好的体验。
4.路由懒加载的原理
动态导入:
- 路由懒加载利用了 JavaScript 的动态导入(dynamic import)特性。在传统的路由配置中,通常会直接引入组件文件,这会导致在应用初始加载时就加载所有的路由组件,即使这些组件可能在用户的整个浏览过程中并不会立即被访问到。
- 而路由懒加载则是在需要访问特定路由时,才动态地导入对应的路由组件。^^Vue.js 官方文档 - 路由懒加载
按需加载:
- 当用户导航到一个特定的路由时,浏览器才会触发对该路由对应的组件的加载。这样可以大大减少初始页面加载的时间和资源消耗,因为只有实际需要的组件才会被加载。
- 例如,一个大型应用可能有很多不同的页面,每个页面都对应一个路由组件。如果没有路由懒加载,所有这些组件都会在应用启动时被加载,这可能会导致很长的加载时间。而有了路由懒加载,只有当用户访问特定页面时,对应的组件才会被加载。
代码分割:
- 路由懒加载通常也会结合代码分割(code splitting)技术。代码分割可以将应用的代码分割成多个小块,每个小块可以独立加载。这样可以进一步优化应用的加载性能,因为浏览器可以并行地加载这些小块,而不是一次性加载一个巨大的文件。
- 例如,在 Vue.js 中,可以使用
import()函数来实现路由懒加载和代码分割。Webpack 官方文档 - 代码分割
总之,路由懒加载通过动态导入和按需加载路由组件,结合代码分割技术,可以显著提高大型应用的加载性能和用户体验。
6.Vue 在性能优化方面的一些方式
一、代码层面
1. 合理使用计算属性和侦听器
计算属性(computed):当依赖的数据发生变化时,计算属性会自动更新,避免了在模板中重复执行复杂的逻辑表达式。例如,如果你需要根据一个数组的长度来显示不同的文本,可以使用计算属性来获取数组长度,而不是在模板中每次都调用 array.length。
侦听器(watch):适合用于监听一个特定的数据变化,然后执行一些异步操作或者复杂的逻辑。但要注意避免过度使用侦听器,因为它会在每次被监听的数据变化时触发,可能会导致性能开销。
2. 避免不必要的组件重新渲染
Vue 的响应式系统会在数据变化时自动更新相关的组件。但是,如果一个组件的渲染结果只依赖于部分数据,而其他数据的变化也导致了这个组件的重新渲染,就会造成不必要的性能开销。可以使用 Vue.nextTick 或者 this.$nextTick 在数据变化后延迟执行一些操作,确保 DOM 已经更新完毕,避免重复渲染。
3. 优化 v-for 循环
在 v-for 循环中避免使用复杂的表达式或者方法调用,这会导致每次渲染时都进行计算,影响性能。可以将复杂的计算提前在组件的 data 或者 computed 属性中进行,然后在模板中直接使用结果。
如果可能的话,为 v-for 循环添加一个唯一的 key 属性,这有助于 Vue 更高效地跟踪和更新 DOM 元素。
二、组件层面
1. 拆分大型组件
如果一个组件变得非常庞大和复杂,它的渲染和更新会消耗更多的资源。可以将大型组件拆分成多个小型组件,每个组件只负责一部分功能,这样可以提高代码的可维护性和性能。
2. 异步组件加载
对于一些不立即需要加载的组件,可以使用异步组件的方式进行加载。这样可以在需要的时候才加载这些组件,减少初始加载时间。例如:
const AsyncComponent = () => import('./AsyncComponent.vue');
export default { components: { AsyncComponent } };
三、网络请求层面
1. 合理使用缓存
如果你的应用中有频繁的网络请求,可以考虑使用缓存来存储已经获取的数据。可以使用浏览器的本地存储(localStorage)或者会话存储(sessionStorage)来存储一些不经常变化的数据,避免重复请求。
对于一些特定的 API 请求,可以使用 HTTP 缓存机制,设置合适的缓存头,让浏览器或者代理服务器缓存响应结果。
2. 减少请求次数
合并多个小的请求为一个大的请求,可以减少网络开销和提高性能。例如,可以使用 GraphQL 来一次性获取多个数据资源,而不是分别发送多个 HTTP 请求。
四、打包优化层面
1. 代码压缩和混淆
在项目打包时,可以使用工具如 Webpack 或者 Vite 对代码进行压缩和混淆。这可以减小代码文件的大小,加快加载速度。
2. 懒加载
对于一些不立即需要加载的模块或者资源,可以使用懒加载的方式进行加载。例如,在 Vue Router 中,可以使用懒加载路由组件:
const Home = () => import('./Home.vue');
const routes = [ { path: '/', component: Home } ];
五、其他方面
1. 使用事件总线时注意清理
如果在项目中使用了事件总线(Event Bus)来进行组件之间的通信,在组件销毁时要记得清理事件监听器,避免内存泄漏。
2. 优化图片和资源加载
对于图片等资源,可以使用合适的图片格式和压缩工具来减小文件大小。同时,可以使用懒加载技术,在用户滚动到图片位置时再加载图片。