14 js09 json 異步加載 js時間線

1照激、json:?輕量級的數(shù)據(jù)交換格式舌仍;[前后端數(shù)據(jù)傳輸都是json格式的恭取,對象里面的鍵必須要有雙引號泰偿,不可省略;傳輸過程中json是以字符串進行傳輸?shù)?直接對象形式傳輸不可以蜈垮,其識別的是二進制耗跛,所以傳輸過程中使用的是二進制的文本格式即字符串]

(1).xml:?其是一種語言(xml ->xhtml ->html),最初也作為數(shù)據(jù)交換格式使用,其以標簽作為數(shù)據(jù)名攒发,標簽內(nèi)容作為數(shù)據(jù)值進行傳遞數(shù)據(jù)课兄,其可以自定義標簽,傳輸效率低下晨继,如今大多使用json;[前后端通信傳遞數(shù)據(jù)是以字符串的形式進行烟阐,字符串內(nèi)填充數(shù)據(jù),而且數(shù)據(jù)就是對象的形式紊扬,前端給后端傳遞數(shù)據(jù)蜒茄,傳遞的是字符串類型的數(shù)據(jù),后臺收到進行解析成對象再進行一系列的操作(類如:表單數(shù)據(jù)收集)餐屎,同理后臺傳遞給前端的數(shù)據(jù)也是字符串格式檀葛,需要轉化為對象] [傳遞數(shù)據(jù)需要高效、便捷]

(2).json 是以對象為樣板腹缩,本質上就是對象屿聋,在js中“一切都是對象”,但其和對象的用途上有區(qū)別藏鹊,對象是本地使用(瀏覽器端润讥、服務器端),json是用來傳輸?shù)呐坦眩问缴弦灿袇^(qū)別楚殿,json中的屬性必須加雙引號,不可省略竿痰;對象中雙引號可以省略【區(qū)分json和對象的要點】

json數(shù)據(jù):var obj = { "name": "abc","age": 18}脆粥;json字符串:"{ "name": "abc","age": 18}"

(3).以下這兩個方法很重要:進行解析數(shù)據(jù)的第一步【JSON、Math都是靜態(tài)類影涉,使用過程中不能new +構造函數(shù)創(chuàng)建對象使用变隔;其上有很多屬性和方法,直接使用就OK】

JSON.stringify();? ?json? --->>> string;? ?JSON.parse();? ?string? --->>> json;

[var obj = {name:"nba",age:18} --->> JSON.stringify(obj); -->> "{ "name": "nba","age": 18}", json本質也是對象蟹倾,目前JSON操作時也識別為json對象]

2匣缘、異步加載:前面談到html和css是異步加載,js是同步加載,加載到js部分阻塞頁面的加載直到js加載完成孵户,所謂異步加載:工具類/數(shù)據(jù)初始化的js腳本庫異步加載,操作dom元素的js腳本進行同步加載即可岔留;(操作dom元素的js腳本若是異步加載夏哭,每次改動必然會影響domTree,進而影響randerTree,耗費性能); 【js是單線程,若是雙線程献联,一個線程增加dom元素竖配,一個線程刪除dom元素,執(zhí)行哪個里逆?

瀏覽器內(nèi)核中有渲染引擎和js引擎进胯,渲染頁面的過程是怎樣的?html原押、css胁镐、js文件執(zhí)行順序是怎么樣的呢?

頭部引入的css文件和html是異步線程執(zhí)行诸衔,引入的js文件和html是同步執(zhí)行:js文件加載完成后盯漂,html才能接著進行解析,也就是js會阻塞后面的dom解析(若遇到網(wǎng)速不好等情況笨农,整個網(wǎng)站將等待js庫加載而不進行后續(xù)渲染)就缆;日常開發(fā)中,一些工具類的js庫谒亦、引入的第三方庫竭宰,我們希望其可以同時進行加載,沒必要阻塞dom解析份招,影響頁面效率切揭,最好采用異步加載的方式;

(1).接下來先分析一些頁面渲染過程:(結合原生js小結圖示過程)

[1].渲染引擎是一行行(按像素點)進行渲染頁面的锁摔,代碼中就是一行行執(zhí)行代碼(當然并非視覺編程的順序伴箩,有預編譯過程),首先它會進行domTree的繪制鄙漏,遵循“深度優(yōu)先原則”嗤谚,渲染dom的過程中,若是存在一些Img標簽怔蚌、a標簽等含有src巩步、href屬性,和css樣式有所關聯(lián)的桦踊,內(nèi)部依舊會繼續(xù)解析dom元素到domTree上椅野,但css相關樣式也開始繪制;

