最近在新项目中用了es6的window.customElements.define。组件使用过程中没发现任何问题,自测页面展示正常、操作正常,然后奇葩的现象来了,频繁切换多语言后,大概切换三四次,页面会出现卡顿的情况,主要表现为,接口请求发出去了,但实际上响应时间较长,页面一直pending.
可以理解为,请求发出去了,但接口返回时间变长,当然,第一想法就是后端问题,让后端检查,检查后发现,后端没有任何问题。因为之前的原生组件已经上线了,并且影响了大概十几个用户,然后检查前端内存调用,方法等,没有发现任何比较特殊的现象,无奈下,只能将原生组件下掉,然后我当时盲目的定义是:es6原生组件某些情况下存在BUG,无法使用。后来想了想,觉得这种低级问题肯定不会存在已经制定为标准的规范上。
因为我们的所有组件都是写成的NPM包,包的依赖又很多,实在不想本地导入。觉得没其他好办法了之后,我将组件的源文件直接引入了项目中,因为依赖的方法很多,我又把源文件中复制了一个新的,引入的方法直接在新文件中定义新的空方法,原则是只要组件展示正常,调用方法不报错就行了。
然后就正常启动了项目,也按我的思路正常运行,我在所有可能触发崩溃的地方都打上log,观察哪个log会比较频繁的调用,或者哪个log加载不正常。然后就发现了一个很奇怪的现象:监听事件会频繁触发,大概是切换语言的几何倍数增加。
原生组件使用的是es6的class,官网简单的DEMO如下,并且有个地方要注意,extends只能继承HTMLElement:
customElements.define(
"element-details",
class extends HTMLElement {
constructor() {
super();
const template = document.getElementById(
"element-details-template",
).content;
const shadowRoot = this.attachShadow({ mode: "open" }).appendChild(
template.cloneNode(true),
);
}
},
);
然后再说一下我们组件的大概实现的思路:
1、在constructor下初始化方法,初始化方法做服务器托管网了两个事1)是将所有的按钮点击事件绑定到按钮上2)监听cookies变化时重新刷新dom结构,3)将dom结构插入
2、实现update方法,update方法跟1实现的思路是一样的,也是监听、绑定、插入
最后问题实际上也是出现了在这里,这个BUG出现也是我代码不严谨和不熟悉导致的,因为第一版代码是别的同事写的,就没很注意里面的实现。我想有的人可能已经发现问题,在update中还实现了监听和绑定,但update时没有将之前的绑定remove调,导致每次update都会重新监听N次,特别是cookies这个监听机制,主要是更新dom,几何次数增加。然后每次改多语言时其实只是更新了cookies,因为多语言(服务器托管网language)也是在cookies中存储的,导致最后1*2*3*4,最后监听了24次,然后在uodate的绑定事件,也是绑定了24次,cookies监听也至少监听了24次,导致主线程被严重的阻塞。
最后解决问题的思路也很简单,1)update只更新,DOM,但不重新监听,但这样有个问题,DOM更新后,ID的监听事件会失败 2)update时,先removeAddeventLister在add,这样其实也算是常规做法。
最后,澄清一下,es6的原生组件没有任何问题,但因为是全部基于原生写法,很多地方之前框架帮你做的事情都需要自己做,所以特别像监听事件、监听行为这种一定要做好事件的清除,不然会出现很难排查的BUG。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
文章目录 图 1.图的两种存储结构 2.图的两种遍历方式 3.最小生成树的两种算法(无向连通图一定有最小生成服务器托管网树) 4.单源最短路径的两种算法 5.多源最短路径 图 1.图的两种存储结构 1. 图这种数据结构相信大家都不陌生,实际上图就是另一种多叉树…