ホームページ > 記事 > ウェブフロントエンド > 高性能なJavaScriptの実行と読み込みを実装する_基礎知識
The browser uses a single process when processing HTML page rendering and JavaScript script execution, so when the browser encounters the 3f1c4e4b6b16bbbd69b2ee476dc4f83a tag while rendering HTML, it will first execute the code in the tag (if the src attribute is used The loaded external link file will be downloaded first and then executed). During this process, page rendering and interaction will be blocked.
...Although there will be blocking, there are still several ways to reduce the impact of JavaScript on performance.
1. The location of the script tag
When 3f1c4e4b6b16bbbd69b2ee476dc4f83a appears in 93f0f5c25f18dab9d176bd4f6de5d30e, such as:
<head> <script type="text/javascript" src="js1.js"></script> <script type="text/javascript" src="js2.js"></script> <script type="text/javascript" src="js3.js"></script> </head>
When loading multiple js files, the browser will first download and execute the js code, blocking page rendering and resulting in a white screen page (the browser will not render any content on the page until it parses the 6c04bd5ca3fcae76e30b72ad730ca86d tag) ), there is no way to preview or interact, which is a very poor user experience.
Note:
Modern browsers support parallel downloading of resources. When downloading external resources only, 3f1c4e4b6b16bbbd69b2ee476dc4f83a will not block other 3f1c4e4b6b16bbbd69b2ee476dc4f83a tags, but will block the downloading of other resources.
Downloading JavaScript resources is asynchronous, but executing JavaScript code is still synchronous, which will also cause blocking.
Therefore, placing 3f1c4e4b6b16bbbd69b2ee476dc4f83a at the bottom of the 6c04bd5ca3fcae76e30b72ad730ca86d tag to ensure that page rendering is completed before executing the script is a relatively common JavaScript optimization method.
2. Merge multiple script tags
When the browser parses HTML and encounters 3f1c4e4b6b16bbbd69b2ee476dc4f83a, there will be a certain delay due to the execution of the script. For external links with src attributes, 3f1c4e4b6b16bbbd69b2ee476dc4f83a will be even worse. Multiple HTTP requests will bring more performance overhead. , Minimizing this delay is also an optimization method. Multiple js files can be merged to reduce the number of HTTP requests, reduce the number of three-way handshakes and redundant HTTP header transmission, reduce response time and improve user experience. There are many solutions and tools for merging js on the Internet, which will not be described here.
3. Use non-blocking method to download JavaScript
3.1. Use the defer and async attributes of the script tag
The async and defer attributes are both used to load js files asynchronously, and will not block other browser processes during the process. The difference is that async is automatically executed after loading, while defer needs to wait until the page is loaded before executing. It should be noted that One thing is that these two attributes must be in the 3f1c4e4b6b16bbbd69b2ee476dc4f83a tag with the src attribute (external link script) to be effective. Below is the demo:
<!DOCTYPE html> <html> <head> <title>defer example</title> </head> <body> <script type="text/javascript" src="defer.js" defer></script> <script> alert("script"); </script> <script> window.onload= function(){ alert("load"); } </script> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> <div class="demo">defer demo</div> </body> </html>
//The defer.js file only has one line of code: alert("defer");
The async example also has the same page structure. I won’t show the example here. You can click on the link below.
Click here for the link to defer example!
Click here for the link to async example!
Although the page structure is the same, the difference is
Open defer.html and you will see the following: The alert box of "script" pops up => The page renders text => The alert box of "defer" pops up => The alert box of "load" pops up
Open async.html and you will see the following: The alert box for "script" pops up => The alert box for "async" pops up => The page renders text => The alert box for "load" pops up
3.2. Use dynamically created script tags to download and execute JavaScript code
var script = document.createElement("script"); script.type = "text/javascript"; script.src = "file.js"; document.getElementByTagName("head")[0].appendChild(script);
file.js starts downloading when the script element is added to the page. The advantage of using this method is that the downloading and execution of file.js will not block other processes on the page.
It can be clearly seen from the demo that the dynamic loading method can see the text on the page before the alert box pops up, but the ordinary method can only see the text on the page after the alert box pops up.
We can encapsulate a cross-browser function that reads script scripts and dynamically creates script tags:
function loadScript(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); }
This type of dynamic script loading method has good compatibility and is relatively simple. It is a commonly used non-blocking solution.
3.3. Use XHR object to download JavaScript code and inject it into the page
Another way to load scripts without blocking is to use the XMLHttpRequest (XHR) object to obtain the script and inject it into the page.
This technique will first create an XHR object, then use it to download a JavaScript file, and finally inject the code into the page through a common dynamic 3f1c4e4b6b16bbbd69b2ee476dc4f83a element.
var xhr = new XMLHttpRequest(); xhr.open("get","file.js",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/javascript"; script.text = xhr.responseText; document.body.appendChild(script); } } }
以上代码发送GET请求file.js文件,onReadyStateChange检测readyState是否为4(4表示请求完成)和HTTP状态吗是否有效(200表示有效响应,304表示读取缓存)。判断响应有效之后,就动态创建一个3f1c4e4b6b16bbbd69b2ee476dc4f83a标签,内容就是服务器接收到的responseText。
这种方法的优点以及缺点:
优点:下载JavaScript代码可以不立即执行,且兼容性好适合所有主流浏览器。
缺点:JavaScript文件必须与所请求页面处于同一个域,这种情况下JavaScript文件不能从CDN下载,不适合大型的Web应用。
4.一种推荐的无阻塞方案
如果页面有大量的JavaScript代码需要添加,可以先在页面中去外链之前我们封装好的动态读取script脚本的函数loadScript,然后再使用它去加载其他所需脚本,例如:
<script type="text/javascript" src="loader.js"></script> <script type="text/javascript"> loadScript("file.js",function(){ //do something }); </script>
这样只需在第一个3f1c4e4b6b16bbbd69b2ee476dc4f83a下载比较精简的loader.js文件时对页面有些许影响,之后的3f1c4e4b6b16bbbd69b2ee476dc4f83a并不会有太多影响。