[2].domTree樹繪制完成后,cssTree的繪制是同時進行的竟闪,[1]中只是繪制相關元素的位置离福,現(xiàn)在開始繪制和domTree有關的所有樣式;

[3].cssTree樹繪制完成后炼蛤,其和domTree會進行結合形成渲染樹妖爷,domTree + cssTree = renderTree;?有了renderTree后,渲染引擎才開始按著它開始渲染頁面理朋;

[4].期間<head></head>標簽部分引入的js文件絮识,其會阻塞頁面的渲染過程,這里還需要介紹兩個重要概念:reflow 嗽上、 repaint次舌;

????????[4.1] js可以操作html,進而也可以間接操作css,每一次操作都會對domTree產(chǎn)生影響兽愤,domTree一變化彼念,就需要重新繪制domTree、cssTree浅萧,這種改變稱為reflow重排(重構国拇、重做),很影響性能惯殊,這也是我們不要隨便修改html結構的原因[常見可引起重構的行為:dom節(jié)點的刪除增加酱吝、dom元素的寬高變化、位置變化土思,display:none -->>> display: block;?改變某個元素會對后續(xù)元素產(chǎn)生一系列影響务热; offsetWidth? offsetHeight 這兩個雖是查看元素,但依舊會對dom元素產(chǎn)生影響]

????????[4.2]repaint?重繪己儒,其區(qū)別于reflow崎岂,只需要進行部分domTree重繪即可,大多是一些樣式的微弱改變闪湾,不影響html結構冲甘,例如字體顏色、背景圖片途样、背景顏色等等江醇,對后續(xù)元素也無影響,對性能也有影響何暇,但很刑找埂;

(2).JS異步加載的三種方法:操作dom元素的還是采取同步加載裆站,對于工具庫/初始化數(shù)據(jù)的庫条辟,采取異步加載或者按需加載來提高頁面效率黔夭;

[1].defer異步加載,只有IE9以下可用羽嫡,在script標簽加入單屬性即可本姥;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<script type="text/javascript" scr="tools.js" defer="defer"></script>;?其不僅可以引入外部文件,也可以將代碼寫入內(nèi)部杭棵,<script type="text/javascript" defer="defer">console.log('a');<script>; [不要既引入外部婚惫,又在內(nèi)部寫代碼]? 缺點:雖然可以同時進行加載,但必須等到dom文檔全部解析完才會被執(zhí)行颜屠;【注意:IE6和IE7的異步加載最多只能有2個辰妙,當多余兩個的時候必須等前兩個加載完才會加載第三個】

[2].async ,w3c標準,(IE9以下不兼容)鹰祸;<scrip type="text/javascript" src="tools.js" aysnc="aysnc" ></script>;?其只能加載外部腳本甫窟,不能把js代碼寫在內(nèi)部,同時其是加載后就執(zhí)行蛙婴;

如何處理兼容性:封裝在任何瀏覽器都能異步加載腳本庫粗井;

方法一:<script type="text/javascript" aysnc="aysnc" src="tools.js" defer="defer"><script>? ,這種方法不可以街图,容易引起系統(tǒng)崩盤浇衬;

方法二:<script type="text/javascript" aysnc="aysnc" src="tools.js"><script>

<script type="text/javascript" defer="defer" src="tools.js"></script>?這種方式也不合理;

--->>>?開發(fā)中采取的方法:進行if判斷,if(IE){使用defer}else{使用async}

[3].按需加載:異步加載并且按需加載餐济,什么時候用到該腳本耘擂,什么時候進行加載,不用就不用管它絮姆;應用場景也很多醉冤,例如:有的按鈕用戶很少會點擊,但卻有產(chǎn)品價值篙悯,而且點擊有可能會出現(xiàn)很多信息蚁阳,可以對其進行“按需加載”,用戶點擊的時候動態(tài)加載完畢即可鸽照,不一定執(zhí)行到該腳本庫就阻塞頁面或異步加載螺捐;

按需加載才是最合適的異步加載方案:創(chuàng)建script,插入到html中矮燎,加載完畢后callBack;(內(nèi)容較多定血,附詳細過程)

[3.1].?重點:創(chuàng)建script標簽后,添加script.src="tools.js"時诞外,只是進行異步加載糠悼,并沒有執(zhí)行;

-------->>>>>>>代碼跑起來的時候會報錯浅乔,下載資源需要過程:發(fā)出請求倔喂,等待響應铝条,響應后開始反饋資源,期間過程是以微秒(us)計算席噩,由于是異步加載槐秧,下面的代碼在加載過程中便開始執(zhí)行,執(zhí)行過程中若是找不到該方法便會報錯妈候;錯誤原因:加載時間大于代碼執(zhí)行時間综看;

