日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

被低估的前端模块化

發(fā)布時(shí)間:2024/4/13 HTML 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 被低估的前端模块化 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

title: 被低估的前端模塊化 tags:

  • 前端模塊化 categories: 前端 date: 2017-03-25 18:18:55

對(duì)于前端的緩存主要包括靜態(tài)資源的緩存

為避免出現(xiàn)類似問題參考?變態(tài)的靜態(tài)資源緩存與更新

在經(jīng)歷了上傳前端資源文件等之后測(cè)試發(fā)現(xiàn)了一堆問題

發(fā)現(xiàn)每一個(gè)出現(xiàn)問題的均是彈出對(duì)話框畫面,由于均是出現(xiàn)函數(shù)未定義,初步判斷為js加載順序問題

因此對(duì)比了生產(chǎn)實(shí)現(xiàn)和開發(fā)實(shí)現(xiàn),發(fā)現(xiàn)現(xiàn)象如下

同樣的文件在生產(chǎn)環(huán)境下表現(xiàn)如此

分別出現(xiàn)在chrome的網(wǎng)絡(luò)面板XHR標(biāo)簽和JS標(biāo)簽下

對(duì)于兩個(gè)版本的差異出現(xiàn)在js加載的域不一樣(生產(chǎn)的域?yàn)楫?dāng)前服務(wù)器而開發(fā)環(huán)境為CDN)

那么為啥出現(xiàn)不同的域出現(xiàn)不同的加載行為呢?

我們知道對(duì)于瀏覽器存在同源策略www.ruanyifeng.com/blog/2016/0…

那么得出結(jié)論ajax請(qǐng)求是無法直接跨域的,因此大部分開發(fā)者使用了jsonp的方式

對(duì)于jsonp實(shí)質(zhì)上是通過script的方式來進(jìn)行跨域的,順便說到我們cdn的請(qǐng)求。

cdn的加載在正常畫面上是OK的,因?yàn)橛蔀g覽器來串行執(zhí)行對(duì)應(yīng)的內(nèi)容,此時(shí)沒有問題。

但是當(dāng)使用對(duì)話框插件之后實(shí)質(zhì)上使用remote是通過ajax請(qǐng)求到對(duì)應(yīng)的html,其次加載對(duì)應(yīng)的js

無說明均為jQuery1.9.1

if ( hasScripts ) {doc = scripts[ scripts.length - 1 ].ownerDocument;// Reenable scriptsjQuery.map( scripts, restoreScript );// Evaluate executable scripts on first document insertionfor ( i = 0; i < hasScripts; i++ ) {node = scripts[ i ];if ( rscriptType.test( node.type || "" ) &&!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {if ( node.src ) {// Hope ajax is available...jQuery.ajax({url: node.src,type: "GET",dataType: "script",async: false,global: false,"throws": true});} else {jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );}}} 復(fù)制代碼

此時(shí)話分兩頭,當(dāng)執(zhí)行ajax時(shí)首先判斷

// A cross-domain request is in order when we have a protocol:host:port mismatchif ( s.crossDomain == null ) {parts = rurl.exec( s.url.toLowerCase() );s.crossDomain = !!( parts &&( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ));}// Handle cache's special case and globaljQuery.ajaxPrefilter( "script", function( s ) {if ( s.cache === undefined ) {s.cache = false;}if ( s.crossDomain ) {s.type = "GET";s.global = false;}});if ( !s.hasContent ) {// If data is available, append data to urlif ( s.data ) {cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );// #9682: remove data so that it's not used in an eventual retrydelete s.data;}// Add anti-cache in url if neededif ( s.cache === false ) {s.url = rts.test( cacheURL ) ?// If there is already a '_' parameter, set its valuecacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :// Otherwise add one to the endcacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;}} 復(fù)制代碼

由上述代碼可以看出ajax默認(rèn)請(qǐng)求script都會(huì)放棄使用緩存,將會(huì)出現(xiàn)在網(wǎng)絡(luò)面板看見形如_=ajax_nonce這樣的的后綴使得無法使用緩存

關(guān)于jQuery加載transport為

// Bind script tag hack transportjQuery.ajaxTransport( "script", function(s) {// This transport only deals with cross domain requestsif ( s.crossDomain ) {var script,head = document.head || jQuery("head")[0] || document.documentElement;return {send: function( _, callback ) {script = document.createElement("script");script.async = true;if ( s.scriptCharset ) {script.charset = s.scriptCharset;}script.src = s.url;// Attach handlers for all browsersscript.onload = script.onreadystatechange = function( _, isAbort ) {if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {// Handle memory leak in IEscript.onload = script.onreadystatechange = null;// Remove the scriptif ( script.parentNode ) {script.parentNode.removeChild( script );}// Dereference the scriptscript = null;// Callback if not abortif ( !isAbort ) {callback( 200, "success" );}}};// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending// Use native DOM manipulation to avoid our domManip AJAX trickeryhead.insertBefore( script, head.firstChild );},abort: function() {if ( script ) {script.onload( undefined, true );}}};}});jQuery.ajaxTransport(function( s ) {// Cross domain only allowed if supported through XMLHttpRequestif ( !s.crossDomain || jQuery.support.cors ) {var callback;return {send: function( headers, complete ) {// Get a new xhrvar handle, i, 復(fù)制代碼

對(duì)于同域的js如上文會(huì)設(shè)置crossDomain為false,此時(shí)由于jQuery默認(rèn)的async為false,因此可以直接按照順序加載

對(duì)于cdn,此時(shí)由于s.crossDomain為true,

/ Base inspection function for prefilters and transportsfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {var inspected = {},seekingTransport = ( structure === transports );function inspect( dataType ) {var selected;inspected[ dataType ] = true;jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {options.dataTypes.unshift( dataTypeOrTransport );inspect( dataTypeOrTransport );return false;} else if ( seekingTransport ) {return !( selected = dataTypeOrTransport );}});return selected;}return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );}```?因此上端代碼將會(huì)返回對(duì)象scriptTransport,此對(duì)象將會(huì)直接執(zhí)行?```javascrpthead.insertBefore( script, head.firstChild ); 復(fù)制代碼

由于未采用前端模塊化依賴,導(dǎo)致加載的順序不定(文件大小,網(wǎng)絡(luò)狀況),因此出現(xiàn)一系列的函數(shù)未定義

因此需要在部署cdn前優(yōu)先完成前端模塊化建設(shè)。

其它外國的倒霉蛋連接一枚Script File Exectuing After Inline Script With CDN or External Domain On HTML injection

總結(jié)

以上是生活随笔為你收集整理的被低估的前端模块化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。