浏览器中Javascript的加载和执行
在剛學習Javascript時曾對該問題在小組內(nèi)做個一次StudyReport,發(fā)現(xiàn)其中的基礎還是值得分析的。?
從標題分析,可以加個Javascript的加載和執(zhí)行分為兩個階段:加載、執(zhí)行。而加載即瀏覽器下載JS腳本的過程,執(zhí)行時瀏覽器JS引擎解釋執(zhí)行的過程。
接下來先分析JS腳本加載的過程,加載方式可分為同步加載和異步加載。
同步加載即瀏覽器加載JS過程中停止對HTML元素的解析,保證JS執(zhí)行的安全一致性,但如果JS中包含大量計算時,會導致阻塞頁面的渲染。常見的JS加載是通過<script>標簽置于<head>內(nèi)加載,這種方式會導致加載時阻塞對HTML元素的渲染,導致頁面短暫空白。因此,建議將<script>便簽置于</body>前,可以在HTML渲染完成后加載JS文件。即,
傳統(tǒng)加載方式:
<head><script src='yourscript.js'></script>
</head>
<body></body>
推薦加載方式:
<head></head><body>
...
<script src='yourscript.js'>
</script>
</body>
使用一個例子加上一張序列圖來描述HTML加載JS/CSS的流程,其中各個步驟均是同步的,會阻塞下一步解析。
<html> <head> <link></link> <script><script> </head> <body> <div></div> <script></script> </body> </html>
異步加載也稱動態(tài)加載,即在后期動態(tài)加載JS。常見的動態(tài)JS加載有以下幾種方式。
1.document.write('yourscript.js');//這種方式在各瀏覽器行為不一致
2.動態(tài)修改<script></script>的src
3.動態(tài)插入<script>標簽,可在<script>腳本中,也可在onload中
<script> var s = document.createElement('script'); s.type = 'text/javascript'; s.src = 'yourscript.js'; var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x); </script>4.XHR結合eval
var xhr = new XmlHttpRequest(); xhr.onreadstatechange = function(){if(xhr.readyState==4){if(xhr.status==200){eval(xhr.responseText);}} } xhr.open("GET",yourscript.js',true); xhr.send(null);5.defer和async屬性。
<script src='yourscript.js' async/defer ></script>
二者都在onload之前執(zhí)行完成,可用于不修改DOM的JS腳本加載。不同之處在與,defer下載的JS按順序執(zhí)行,而async不能保證執(zhí)行順序。
?
接下來分析腳本的執(zhí)行流程。執(zhí)行可分為解釋與執(zhí)行兩個過程。
在腳本解釋的過程中,會對var和function做不同的處理,var定義的對象賦值undefined,而function定義的對象賦值為函數(shù)體。
我們用示例來解釋上面的意思。首先看解釋器對var的處理。
?
<script>alert(i); // undefinedvar i = 1;alert(i); </script>上述代碼在解釋器中進行轉(zhuǎn)換為:
<script>var i;alert(i); // undefinedi = 1;alert(i); </script>這樣就能理解為什么i值為undefinded。接下來我們看看對function的處理。
<script>alert(func); // function(){alert('out')}var func = function(){alert('out');};alert(func); </script>上述代碼在解釋器中進行轉(zhuǎn)換為:
<script>var func = function(){alert('out');};alert(func); // function(){alert('out')}alert(func); </script>這就是解釋器對var和function的不同處理,function的聲明和函數(shù)體定義都會被提前。
另外,腳本解釋過程中,以<script>以塊為單位執(zhí)行,塊間可共享變量。對外部腳本會將JS加載完成并執(zhí)行,而且JS腳本在執(zhí)行的過程中會阻塞后續(xù)HTML頁面的渲染。
<script>alert(i); // error 該塊內(nèi)后續(xù)代碼不執(zhí)行i = 1;alert(i); </script> <script>var j=0; alert(j); // </script>上面這個例子解釋了腳本以塊為單位執(zhí)行的原理,雖然第一個<script>會報異常,但并不影響第二個<script>的執(zhí)行。
<script>var i = 1;alert(i); //1 </script> <script>alert(i); //1 </script>通過上例結果,可解釋兩個<script>之間是可以共享變量的。這也就是為什么加載jquery.min.js后,在任何<script>中都可以使用$來引用jQuery。
?
關于瀏覽器加載JS并執(zhí)行的過程暫時描述到此,后期繼續(xù)補充。
?
轉(zhuǎn)載于:https://www.cnblogs.com/tesky0125/p/4619554.html
總結
以上是生活随笔為你收集整理的浏览器中Javascript的加载和执行的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 专业实训题目需求分析
- 下一篇: Swift - 移除页面视图上的所有元素