接上篇。ie下错位几率相对而言有些大,于是基于interactive特性进行改善。这其实反而是走回老路了~
在意想之中的是,ie下十万分之一几率的错位果然降了,而且降到了没有一个错误……webkit内核依旧保持极低概率,奇怪的是firefox在上两次中从未出现错误的先提下,这次爆出了十位数的错位。
8420947
接上篇。ie下错位几率相对而言有些大,于是基于interactive特性进行改善。这其实反而是走回老路了~
在意想之中的是,ie下十万分之一几率的错位果然降了,而且降到了没有一个错误……webkit内核依旧保持极低概率,奇怪的是firefox在上两次中从未出现错误的先提下,这次爆出了十位数的错位。
8420947
接上篇。尽管已经降到了十万分之一级别的几率,但并发下浏览器的不靠谱行为依旧存在。IE6-8下依旧为主要因素,这与使用者人数多也有关,基数大所以数量高。另外2次幂延迟算法对于单线程情况(aA)是能够完全纠正的,这点值得欣慰。
并发时,abAB、aABb、aAbB、ABba、abBA、AbBa、aBbA、aBAb几种情况按几率依次递减,想要完美解决必须全部纠正。在2次幂延迟算法纠正后,前面3个已经正确,但后面的还是错误的,它们可以统一概括为:ABba。结果原本应该赋给A的a跑到B的身上,互相错位了,所以要进行错位交换。
理论上前期不可能再进行处理了,我耗了很久发现前期处理是个悖论,剩下的可能只有运行时决定。
在运行时:
use(['a', 'b'], function(a, b) {
a.methodA();
b.methodB();
});
在错位情况下,a不具有methodA方法b才具有,b也反之。此时会抛异常。简单的做法是运行时try,捕捉到异常后交换错位的arguments再运行一次。看起来似乎不错,实际陷阱重重。
首先methodA和methodB可能方法名相同,甚至逻辑极为相似。这样就不会异常但运行结果是错的。这个概率很低。
然后这是在2个参数的情况下,2个以上排列比例太多,交换次数很恐怖,不切实际。
还有这只有1级递归,也就是a和b互相颠倒而已。如果a有依赖或b有依赖,所造成的错位可能有很多,那它们之间互相递归交换非常恐怖,根本不可能实现。
即使可以通过的define进行包裹一层,抽出factory返回的方法名来提升判断callback的参数顺序准确度,但依然不能解决上述所有问题。所以最后错位交换算法被pass。
IE下,通过getInteractiveScript的方法,可能提升并发准确度到百万分之一的级别,有待验证。
接上篇,之前用的加载script机制有问题,同时赋予了onload = onreadystatechange,这在同时支持的浏览器(ie9)下有影响,新的方法分开对待。
接上篇。另外对于基础性原理不清楚的请查看射雕的介绍:http://lifesinger.wordpress.com/2011/11/11/get-url-in-module-loader/
通过1周的海量数据多次测试与研究,我和射雕发现了所有浏览器下都有的共同bug:onload事件先于script标签的加载发生。这个结论直接表明,目前所有对于script的onload的侦听都不是完美的!一旦有了这个低几率问题,那些莫名的错误会让人十分困惑。
介于此,我尝试使用2^ delay的算法来延迟onload的运行。它的理论基础来源于抑制网络风暴的算法:即onload先检查script的exec,没有时延迟2 ^ 0单位时间后再检查、再没有延迟2 ^ 1、2 ^ 2……以此类推。
在昨天的海量观测数据下面,结果是惊喜的。没有1次发生了error,全部正确。但是依然存在低几率次序打乱的情况,这是接下来要着手解决的问题(或者干脆忽略掉)。
最后祝福下Firefox和IE10,你们的顺序是100%正确的。
问题的起源是这样的:
假设加载有2个脚本A和B,而a和b则是附加在各自脚本上的onload侦听。众所周知的,IE下A加载完成exec后a并不是保证立刻触发的,非IE下正常。但是,倘若前提是A的加载完成和B的加载完成顺序确定,即A->B,那么a->b的顺序能不能得到保证?即:有可能是AaBb、ABab,但绝不可能有ABba。
自己测是发现不了问题,但显然范围太小不足以说明情况,所以我借助土豆的某个次要页面流量,做了个大范围精度测试。
目标:测出IE6、7、8、9下面的顺序情况。
理由:懂的入。
用例:用户有25%的几率加载a.js、25%的几率加载b.js、剩余50%全部加载,以此模拟出各种可能被缓存的情况——即可能先缓存a,然后再加载a和b。
数据结构:第一位的0和1标明页面是否发生error,是的话1,否的话0;后面大写字母是script标签被加载exec时记录,小写字母是其onload触发时记录;再后面数字是次数。
结果:近千万份数据,可能因对浏览器ua的判断稍稍有些误差。
error
ie6
“1Aab” “3410″
“1a” “2979″
“1b” “2901″
“1Bba” “1575″
“1Bab” “136″
“1Aba” “61″
“1″ “56″
“1Aa” “12″
“1A” “10″
“1ab” “9″
“1Bb” “7″
“1ABab” “4″
“1AB” “1″
ie7
“1b” “771″
“1a” “743″
“1Aab” “738″
“1Bba” “376″
“1″ “108″
“1Bab” “23″
“1Aba” “15″
“1Bb” “10″
“1Aa” “3″
“1ABab” “1″
ie8
“1Aab” “2460″
“1a” “2050″
“1b” “1887″
“1Bba” “1290″
“1″ “322″
“1Bab” “95″
“1Aba” “39″
“1Aa” “20″
“1Bb” “11″
“1ABab” “1″
ie9
“1Aab” “372″
“1a” “321″
“1b” “285″
“1Bba” “218″
“1Bab” “10″
“1Aba” “6″
“1″ “1″
“1Bb” “1″
success
ie6
“0ABab” “1591785″
“0Bb” “1093518″
“0Aa” “1093213″
“0AaBb” “373421″
“0BbAa” “137775″
“0BAba” “79495″
“0ABba” “4″
“0ab” “1″
“0aBb” “1″
“0BaAb” “1″
ie7
“0ABab” “371165″
“0Aa” “257674″
“0Bb” “257001″
“0AaBb” “88582″
“0BbAa” “33734″
“0BAba” “20710″
“0ABba” “108″
“0BAab” “23″
“0BaAb” “2″
ie8
“0ABab” “1108442″
“0Aa” “794383″
“0Bb” “792879″
“0AaBb” “313784″
“0BbAa” “108791″
“0BAba” “54147″
“0ABba” “4″
“0BaAb” “1″
ie9
“0ABab” “188309″
“0Aa” “132499″
“0Bb” “131587″
“0AaBb” “44003″
“0BbAa” “19110″
“0BAba” “12620″
“0ABba” “211″
“0BAab” “40″