ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

随笔

2022-07-22 08:35:02  阅读:109  来源: 互联网

标签:缓存 obj DOM 响应 vue key 随笔


原型为函数独有,通过new继承,
原型链大家都有,查找规则:从当前实例查找再去原型链查找
实例的原型链指向构造函数的prototype 最上面是object

关于 Vue 编译原理这块的整体逻辑主要分三个部分,也可以说是分三步,这三个部分是有前后关系的:

第一步是将 模板字符串 转换成 element ASTs(解析器)
第二步是对 AST 进行静态节点标记,主要用来做虚拟DOM的渲染优化(优化器)
第三步是 使用 element ASTs 生成 render 函数代码字符串(代码生成器)

模板编译
上面提到了挂载的$mount函数,此函数的实现与运行环境有关,在此只看web中的实现。该方法在src/platforms/web/runtime/index.js中定义,挂载在vue的原型上。实现只有简单的两行,判断运行环境为浏览器,调用工具方法查找到el对应的DOM节点,再调用位于src/core/instance/lifecycle.js下的mountComponent方法来实现挂载,这里就涉及到了挂载之前的处理问题。对于拥有render(JSX)函数的情况,组件可以直接挂载,如果使用的是template,需要从中提取AST渲染方法(注意如果使用构建工具,最终会为我们编译成render(JSX)形式,所以无需担心性能问题),AST即抽象语法树,它是对真实DOM结构的映射,可执行,可编译,能够把每个节点部分都编译成vnode,组成一个有对应层次结构的vnode对象。有了渲染方法,下一步就是更新DOM,注意并不是直接更新,而是通过vnode,于是涉及到了一个非常重要的概念。

虚拟DOM
虚拟DOM技术是一个很流行的东西,现代前端开发框架vue和react都是基于虚拟DOM来实现的。虚拟DOM技术是为了解决一个很重要的问题:浏览器进行DOM操作会带来较大的开销。

操作DOM是不可避免的,常规的操作也不会有任何问题,但是经验不足的开发者往往很容易写出大量的多余或重复的DOM操作,成为前端性能优化中重要的问题。想提升效率,我们就要尽可能减少DOM操作,只修改需要修改的地方。要知道js本身运行速度是很快的,而js对象又可以很准确地描述出类似DOM的树形结构,基于这一前提,人们研究出一种方式,通过使用js描述出一个假的DOM结构,每次数据变化时候,在假的DOM上分析数据变化前后结构差别,找出这个最小差别并且在真实DOM上只更新这个最小的变化内容,这样就极大程度上降低了对DOM的操作带来的性能开销。

上面的假的DOM结构就是虚拟DOM,比对的算法成为diff算法,这是实现虚拟DOM技术的关键,在vue初始化时,首先用JS对象描述出DOM树的结构,用这个描述树去构建真实DOM,并实际展现到页面中,一旦有数据状态变更,需要重新构建一个新的JS的DOM树,对比两棵树差别,找出最小更新内容,并将最小差异内容更新到真实DOM上。

有了虚拟DOM,下面一个问题就是,什么时候会触发更新,接下来要介绍的,就是vue中最具特色的功能--数据响应系统及实现。

数据绑定
记得vue.js的作者尤雨溪老师在知乎上一个回答中提到过自己创作vue的过程,最初就是尝试实现一个类似angular1的东西,发现里面对于数据处理非常不优雅,于是创造性的尝试利用ES5中的Object.defineProperty来实现数据绑定,于是就有了最初的vue。vue中响应式的数据处理方式是一项很有价值的东西。

关于响应式的实现原理,vue官网上面其实有具体介绍,下面是一张官方图片:

vue会遍历此data中对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter,而每个组件实例都有watcher对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。这就是响应实现的基本原理,Object.defineProperty无法shim,所以vue不支持IE8及以下不支持ES5的浏览器。

一个简单的demo:


// 传统方式处理数据 // document.getElementById('inputName').addEventListener('keyup', function (e) { // document.getElementById('showName').innerText = e.target.value; // });
// 利用Object.defineProperty自动响应数据
var obj = {};
Object.defineProperty(obj, 'name', {
  get: function () {

  },
  set: function (val) {
    document.getElementById('showName').innerText = val;
  }
});
document.getElementById('inputName').addEventListener('keyup', function (e) {
  obj.name = e.target.value;
});

这个例子并不是什么复杂的实现,但是却体现了vue最核心的东西,我们可以发现,Object.defineProperty下的get和set是可以自动相应的,基于此vue实现了一套基于数据驱动视图的自动响应系统,使得开发模型得到了极大的简化。

Vue2响应式原理弊端

响应化过程需要递归遍历消耗较大

新加或删除属性无法监听数组响应化需要额外实现

Map、Set、Class等无法响应式
修改
语法有限制

Vue3响应式原理简化
vue3中使用ES6的Proxy特性来实现响应式
可以一次性友好的解决
对象和数组
设计原理
effect:将回调函数保存起来备用,立即执行一次回调函数触发它里面一些响应数据的getter
track(依赖收集):getter中调用track,把前面存储的回调函数和当前target,key之间建立映射关系
trigger(派发更新):setter中调用trigger,把target,key对应的响应函数都执行一遍

var 缺点:
声明覆盖
没有局部作用域
var 存在声明提升

解构赋值浅拷贝
深拷贝
function deepClone(obj){
//判断参数是不是一个对象
let objClone = obj instanceof Object?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}

浏览器缓存策略

memory cache(本地缓存)
memory cache 是浏览器为了加快读取缓存速度而进行的自身的优化行为,不受开发者控制,也不受 HTTP 协议头的约束。当资源被存入内存后,下次同样的请求将不再通过网络,而是直接访问内存,当关闭该页面时,此资源就被内存释放掉了,再次重新打开相同页面时不再出现from memory cache的情况

强缓存:2.1.1Expires

Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求的结果缓存的到期时间,即再次发送请求时,如果客户端的时间小于Expires的值时,直接使用缓存结果。

2.1.2Cache-Control

在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,主要取值为:

(1)public:所有内容都将被缓存(客户端和代理服务器都可缓存)

(2)private:所有内容只有客户端可以缓存,Cache-Control的默认取值

(3)no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定

(4)no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存

(5)max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效

当浏览器再次访问一个已经访问过的资源时,它会这样做:

1.根据相关字段判断是否命中强缓存,如果命中,就直接使用缓存了

2.如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存。

3.如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存

4.否则,返回最新的资源。

标签:缓存,obj,DOM,响应,vue,key,随笔
来源: https://www.cnblogs.com/teahouse/p/16504291.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有