setTimeout 導致的瀏覽器假死

來源:互聯網
上載者:User

標籤:http   java   strong   問題   html   代碼   

 問題

   前幾天,同事遇到一個瀏覽器假死的問題。就是瀏覽器在響應一個請求的時候,就突然不回應時間,進入假死狀態,Cup也飆升到100%. 但是這個問題只出現在IE瀏覽器,chrome和Firefox等其他瀏覽器正常。

原因

  Js 代碼裡面,看著也沒有什麼耗時的操作和後台非同步呼叫。沒辦法,只能從響應事件的最開始一步一步調查。經過一番調試之後,問題定位在setTimeout 函數。當把setTimeout 裡面執行的函數去掉之後,立馬就不會出現這種情況。查看setTimeout 裡面調用的函數,發現裡面JS中有一些的DOM操作,函數裡面還進行了html的拼接。難道是這個原因導致的。於是網上查原因:當一段JS指令碼長時間佔用著處理機就會掛起瀏覽器的GUI更新,而後面的事件響應也被排在隊列中得不到處理,從而造成了瀏覽器被鎖定進入假死狀態。說白了就是:瀏覽器無法在渲染頁面的同時執行js。在setTimeout 函數裡面,確實有一些拼接html 和操作dom 的情況。可能就是js在執行的時候,js代碼裡面又有一些拼接html 的操作。導致瀏覽器無法渲染頁面,而js 裡面在操作這個頁面的內容。導致瀏覽器卡死。

瀏覽器的核心處理方式:

  瀏覽器的核心是多線程的,它們在核心制控下相互配合以保持同步,一個瀏覽器至少實現三個常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發線程。

  1. JavaScript引擎是基於事件驅動單線程執行的,JS引擎一直等待著任務隊列中任務的到來然後加以處理,瀏覽器無論再什麼時候都只有一個JS線程在運行JS程式。
  2. GUI 渲染線程負責渲染瀏覽器介面,當介面需要重繪(Repaint)或由於某種操作引發迴流(reflow)時,該線程就會執行。但需要注意 GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會被儲存在一個隊列中等到JS引擎空閑時立即被執行。
  3. 事件觸發線程,當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeOut、也可來自瀏覽器核心的其他線程如滑鼠點擊、AJAX非同步請求等,但由於JS的單線程關係所有這些事件都得排隊等待JS引擎處理。

 

  明白了瀏覽器核心處理方式,就可以理解瀏覽器為什麼會進入假死狀態了,當一段JS指令碼長時間佔用著cpu 時間時,就會掛起瀏覽器的GUI更新,而後面的事件響應也被排在隊列中得不到處理,從而造成了瀏覽器被鎖定進入假死狀態。另外JS指令碼中進行了DOM操作,一旦JS調用結束就會馬上進行一次GUI渲染,然後才開始執行下一個任務,所以JS中大量的DOM操作也會導致事件響應緩慢甚至卡死瀏覽器。

 

  這個文章寫得更加透徹:http://www.nowamagic.net/librarys/veda/detail/787

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.