js代碼執(zhí)行速度 很大程度上依賴瀏覽器的引擎 不同瀏覽器跑 速度可能會差很多

成都創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務領域包括:網(wǎng)站設計、成都網(wǎng)站建設、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務,滿足客戶于互聯(lián)網(wǎng)時代的行唐網(wǎng)站設計、移動媒體設計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡建設合作伙伴!
然后就是算法的時間復雜度 和處理的數(shù)據(jù)量
還有就是多次操作dom也相當耗時
你要分析下你的代碼慢的原因
是循環(huán)套循環(huán)了?
還是說邏輯太復雜了
如果多次操作dom 導致頁面reflow次數(shù)過多
渲染次數(shù)過多 也可能給你感覺很慢
1.后臺統(tǒng)計方法執(zhí)行時間,顯示為秒級別longstartTime=System.currentTimeMillis();//執(zhí)行方法longendTime=System.currentTimeMillis();floatexcTime=(float)(endTime-startTime)/1000;System.out.println("執(zhí)行時間:"+excTime+"s");2.前臺統(tǒng)計時間,顯示為秒級別varst=newDate();//執(zhí)行方法varet=newDate();varexecTime=(et-st)/1000;varet=document.getElementById("time");et.innerHTML="執(zhí)行時間:"+execTime+"s";不過從Firefox的firebug調試工具統(tǒng)計時間來看,前臺統(tǒng)計時間比真實時間短,調試工具統(tǒng)計的時間跟后臺統(tǒng)計的時間相近,且稍長,合情理,所以前臺統(tǒng)計數(shù)據(jù)直接從后臺取。3.得出查詢速度的方法是:在各個select語句前加:declare@ddatetimeset@d=getdate()并在select語句后加:select[語句執(zhí)行花費時間(毫秒)]=datediff(ms,@d,getdate())
建議你觀察下頁面內(nèi)資源的加載時間,同時在頁面中打開多個js文件主要耗時為TTFB,主要耗時為「等待某個js加載渲染完成」+「等待dns解析時間」+「瀏覽器的pending策略」等。你在頁面內(nèi)同步加載了多個js資源,所以下載速度的不可控是正常的。
因為JS在執(zhí)行的時候會影響到頁面的DOM和樣式等情況。瀏覽器在解析渲染HTML的時候,如果解析到需要下載文件的script標簽,那么會停止解析接下來的HTML,然后下載外鏈JS文件并執(zhí)行。減少 JavaScript 對性能的影響有以下幾種方法:1、將所有的
方案1:針對支持html5 webworker的現(xiàn)代瀏覽器方案:。
代碼1.你的大量計算,放到一個js文件中。如下:
//job.js
onmessage?=function?(evt){
//do?massive?job.在這里你進行大量耗時的計算過程。
postMessage(?data?);//將計算結果的數(shù)據(jù)發(fā)送會主線程
}
你的頁面代碼:
!DOCTYPE?HTML
html
head
meta?http-equiv="Content-Type"?content="text/html;?charset=utf-8"/
script?type="text/javascript"
//WEB頁主線程
var?worker?=new?Worker("job.js");?//創(chuàng)建一個Worker對象并向它傳遞將在新線程中執(zhí)行的腳本的URL
worker.postMessage('開始計算');
worker.onmessage?=function(evt){//接收worker傳過來的數(shù)據(jù)函數(shù)
console.log(evt.data);//輸出worker發(fā)送來的數(shù)據(jù),這里就獲取到了大量計算的結果。
}
/script
/head
body/body
/html
方案2:對于不支持WebWorker線程的瀏覽器。
可以考慮分批處理。即是說創(chuàng)造一個間隔定時器setInterval。
每隔一小段時間,處理大量數(shù)據(jù)中的一部分。
這樣就可以避免大量計算導致瀏覽器卡死。
大致代碼如下(這里是簡單的例子。具體情況具體分析。):
假設我們要計算1000萬個數(shù)據(jù)的和。
var?jobData?=??[];//假設是一個數(shù)組。里面有1000萬個數(shù)據(jù)。
function?sliceJob(){
var?num?=?(jobData.length?/?100)?+?1;//把任務數(shù)據(jù)劃分為100份。
var?portion?=?100000;//每份有10萬個數(shù)字。
var?addition?=?0;//這里用來保存最后的結果。一開始是0;
var?intv?=?setInterval(function(){
if(num--){
//然后每一份結果。
additoin?+=?every;
}?else?{
計算最后一份,然后輸出結果。
alert('最終結果是:',?addition);
window.clearInterval(intv);
}
},?50);
}
此外。jQuery的deferred對象無法實現(xiàn)你的要求。
因為deferred對象的目的是為了串行處理異步過程。
但是異步過程在執(zhí)行的過程中,如果耗時過長,仍然會阻塞瀏覽器線程,導致瀏覽器不可操作(卡死)。
唯一的一個例外是$.ajax。$.ajax方法也會返回一個Deferred對象。但是由于該異步過程是用的XMLHttpRequest。而xhr默認是異步執(zhí)行的,相當于另起一個線程,因此不會阻塞瀏覽器縣城。
說起JS的異步執(zhí)行機制,如果百度一下,你首先會發(fā)現(xiàn)阮一峰的寫過一篇關于異步機制的文章( ),等你津津有味又一頭霧水的看完,然后繼續(xù)看百度的其他結果,然后會發(fā)現(xiàn),阮一峰的這篇被另一個大牛樸靈給批判了
( )。
由此可見,關于異步執(zhí)行機制到底是怎么回事,因為涉及到瀏覽器底層機制,所以不容易徹底了解清楚,就算是大牛阮一峰,也只是通過英文文獻來了解,而且一知半解。我的這篇文章只是試圖盡可能簡單的描述一下JS的異步執(zhí)行機制,坦白說,我現(xiàn)在并不能完全弄懂這個機制,所以也不能完全解釋清這個機制,所以,如果我寫的越嚴謹,就越容易出錯,我只能簡單但是較模糊的描述一下:
JS的運行環(huán)境是一個很復雜的環(huán)境,它里面有非常多的復雜的名詞事物,用簡單又不嚴謹?shù)恼f法來說,運行環(huán)境里至少有下面這些事物:
有一個國外的web app,專門用來講解異步事件的門道 Loupe ,這個更接近真實情況。為什么我不講解這個?因為更復雜了,我們并不打算研究瀏覽器的底層,不是么?
然后說一下任務隊列里的任務。所有任務可以分成兩種,一種是同步任務(synchronous),另一種是異步任務(asynchronous)。同步任務指的是,靠主線程自己就可以執(zhí)行完成的任務;異步任務指的是,主線程執(zhí)行開始之后,需要靠主線程之外的線程才能完成的任務。由主線程決定是否要動用其他線程。以下內(nèi)容,不再提棧,只說主線程。
現(xiàn)在說重點:
異步任務的執(zhí)行機制是:
當主線程遇到一個異步任務,比如一個ajax請求,當主線程執(zhí)行到 xhr.send() 的時候,這個send命令是立即執(zhí)行的, 并不會像一些人想象的,拖到所有同步任務的最后面。 然后主線程向http線程發(fā)送指令,要求http線程向服務器發(fā)送請求。這里強調一下http線程,顯然它不是主線程的一部分,因為它可以并發(fā),如果你有100個ajax請求,每個都需要1秒鐘,是不是http線程要花100秒呢?并不是,它會并發(fā)100個請求,總共耗時大約1.01秒就完成了。
主線程向以http線程為代表的幾個線程發(fā)送指令之后,主線程就暫時不再管這個ajax任務了,而是去看任務隊列里的下一個任務。
http線程發(fā)送了請求之后接收反饋,收到之后,形成一個新的事件(可以叫做“我收到啦!”事件),然后插入到回調函數(shù)隊列中,因為回調函數(shù)隊列的優(yōu)先級很低,所以會排到總隊列的最后面,其結果就是:主線程把同步任務都完成了,才開始執(zhí)行異步事件的 回調 。 注意,并不是異步任務在全體同步任務結束之后才開始,而是異步任務的回調通常在全體同步任務結束之后才開始!異步任務跟異步任務的回調是兩回事!是兩個任務!一個鮮明的例子就是 setTimeout(fn, 1000) ,計時是從主線程遇到 setTimeout() 任務,然后分配給計時器線程,計時器線程開始干活的時候就開始計時了!只不過要1秒之后 fn 才執(zhí)行! setTimeout() 和 fn 是兩個任務! setTimeout() 是立即執(zhí)行, fn 才是1秒之后執(zhí)行。但是 setTimeout() 的執(zhí)行,人眼是感受不到的,因為并沒有什么地方有一個秒表告訴你 setTimeout() 開始執(zhí)行了;而fn的執(zhí)行,人眼能感受到,所以人們會錯誤的以為fn才是異步任務,其實fn并不是, fn 是個回調任務,往往 fn 是同步任務,比如 fn 可能是 console.log(123) ,這怎么會是異步任務。
所以,異步機制是瀏覽器的兩個或以上常駐線程共同完成的,異步請求是JS主線程和其他某個線程共同完成的,JS的執(zhí)行線程發(fā)起異步請求(這時瀏覽器會開一條新的HTTP請求線程來執(zhí)行請求,這時JS自己的任務已完成,繼續(xù)執(zhí)行線程隊列中剩下的其他任務),然后在未來的某一時刻"任務隊列"線程監(jiān)視到之前的發(fā)起的HTTP請求已完成, "任務隊列"就會把完成事件插入到JS執(zhí)行隊列的尾部等待JS處理 。
最后專門說說定時觸發(fā)(settimeout和setinterval)。
定時觸發(fā)是由瀏覽器的定時器線程執(zhí)行的定時計數(shù), 然后在定時時間到達之后,定時器線程把定時處理函數(shù)的執(zhí)行請求插入到JS回調隊列的尾端。
這個1到底是100毫秒之后彈出,還是1000毫秒(或更多時間)后彈出呢?又或是1100毫秒之后彈出?
答案是,1000毫秒多一點點之后彈出。
原因:瀏覽器會先執(zhí)行setTimeout,也就是開始計時,然后開始執(zhí)行sometask,執(zhí)行了1000毫秒,然后去回調隊列里看回調任務,alert(1);早就恭候了,因為定時100毫秒之后alert(1)就可以執(zhí)行了。所以,等1000毫秒的任務完成,1就會立即彈出,所以答案是1000毫秒多一點點之后彈出。
所以用這兩個函數(shù)的時候,實際的執(zhí)行時間是大于或等于指定時間的,不保證能準確定時的。
最后強調一下setInterval。比如我希望每100毫秒打印一個1。然后,又有極端情況,就是sometask耗時1000毫秒。你以為sometask結束之后會打出10個1么?并不會,只會打出1個1,因為setInterval第一次讀秒結束之后,回調隊列出現(xiàn)了一個alert(1),根據(jù)之前的理論,并不會執(zhí)行。又過了100毫秒之后,計時器線程會去觀察回調隊列是不是已經(jīng)有了alert(1),如果有,就不再往回調隊列里加alert(1),目的就是為了避免回調疊加執(zhí)行。
總之,你需要記住,異步任務就是主線程在任務隊列里看到了這個任務,看了一眼之后就然后安排別的線程幫忙,然后主線程就忙別的去了,別的線程幫忙完事之后,再在隊列末尾放一個新任務叫“幫忙完畢”,到此異步任務本身就完事。主任務看到“幫忙完畢”任務之后,就去執(zhí)行回調,回調執(zhí)行完,這個異步任務連同回調就全都完事。然后,如果并沒有回調。。。沒有就沒有唄。
看得出來你不太懂 JS,先把代碼給你,做了很多注釋,先仔細看看,然后后面講解為什么:
//?檢查表單的函數(shù)
function?checkForm()?{
/**?@type?{string}?數(shù)據(jù)容器?*/
var?merArr="";
/**?@type?{number}?局部循環(huán)指針?*/
var?p=0;
/**?@type?{Array.Element}?獲取待提交的表單元素?*/
var?items?=?document.getElementsByName("add_mer");
//?遮罩
Ext.getBody().mask("數(shù)據(jù)保存中,請稍等...");?//這里沒有起作用
//?開始檢查
doCheck();
function?doCheck(){
/**
?*?循環(huán)構造字符串
?*?為了避免長時間阻塞,每一段僅允許循環(huán)?100?次
?*?如果一次不能完成,則分組完成
?*/
for(var?i=0;?i100??pitems.length;?i++,?p++)?{
if?(items[x].checked)?{
merArr?=merArr+Trim(items[x].value)+",";
}
}
//?如果循環(huán)結束
if?(p?===?items.length)?complete();
//?如果循環(huán)沒有完成,則用?setTimeout?交出控制權,延遲循環(huán)
else?setTimeout(doCheck,?1);
}
//?檢查結束,真正的處理表單
function?complete(){
document.getElementById("merArray").value?=?merArr;
if(merArr==""){
alert("請勾選!");
Ext.getBody().unmask();
return?false;
}
document.forms['listForm'].action?=?'addGroupMer.action';
document.forms['listForm'].submit();
}
return?false;
}
下面是講解:
1、 JS 是阻塞式的。在一個 JS 函數(shù)正在執(zhí)行的時候,對 DOM 的渲染其實對于用戶來說是不可見的。也就是說,你在一個 JS 循環(huán)中不論對 DOM 做了什么,用戶都是看不到中間過程,只能看到一個最終的結果。
2、 所以,上面代碼的核心是,把耗時特別長的操作部分,使用 setTimeout 延遲。 setTimeout 可以把控制權還給瀏覽器,留出足夠的頁面渲染時間。
3、 setTimeout 的過程中,要注意變量的處理。對于閉包的應用是一個需要注意的地方。
以上,請采納,請給分。
網(wǎng)頁名稱:javascript耗時的簡單介紹
文章出自:http://chinadenli.net/article8/dsgjiip.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供標簽優(yōu)化、手機網(wǎng)站建設、面包屑導航、關鍵詞優(yōu)化、網(wǎng)站收錄、App設計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)