摘要:的堵塞特性上面引用兩段話的意思大致是,當瀏覽器解析文檔時,一旦遇到標簽沒有和屬性就會立即下載并執行,與此同時瀏覽器對文檔的解析將會停止,直到代碼執行完成。實現代碼執行代碼缺點是不能跨域請求參考裝載和執行元素所著的的第一章
Script 的堵塞(block)特性
Scripts without async or defer attributes, as well as inline scripts, are fetched and executed immediately, before the browser continues to parse the page. - MDN
the blocking nature of JavaScript, which is to say that nothing else can happen while JavaScript code is being executed. In fact, most browsers use a single process for both user interface (UI) updates and JavaScript execution, so only one can happen at any given moment in time. The longer JavaScript takes to execute, the longer it takes before the browser is free to respond to user input. - Nicholas C. Zakas「High Performance JavaScript 」
上面引用兩段話的意思大致是,當瀏覽器解析DOM文檔時,一旦遇到 script 標簽(沒有defer 和 async 屬性)就會立即下載并執行,與此同時瀏覽器對文檔的解析將會停止,直到 script 代碼執行完成。出現這種堵塞行為一方面是因為瀏覽器的UI渲染,交互行為等都是單線程操作,另一方是因為 script 里面的代碼可能會影響到后面文檔的解析,比如下面的代碼:
html
這個堵塞特性會嚴重的影響用戶體驗,下面是幾種優化方案:
盡量把腳本往文檔的后面放,以減少對文檔的堵塞,最好放在
前面。
盡量把腳本按照它們的依賴關系放在一個文件中
不過更好的方法是下面的非堵塞加載腳本(Nonblocking Scripts)的方法:
1. Deferred Script (延遲腳本)Script 有一個 defer 屬性,擁有這個屬性的script表明這個script不會修改DOM,因此這段腳本會在文檔樹全部解析完成后觸發( to be executed after the document has been parsed). 但這個屬性并不被所有的瀏覽器支持。
2. Dynamic Script Elements (動態腳本)原理就是使用腳本創建 script 元素,設置 src 需為要動態添加腳本的 URL,再把這個 script 添加到DOM中。有時我們需要動態腳本加載完成后再執行某些操作,這就需要我們在腳本加載完成后添加一個回調函數,這個可以通過 script 的 onload 事件實現。下面的實現代碼:
jsfunction loadJS(url, callback){ var script = document.createElement("script"); script.type = "text/javascript"; if(script.readyState){ // 兼容IE的舊版本 script.onreadystatechange = function(){ if(script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; callback(); } } } else{ script.onload = function(){ callback(); } } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }
有時我們需要我們動態加載的腳本按照我們加載的順序執行,但上面的實現并不能保證這一點,加載的腳本在下載完成后就會立即執行,而不會按照我們定義的順序。要解決這個問題也不難,可以參照下面的代碼:
jsloadJS("a.js", function(){ loadJS("b.js", function(){ loadJS("c.js", function(){ app.init(); }) }) })
當有大量的腳本需要動態添加時,這樣寫也會遇到問題;另外的解決方案是利用一些現成的庫,比如 LABjs
3. XMLHttpRequest Script Injection (XHR動態插入)原理是利用XMLHttpReques(XHR)對象,動態獲取一段JS代碼,然后插入文檔。
相對其他方法來說的一個優點是可以“懶執行”,也就是JS代碼已經先下載好了并沒有執行,可以在需要的來執行(?)(之前的動態腳本在下載后會立即執行)。實現代碼:
jsfunction xhrLoadJS (url, callback){ var xhr = new XMLHttpRequest(); xhr.open("get", url, true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){ var script = document.createElement("script"); script.type = "text/script"; script.text = xhr.responseText; eval(xhr.responseText); // 執行代碼 document.body.appendChild(script); callback(); } } } xhr.send(null); }
缺點是不能跨域請求
參考Javascript 裝載和執行
MDN Script元素
Nicholas C. Zakas 所著的「High Performance JavaScript 」的第一章 "Loading and Execution"
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85720.html
摘要:是一款可愛的小插件,將和瀏覽器的封裝到一起,解決了單純使用進行無刷新加載時對搜索引擎的不友好,并且節省了開支提高了瀏覽速度,明顯地優化了用戶體驗。是提供的,是對瀏覽器歷史對象的增強。 showImg(https://segmentfault.com/img/remote/1460000007640529?w=1008&h=569); pjax 是一款可愛的 jQuery 小插件,將 a...
摘要:是一款可愛的小插件,將和瀏覽器的封裝到一起,解決了單純使用進行無刷新加載時對搜索引擎的不友好,并且節省了開支提高了瀏覽速度,明顯地優化了用戶體驗。是提供的,是對瀏覽器歷史對象的增強。 showImg(https://segmentfault.com/img/remote/1460000007640529?w=1008&h=569); pjax 是一款可愛的 jQuery 小插件,將 a...
摘要:我把這個領域的東西寫成了一個系列,以后還會繼續完善下去安全一同源策略與跨域安全二攻擊安全三攻擊 上文說完了CSRF攻擊,本文繼續研究它的兄弟XSS攻擊。 什么是XSS攻擊 XSS攻擊全名(Cross-Site-Script)跨域腳本攻擊,為了跟CSS(Cascading-Style-Sheet)區分開來,所以縮寫是XSS。 XSS攻擊的原理 上一節說道的CSRF攻擊是利用的是偽請求,這...
摘要:我把這個領域的東西寫成了一個系列,以后還會繼續完善下去安全一同源策略與跨域安全二攻擊安全三攻擊 上文說完了CSRF攻擊,本文繼續研究它的兄弟XSS攻擊。 什么是XSS攻擊 XSS攻擊全名(Cross-Site-Script)跨域腳本攻擊,為了跟CSS(Cascading-Style-Sheet)區分開來,所以縮寫是XSS。 XSS攻擊的原理 上一節說道的CSRF攻擊是利用的是偽請求,這...
摘要:關于動靜分離的描述,這里推薦一篇不錯的博文網站靜態化處理動靜分離策略。這里的解決辦法則是采用的屬性,將其應用于數據請求相關的上,就可以達到腳本與數據并發加載的效果。 作者:莫冠釗 轉載請注明出處,保留原文鏈接和作者信息 前言 當今許多大型網頁應用尤其是SPA均采用了動靜分離的策略。關于動靜分離的描述,這里推薦一篇不錯的博文 網站靜態化處理—動靜分離策略。 本人是做前端的,之前有幸與一...
閱讀 351·2024-11-07 18:25
閱讀 130598·2024-02-01 10:43
閱讀 914·2024-01-31 14:58
閱讀 879·2024-01-31 14:54
閱讀 82884·2024-01-29 17:11
閱讀 3176·2024-01-25 14:55
閱讀 2028·2023-06-02 13:36
閱讀 3108·2023-05-23 10:26