秒速赛车技巧-秒速赛车规律_官网-秒速赛车走势图
当前位置:主页 > 秒速赛车技巧 > 正文

秒速赛车免费计划域名劫持资源重加载方案

  在部分用户的网络环境中,页面CDN域名被劫持,导致前端资源无法正常加载,而页面主域名正常,导致页面可以访问,但是功能不正常。

  通常来说,主域名一般都是众所周知的域名,运营商一般不会劫持(本文特指劫持后导致无法加载,注入这些不在本文考虑范围内),主域名被劫持的可能性小。因为被劫持后,用户无法访问自然能够很明显感知到这是网络问题(鉴于挂掉情况可能性较小)。而CDN域名一般鲜为人知,运营商由于商业目的可能会劫持部分域名,于是就会导致页面html结构出来了,样式和交互都不正常,用户可能会认为这是产品的问题,很少会认为这是网络问题。

  CDN和主域名都同时承载资源,优先CDN加载,在CDN加载失败的情况下,切换到主域名再次加载资源。

  在每个script或者link标签中添加onerror属性,捕捉加载错误。

  缺点:代码入侵性强,不能够很好的复用。对于fis利用占位来添加css或者js的方式支持比较困难。

  在html最后加一段js,使用 HEAD 请求对所需要检测的资源进行检测,如果返回404或者503,则触发加载失败重新加载机制。

  资源一般来说都加了缓存,在正常网络下,HEAD请求会从本地缓存中返回结果,不会真正发送http请求到服务器,不会有额外消耗流量,增大延迟。

  但是资源加载失败的情况下,会消耗额外的流量、增大延迟。尤其是在网络返回延迟比较大的情况下,延迟会比较大。(但是这种情况,挽救的意义不大)

  当资源在加载时成功返回,而在检测时加载失败时会导致资源加载两次,仅仅针对无缓存资源而言。对于有缓存资源,加载完成之后,网络情况出现变化,HEAD请求已经感知不到了,因为HEAD请求就会走本地缓存,而不会发送到网络当中。

  当资源在加载时加载失败,而在检测时成功返回时,检测无效。以上情况出现概率比较小,需要出现在资源加载成功与失败之间的微小时差中产生,几乎可以忽略不计。

  优点:检测代码能够和业务代码很好的分离,能够检测到绝大部分资源加载失败的场景。

  但和labjs和requirejs不同的是,labjs和requirejs一般用于管理依赖以及按需加载,而针对检测错误重加载的加载器用于检测加载错误并切换源重新加载,有更好的加载错误重新加载机制,需要覆盖页面中所有的css、js等资源。

  优点:能够准确捕捉错误,且能够在加载失败并重试新域名的情况下保证正确的js执行顺序。

  css、js的加载都会在加载器执行后再进行加载,而且浏览器无法识别将要加载哪些资源,不能进行并行预加载,导致css、js加载比较慢。且对于js而言,需要按顺序执行,加载器只能按顺序串行加载,加载完一个再加载另一个,相对于浏览器的自动并行加载,js加载时间会变长。

  后端吐模板的页面,一般来说,页面响应之后,html大致结构就出来了。如果使用加载器加载,css的加载会晚于页面显示的时间,会导致暂时性的页面布局没有样式只有html结构的情况。

  普通页面来说,css一般放在head里,当浏览器解析页面的时候,解析到link的时候,浏览器会去加载资源,同时继续解析html,生成DOM树,等到css加载完成、Style Rules树也完成后,页面才会render,你就会看见一个有样式的页面。

  而对于加载器加载css的情况,在css加载完成之前,页面就显示了,就是一丢丢没有样式的html。等到css加载完成后,页面在repaint/reflow一下,闪屏一下,页面才显示正常。

  对于没有采用labjs、requirejs等加载器的项目而言,改动成本比较大。

  Resource Timing API(chrome和firefox等)不能检测到加载失败的资源,只能获取到加载成功的资源的加载时间数据。

  既然Resource Timing API 不能检测到加载失败的资源,那么不能被检测到的,自然就是加载失败的资源。通过这个原理可以准确捕捉到所有加载失败的场景。

  IE并不支持这个方案,因为在IE中,加载失败的资源会被包含在PerformanceResourceTiming中,而chrome、firefox等其他浏览器大部分并不包含。且并不能很好地区分加载失败和加载成功的资源(尤其是404)。

  当你看到此方法的标题时,或许你会觉得这个方法和1.1没什么区别。全局onerror不能捕捉到加载错误的原因1.1已经提及,那为什么window.addEventListener却能捕获加载错误呢?

  可以看到,加载错误的event中 canBubble: false, cancelable: false。自然用通常的冒泡机制不能捕捉加载错误,需要用捕获的方式来捕捉加载错误。同理代码也可以在HTMLLinkElement.cpp等资源加载的场景中看到。

  仅仅能够捕获加载错误还是不够的,还需要区分加载错误和其他错误,因为该方法也能够捕捉语法错误等一系列错误事件。

  对比以上情况,拟采用window.addEventListener捕获的方法来实现检测资源加载失败的情况。

  js加载失败,则加载原位置之后(包含该js)的所有js资源切换到主域名重加载

  可能某个js加载失败了,不需要加载剩余的全部js,只需要加载某个js,或者其他不在页面中的js。

  如果只是简单的重新加载剩余的js,这个倒不是什么问题。但是如果要支持自定义重加载关系,那这里就有点文章。资源依赖关系交叉了如何解决?有以下依赖关系:

  箭头表示依赖链关系,例如a->

  b,则说明b依赖于a,a需要在b之前执行。

  很显然a、b、e要d之前加载,且f要在d之前加载。这并不是简简单单的去重这么简单,在红线个位置,而在蓝线个位置。如果各自都按照顺序加载,那么就会造成b和c同时加载。

  那么解析依赖关系的过程中应该标记一个层级关系。对于重复的依赖,比较依赖层级,选择大者,并且更新子依赖的层级。

  注:[n]表示层级n,层级递增排序组成加载队列,每个层级包含一个资源数组,层级内资源无先后顺序。

  处理完成后,只需要对层级进行排个序,按照层级顺序加载,依赖自然就OK了。从以上例子来说,a和e可并行加载,两者先后顺序并无相互影响,其次是b、c等。

  加载一个script很简单,加载很多script也很简单,加载很多有顺序关系的script就有点文章了。

  串行加载,串行执行,自然想到了,浏览器的并行加载,串行执行。promise加载一个资源的过程中,并不能同时加载另一个资源(其实有办法,看下文),加载速度自然就是一个短板。

  以上,用promise是不值得的。考虑第一个问题,自己写回调不就好了嘛。但是写回调第二个问题也依然存在。

  模拟浏览器加载和执行js的方案,把加载和执行分开,用XmlRequest并行加载资源,然后用eval按依赖顺序执行代码。比较头疼的是,302、301就尴尬了,还得自己处理。加上跨域,就更头疼了(跨域需静态资源提供方配合解决)。

  哎,浏览器本来就有一套加载的方案,还得自己用xml http request写一套多麻烦,何不直接document.write呢,执行顺序也不用管了,浏览器都包了。

  但是,一定要确保在DomContentLoaded之前,否则你将看到白刷刷的一片。那问题就来了,如何确保在loaded之前检测完错误,并write依赖到body中。

  那么addEventListener则需要放到head里的最开始的地方(在任何资源加载之前即可),在body末尾插入依赖解析和加载。在html解析开始的时候开始监听加载错误事件,秒速赛车免费计划在html解析将结束时开始依赖解析和加载。

版权保护: 本文由 主页 原创,转载请保留链接: http://www.ecentiv.com//html/674.html