admin 管理员组文章数量: 1184232
一、问题描述
这个问题几个月前就曾困扰我,但是因为这个问题的出现看似“很偶然”,所以当时不了了之了。
Forced reflow while executing JavaScript took <N>ms
二、问题排查
以前也看到过类似警告,不过没有重视。警告内容很明显,就是执行JS代码的时候强制浏览器回流消耗了几十ms。
排查相关代码后发现在某个组件中,使用了一个
v-if频繁增删DOM节点
。
相关代码如下:
template部分
<template><divv-if="detail.id">
xxxx
</div></template>JS部分:
exportdefault{
props:{
detailId,},data(){return{
detail:{
id: xxx,}}},
watch:{
detailId:{
immediate:true,handler(){this.getDetail()}}},
methods:{
getDetail:{this.detail ={}
axios.get('xxx',this.detailId).then(res =>{// xxxthis.detail = res.data.data
})}}}
本来是想在detailId改变的时候,重新获取detail,但是在获取的过程中不想显示遗留数据,所以先将detail清空了。猜测正是这里导致了浏览器移除DOM节点又插入DOM节点,然后就有了上述警告和崩溃页面。
我这里修改detailId是通过用户点击不同的元素触发的,为了验证猜测,直接在父组件用一个setInterval函数模拟用户操作:
// ...mounted(){let time =0let detailList =[xxx, xxx]setInteval(()=>{
console.log(time,'setInteval')this.detailId =this.detailId === detailList[0]? detailList[1]: detailList[0]},200)}
刷新页面后发现,当打印的time到100次(也就是模拟了用户切换100次, v-if也生效100次)左右,页面就会崩溃。
果然就是这里v-if导致的问题,试了多次均是如此,看来问题也不是那么“偶然”。
问题定位到了, 那就很好解决了!
三、解决方案:
因为我这里只是想不显示遗留数据,所以其实只用把旧数据隐藏起来就行了,所以解决办法还是很多的。这里在请求过程中我给要隐藏的dom加了一个class,然后为这个class设置opacity(不透明度)为0:
<div:class="{ hide: !detail.id }">
xxx
<div>.hide
opacity 0
再用之前的代码测试,再也没有出现警告与页面崩溃,到此解决了以上问题。
四、反思
-
本文虽然解决了当前浏览器崩溃的问题,但是因为时间有限,并没有深究:
为什么这种情况下v-if会导致回流耗时异常(为什么一般情况下的v-if并不会有警告)?
为什么JS操作导致回流超时多次后会导致浏览器崩溃? - 一点思考:当一个问题重复出现的时候,就应该去尝试重现它,并且可以适当采用代码模拟人为操作,会大大提升效率。
版权声明:本文标题:当Adobe Flash Player遇到挑战,如何确保你的Vue应用程序在所有浏览器中都能正常运行? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1771582371a3546248.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论