[3.2]使用定時器驗證上述說法:

-------->>>>>代碼可以正常運行,加載的時間受很多因素影響馒索,例如網(wǎng)速不好等莹妒,接下來進行一些操作解決bug,等其加載完成后再執(zhí)行代碼绰上;

[3.3].load事件旨怠,很多對象都有l(wèi)oad事件,并非window獨有(涉及到下載的就有l(wèi)oad事件)蜈块;表示:下載完成后觸發(fā)事件鉴腻,兼容性很好,safari/chrome/firefox/opera都兼容百揭,IE瀏覽器也有l(wèi)oad事件爽哎,但IE中的script標簽上沒有l(wèi)oad事件;

[3.4].IE使用:?readystatechange事件器一,IE在script上設置了狀態(tài)碼readState,隨著加載過程其的屬性值會變化课锌;開始:script.readyState = "loading",--->>>加載完成后:script.readyState="complated" /? script.readyState="loaded";[IE和高版本的chrome、firefox的script有此事件祈秕,但是其他瀏覽器的dom元素上也有此事件和屬性渺贤;document.readyState,表示狀態(tài)]

[3.5]封裝兼容性函數(shù):url:引入的腳步庫踢步,callback();?回調函數(shù)癣亚,當滿足一定條件才執(zhí)行的函數(shù);將script.src=url;換位置的原因是解決bug获印,防止IE無法判斷述雾,解釋:IE判斷的標準就是script的狀態(tài)碼是否發(fā)生變化,若是代碼執(zhí)行到script.src=url;?加載速度特別特別快兼丰,在執(zhí)行下面的判斷語句前玻孟,已經(jīng)加載完成,這時候script.readyState="complete";?這時候就那些if條件判斷時鳍征,里面的事件就無法觸發(fā)黍翎,這時里面的函數(shù)也無法執(zhí)行,所以可以先讓其進行if條件判斷艳丛,然后再加載匣掸;

[3.6]封裝兼容性函數(shù)[最終版]:如果只是異步加載腳本庫趟紊,傳入url即可,封裝的是較為靈活的碰酝,按需加載腳本庫霎匈、函數(shù),callback如果多個函數(shù)送爸,可以以數(shù)組形式傳入铛嘱,靈活應用;

補充:

(1).實際操作中又報錯袭厂;解釋:結合預編譯的過程墨吓,函數(shù)執(zhí)行前并不能解析函數(shù)內(nèi)部到底有什么內(nèi)容,當函數(shù)執(zhí)行時纹磺,執(zhí)行到第二個參數(shù)的時候帖烘,里面的腳本庫還未加載成功,會報錯爽航;

解決方案1:使用函數(shù)引用作為參數(shù)蚓让,當傳入時并不會解析里面的內(nèi)容乾忱,用到的時候才會解析讥珍;

解決方案2: loadScript("tools.js","test()");?第二個參數(shù)可以為字符串形式,eval();和setInterval();可以將字符串轉化為代碼執(zhí)行窄瘟;不常用衷佃,es3.0也不支持eval();

對象屬性名的方式也可以;(實操中也可使用)

總結:

(1).渲染引擎解析html/css,js引擎解析javascript代碼蹄葱,domTree + cssTree = renderTree;渲染引擎開始渲染頁面氏义;

(2).js會阻塞dom的解析,解析過程就是識別dom元素的過程(domTree包含元素節(jié)點/文本節(jié)點等系列節(jié)點图云,聚焦點為元素節(jié)點)惯悠,而dom樹的加載完成包含里面的圖片、a標簽的鏈接等都下載完畢,觸發(fā)window.onload竣况,顯然dom解析必然是在dom加載之前完成克婶;

(3).當屬性等于屬性值的時候,可直接寫一個屬性名即可丹泉,也稱為單屬性情萤,系統(tǒng)可以識別,但是最好寫成屬性=“屬性值”的寫法摹恨;

<script type="text/javascript" src="tools.js" defer="defer"></script>

<script type="text/javascript" src="tools.js" defer></script>


3筋岛、js時間線:

(1).創(chuàng)建document對象,開始解析web頁面晒哄。解析HTML元素和他們的文本內(nèi)容后添加Element對象和Text節(jié)點到文檔中睁宰。這個階段document.readyState = ‘loading’;

(2).遇到link外部css肪获,創(chuàng)建線程加載,并繼續(xù)解析文檔;

