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

歡迎訪問 生活随笔!

生活随笔

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

javascript

高性能JavaScript-JS脚本加载与执行对性能的影响

發(fā)布時(shí)間:2025/3/17 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高性能JavaScript-JS脚本加载与执行对性能的影响 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在web產(chǎn)品優(yōu)化準(zhǔn)則中,很重要的一條是針對js腳本的加載和執(zhí)行方式的優(yōu)化。本篇文章簡單描述一下其中的優(yōu)化準(zhǔn)則。

1. 腳本加載優(yōu)化

1.1 腳本位置對性能的影響

優(yōu)化頁面加載性能的原則之一是將script標(biāo)簽放在body底部,這跟瀏覽器的渲染原理有關(guān):

  • js腳本的下載和執(zhí)行會阻塞瀏覽器的解析。在較早時(shí)期,瀏覽器不支持并行下載的時(shí)候,js腳本的下載執(zhí)行按照在html文檔中的位置依次進(jìn)行,可以想象當(dāng)頁面有大量js腳本時(shí)頁面的加載有多慢;
  • js腳本的下載會阻塞其他資源的下載,比如圖片、外鏈css等。雖然目前大多數(shù)瀏覽器支持并行下載,外鏈js文件可以并行下載,但是在下載js的過程中,其他資源的加載仍然會被阻塞。
  • 綜上所述,除非業(yè)務(wù)需求必須將js腳本放在指定位置,最佳的優(yōu)化準(zhǔn)則是將js放于body底部。

    1.2 合并腳本文件

    每個(gè)script標(biāo)簽都會阻塞頁面的解析和其他資源的加載,可以通過合并js腳本文件進(jìn)行優(yōu)化。雖然目前大多數(shù)瀏覽器支持并行下載,但是隨著web產(chǎn)品越來越龐大,瀏覽器支持的并行數(shù)量明顯不能滿足需求,隨意js文件的合并打包是很有必要的。

    目前較流行的grunt/gulp/webpack等編譯工具都支持文件的打包合并,webpack甚至可以將css文件也一并打包到j(luò)s文件里。我們先不去評價(jià)這種模式的好壞,單從減少文件數(shù)量這個(gè)角度來看,這是為了減少http請求數(shù)目、script標(biāo)簽數(shù)量以提高頁面的加載性能。

    其實(shí)這種理念很早就有,有后端開發(fā)經(jīng)驗(yàn)的朋友可能接觸過combo handler,這是Yahoo YUI團(tuán)隊(duì)開發(fā)的一個(gè)Apacha模塊。combo handler可以支持瀏覽器使用一個(gè)url請求多個(gè)文件,比如我們頁面中需要兩個(gè)js文件,常規(guī)情況下使用2個(gè)script標(biāo)簽請求:

    <script src='http://static.me.com/a.js'></script> <script src='http://static.me.com/b.js'></script>

    使用combo handler可以通過以下形式:

    <script src='http://static.me.com?a.js&b.js'></script>

    a.js和b.js在服務(wù)器是獨(dú)立存在的,combo handler可以通過一個(gè)http請求將兩者合并為一起返回,減少了http請求數(shù)目,提高了頁面加載性能。

    2. 無阻塞腳本

    2.1 defer和async

    defer和async都是針對外鏈的js腳本文件,如下:

    <script src='http://static.me.com/a.js' defer></script> <script src='http://static.me.com/a.js' async></script>

    defer和async的作用都是令指定的js文件異步加載,不影響html文檔其他內(nèi)容的解析,也就是說帶有defer和async的js文件和html文檔的解析是并行的。但是兩者的運(yùn)行機(jī)制有稍許差別。

    defer在IE4就引入了,目前幾乎所有瀏覽器都支持。defer的js文件在并行下載結(jié)束后并不立即執(zhí)行,其執(zhí)行時(shí)機(jī)是在文檔加載完畢后window.onload觸發(fā)之前

    async是HTML5引入的新規(guī)范,目前獲得了大多數(shù)瀏覽器的支持。async的js文件在并行下載結(jié)束后立即執(zhí)行

    比較defer和async的區(qū)別可以得到以下結(jié)論:

  • 兩者都是并行下載,不影響html文檔的解析;
  • defer文件的執(zhí)行時(shí)機(jī)是在window.onload之前,所以defer文件的位置任意;
  • async文件下載結(jié)束后立即執(zhí)行,是亂序的。所以并不適用于有依賴關(guān)系的js腳本;
  • defer和async的腳本中應(yīng)當(dāng)避免使用document.wirte,否則會清空頁面原有的內(nèi)容。
  • 2.2 動態(tài)腳本

    所謂動態(tài)腳本的意思是使用JavaScript創(chuàng)建一個(gè)script,指定其src并將此script標(biāo)簽插入文檔的head中。

    之所以將動態(tài)script標(biāo)簽插入head而不是body中是因?yàn)樵诘桶姹綢E中如果在html文檔未解析完畢時(shí),body中插入script標(biāo)簽會拋出“操作已終止”的錯誤信息。具體可參考The dreaded Operation Aborted error。

    動態(tài)腳本請求到的js腳本是立即執(zhí)行的。

    動態(tài)創(chuàng)建script標(biāo)簽時(shí),某些業(yè)務(wù)場景下需要監(jiān)聽被請求的js腳本是否加載完畢。大多數(shù)瀏覽器都支持script.onload事件:

    script.onload = function(){}

    IE瀏覽器沒有實(shí)現(xiàn)onload事件,而是會觸發(fā)readystatechange事件。當(dāng)readyState的狀態(tài)為loaded或complete時(shí)便可以認(rèn)為js腳本文件已加載完畢。兼容所有瀏覽器的loadScript函數(shù)如下:

    function loadScript(url,callbakc){var script = document.createElement('script');script.type = 'text/javascript'; //低版本IE下必須制定type,其他瀏覽器可以不寫if(script.readtState){ //IEscript.onreadystatechange = function(){if(script.readyState === 'loaded' || script.readyState === 'complete'){script.readyState === 'null';callback();}};}else{ //其他瀏覽器script.onload = function(){callbakc();}}script.src = url;document.getElementByTagName('head')[0].appendChild(script); }
    2.3 使用XHR注入js腳本

    使用XHR注入腳本是比較偏門并且應(yīng)用面很小的一門技術(shù),原理就是用Ajax去get請求一個(gè)js文件,監(jiān)聽xhr.status,獲取到的響應(yīng)信息是js文件的代碼。然后動態(tài)創(chuàng)建一個(gè)script標(biāo)簽,將獲取到的js代碼注入script標(biāo)簽內(nèi),最后將script標(biāo)簽插入文檔中。

    這種方式注入的js腳步并不會立即執(zhí)行。缺點(diǎn)是無法跨域,因此很少得到應(yīng)用。

    總結(jié)

    以上是生活随笔為你收集整理的高性能JavaScript-JS脚本加载与执行对性能的影响的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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