解决vue项目中,iframe依赖onload事件传递消息不可控接收问题

背景介绍

因项目需求,在原网站内需要嵌入另一个关联网站的内容,很自然的想到用iframe去解决。但是进入内联网站依赖于主网站的accessToken进行身份验证,因此就涉及到传递token的方式,以及传递的时机这两方面,而内联网站的首次渲染速度过慢问题,在排除webpack打包优化这方面影响后,很有可能就是接受token不及时导致延迟渲染。

另外,这两个都是vue项目。

先上案例代码

// 父页面




// 子页面


复制代码

(上述代码让子项目的渲染时间在网络状态良好情况下3-20秒内不定期发生。。。)

问题分析

两个项目直接传递和接收消息,是使用postMessage达成的。我们知道,postMessage是一个异步方法,他的执行排在同步方法后面。postMessage只负责传递消息,并不负责监听消息是否被接收,而是在消息一旦传递就立刻给传递者返回成功状态。 

问题一:token的传递依赖于load函数的触发,若触发时机不正确,会导致token获取不到。

划重点

原因:使用单页面开发的Vue程序,在Vue代码开始执行之前就已经触发了onload()。此时iframe中包含的是一个空的document。虽然在子项目完成挂载之后,依旧会再次触发onload事件,但传递token的最佳时机已经错过。可以想到,传递token的最佳时机是在页面一挂载的时候。

问题二:子页面是一个独立的vue项目,在子组件挂载之前就有同步函数、项目自身的postMessage执行。父页面传递的消息需要排队等待被接收。

原因:由于子项目中同步函数的执行,会阻塞异步postMessage的消息接收,此时就算传递了消息也没办法及时获取。

解决方案

由此可见,在vue项目中用onload事件并不靠谱(--!!,原来坑在这)

那应该何时向子项目传递token才能确保页面可以正常加载呢?

由子页面通知父页面可以传递消息了,替代onload事件

改良案例如下

// 父页面




// 子页面


复制代码

当子项目的根节点挂载后,postMessage通知父项目传递token

其一,避免了onload事件触发不准确的问题;

第二,避免消息队列的等待导致的接收不及时问题。

最终结果,子项目的渲染时间在网络状态良好情况下,被控制在0-2秒内。

以上就是本周遇到并解决的vue中iframe内嵌项目,由于postMessage接收不到导致的首页加载过慢的问题。除了postMessage本身的无法监听是否接收到消息问题之外,还有onload事件在Vue项目中的问题。


你可能感兴趣的:(解决vue项目中,iframe依赖onload事件传递消息不可控接收问题)