(3).遇到script外部js柒傻,并且沒有設置async贪磺、defer,瀏覽器加載诅愚,并阻塞寒锚,等待js加載完成并執(zhí)行該腳本,然后繼續(xù)解析文檔;

(4).遇到script外部js违孝,并且設置有async刹前、defer,瀏覽器創(chuàng)建線程加載雌桑,并繼續(xù)解析文檔喇喉。 對于async屬性的腳本,腳本加載完成后立即執(zhí)行校坑;(異步禁止使用document.write())

(5).遇到img等拣技,先正常解析dom結構,然后瀏覽器異步加載src耍目,并繼續(xù)解析文檔;

(6).當文檔解析完成膏斤,document.readyState = ‘interactive’;

(7).文檔解析完成后,所有設置有defer的腳本會按照順序執(zhí)行邪驮。(注意與async的不同,但同樣禁止使用document.write());【defer腳本監(jiān)視的便是document.readyState的狀態(tài)】;

(8).document對象觸發(fā)DOMContentLoaded事件莫辨,這也標志著程序執(zhí)行從同步腳本執(zhí)行階段,轉化為事件驅動階段;

(9).當所有async的腳本加載完成并執(zhí)行后毅访、img等加載完成后沮榜,document.readyState =‘complete’,window對象觸發(fā)load事件;

(10).從此喻粹,以異步響應方式處理用戶輸入蟆融、網(wǎng)絡事件等。

補充:

[1].關于document.write();其會把括號里的內(nèi)容當作是html文檔輸出到頁面里去守呜,但有兩種特殊情況型酥,1.當頁面全部加載完成,其會將頁面內(nèi)容全部清空弛饭;2.異步加載過程中使用也會將頁面內(nèi)容清空冕末;【開發(fā)中也沒太大用處,盡量不要使用】

[2].文檔解析完成:domTree解析完成侣颂,不同于頁面加載完成档桃,頁面加載完成包括randerTree、js都加載完成憔晒;(文檔解析完成發(fā)生在頁面加載完成之前)

[3].事件驅動階段藻肄,頁面加載完成后基本都是都是這個階段蔑舞,沒有事件的為純靜態(tài)頁面;

[4].window.onload=function(){};?整個頁面加載完成后執(zhí)行嘹屯;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? $(document).ready(function(){ });? jquery中這種方式表示dom解析完就執(zhí)行攻询;document.addEventListener('DOMContentLoaded',function(){},false);? dom解析完成后就執(zhí)行;[此事件沒有句柄的方式州弟,只能使用addEventListener();]

? ? ? ?如圖也不會報錯钧栖,阻斷dom解析進行加載,完成后繼續(xù)進行dom解析婆翔,此事件會在dom解析完成后開始執(zhí)行拯杠,所以這種寫法沒錯,但是不建議啃奴;【dom解析目的是生成dom樹潭陪,script是標簽當然也會存在于dom樹上,但里面的js代碼是js引擎進行解析的最蕾,渲染引擎和js引擎功能不同依溯,最后渲染引擎開始渲染頁面,就是視圖所看到的】

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘟则,一起剝皮案震驚了整個濱河市黎炉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌壹粟,老刑警劉巖拜隧,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宿百,死亡現(xiàn)場離奇詭異趁仙,居然都是意外死亡,警方通過查閱死者的電腦和手機垦页,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門雀费,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人痊焊,你說我怎么就攤上這事盏袄。” “怎么了薄啥?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵辕羽,是天一觀的道長。 經(jīng)常有香客問我垄惧,道長刁愿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任到逊,我火速辦了婚禮铣口,結果婚禮上滤钱,老公的妹妹穿的比我還像新娘。我一直安慰自己脑题,他們只是感情好件缸,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叔遂,像睡著了一般他炊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上已艰,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天佑稠,我揣著相機與錄音,去河邊找鬼旗芬。 笑死舌胶,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的疮丛。 我是一名探鬼主播幔嫂,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼誊薄!你這毒婦竟也來了履恩?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤呢蔫,失蹤者是張志新(化名)和其女友劉穎切心,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體片吊,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡绽昏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俏脊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片全谤。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖爷贫,靈堂內(nèi)的尸體忽然破棺而出认然,到底是詐尸還是另有隱情,我是刑警寧澤漫萄,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布卷员,位于F島的核電站,受9級特大地震影響腾务,放射性物質發(fā)生泄漏毕骡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挺峡。 院中可真熱鬧葵孤,春花似錦、人聲如沸橱赠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狭姨。三九已至宰啦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饼拍,已是汗流浹背赡模。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留师抄,地道東北人漓柑。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像叨吮,于是被迫代替她去往敵國和親辆布。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容