1. 程式人生 > >解決AJAX請求使PHP反應時間過長的問題

解決AJAX請求使PHP反應時間過長的問題

現在我們開發了很多依賴於Ajax請求的應用,在某些情況下,甚至全部頁面都依賴Ajax。有時我們會注意到,當一個網頁傳送兩個或者更多Ajax請求時,PHP的反應時間會很長並會同時返回響應內容。

這個問題很可能是你處理PHP會話的方式造成的,跟著本文去理解這個問題,並做一些處理來避免這個問題。

內容

什麼是PHP會話?
什麼是Ajax?
具體問題
造成的原因
問題的解決方法
總結

PHP Ajax

什麼是PHP會話?

為了理解這個問題,有必要先了解一下PHP會話和Ajax,以及它們是怎麼幹擾的。
假設你正在開發一個Web應用,想要識別不同使用者。你想要記住是誰每次瀏覽了所有頁面但都沒有登入,這種情況下,你可以使用cookies或sessions。
可以你已經意識到了,sessions是一種儲存使用者資訊的方式,它可以在任何頁面重新取回使用者資訊。跟Cookies不同,Sessions是儲存在伺服器上的,所有使用者不能直接改變這些資訊。
預設情況下,Sessions在使用者關閉瀏覽器之前均有效,或者使用者在PHP配置檔案中指定的時間內沒有活動之後才失效。
在PHP頁面中,無論你什麼時候想要儲存或者重新獲取使用者資料,都必須在頁面開始處呼叫session_start()

,因此才有許可權使用$_SESSION去獲取session資料。

什麼是Ajax?

Ajax代表 Asynchronous JavaScript and XML,它是一種不用重新載入整個頁面就能向伺服器傳送資料和從伺服器接收資料的方式。
我們使用這種方式來發送資料,並以較快的速度從伺服器檢索資料。我們不用得到整個頁面並在瀏覽器中渲染它,因為這是很慢的。
因此,我們可以更新網頁的一部分,並且使用者是可以看見這種改變的,就像使用者向下滾動Facebook的時間線頁面來看他們想看的東西,隨著新內容新增而不用過載整個頁面。

具體問題

開發幾乎100%基於Ajax的Web應用已經不是一件新鮮事了,但是當一個網頁同時傳送兩個及以上的Ajax請求時,你會注意到請求會花費很長時間,並且幾乎在同一時刻完成了請求。

造成的原因

當你想伺服器傳送一個Ajax請求時,PHP指令碼也開啟了session_start(),它的呼叫會鎖定PHP的session檔案。
你可能已經知道,PHP預設會把session資料儲存在伺服器上的檔案中。因為僅僅只有一個PHP請求能改變同一個session檔案,兩個同時的PHP請求可能會造成典型的檔案鎖條件,因此,任何一個其他由PHP呼叫的對於同一個使用者的session_start()請求將不得不等到第一個請求結束。
現在,大部分PHP框架會首先在主檔案中使用session_start()。因此,如果你正在使用會呼叫session_start()的框架或者函式庫,將會造成session檔案鎖,對於使用同一個瀏覽器的相同使用者,這將延遲同時傳送的Ajax請求。

問題的解決方法

呼叫session_write_close()函式會使PHP寫入session檔案並關閉它,因此釋放session檔案後,另一個請求就有許可權寫入。
呼叫session_write_close()之後,當前指令碼會繼續正常執行,但你應該清楚在呼叫session_write_close()之後不允許改變任何session變數;在同一個指令碼中,其它同時傳送給PHP的請求可以鎖定session檔案並改變session變數。
為了讓你看到這種問題,我建立了測試程式碼並將它上傳到了github。你可以再這裡找到測試指令碼。在本地,你需要用一個例項來使用測試程式碼,然後開啟瀏覽器控制檯,檢視請求和響應時間。
正如我們在這個檔案中看到的示例程式碼,如果我們像下面程式碼這樣,建立多個請求…

session_start();
sleep(5);

同一個使用者的每個請求完成之前都將等到前一個請求完成。它將用時5s,因為知道指令碼完成之前,session檔案都沒有被釋放。因此,當第一次呼叫session_start()時,新的請求將被阻塞。那將殺死非同步請求的想法,也就是說,多個請求會在同一時間被髮送和被執行。
如果將檔案中的程式碼改一下:

session_start();
// do something useful here
session_write_close();
sleep(5);

第三行程式碼將釋放session檔案鎖,所以另一個併發請求不需要等待就能執行,因為它可以呼叫session_start()而不會有任何問題。

總結

PHP有些微妙,會讓你擔心為什麼奇怪的事情會發生。但是一旦你理解事情是怎麼執行的,一切將變得有意義,並且你能更好的思考去解決問題。

相關推薦

解決AJAX請求使PHP反應時間的問題

現在我們開發了很多依賴於Ajax請求的應用,在某些情況下,甚至全部頁面都依賴Ajax。有時我們會注意到,當一個網頁傳送兩個或者更多Ajax請求時,PHP的反應時間會很長並會同時返回響應內容。 這個問題很可能是你處理PHP會話的方式造成的,跟著本文去理解這個問題

使用Ajax同步請求時,等待時間增加頁面提示問題

最近在做專案時,有一個需求是批量列印好多個合同,使用AJAX向後臺傳送資料,等待後臺執行後,需要把生成之後的檔案地址傳送過來。 後臺的處理時間比較長,根據合同的多少可能等待時間比較長,會達到10s左右,這個時候如果不加任何的提示,會導致使用者因為沒有看到是否執行而導致重複的操作,為了增加使用者的體驗感,,以

解決首次啟動程式白屏時間的問題(針對Android Studio Instant Run)

轉自郭霖大神: Android Studio中新加入的Instant Run功能,使得我們開發的效率可以大大地提升(詳情見上一篇部落格)。 問題重現 我初次發現這個問題是在升級了Android Studio 2.0之後,當時Android Studio的版本是從1.5直

解決首次啟動程式白屏時間的問題

寫在前面 記得在前兩個星期,我發表了一篇文章叫《你真的瞭解Instant Run嗎?》,裡面詳細講解了Android Studio中新加入的Instant Run功能,使得我們開發的效率可以大大地提升。 不過對於這個功能也有不少朋友提出了疑問,比如我在我的部落格評論區就看到了這樣的評論:

對HTTP請求介面資源下載時間的問題分析

問題描述 我司某產品線有指定業務介面customQuery在線上環境中,與首頁一起開啟時下載資料的時間明顯過長(平均可以達到2s) 注: “與首頁一起開啟” 的含義是指使用者進入WEB系統後會首次載入的主頁面,該主頁會提前請求customQuery資料,以用於顯示首頁中的列表資料。

關於心跳ajax請求pending狀態(被掛起),stalled時間的問題。涉及tcp連接異常。

.net section 解決 5.1 網絡問題 chrome瀏覽器 time iou 數據包 環境:景安快雲服務器(聽說很垃圾,但是公司買的,我也剛來),CentOS-6.8-x86_64,Apache,MySQL5.1,P

ajax請求後返回的時間轉換格式

mda err 時間轉換 simple str tex pro 轉換格式 class 1.以前見過[email protected]/* */(pattern = "yyyy-MM-dd hh:mm:ss") 這種方式,但是最近用的時候不好使 2.一個比較不通

關於Hbase的RegionServer的GC持續時間解決辦法

hbase gc 持續時間 問題現象:分析原因:http://www.aboutyun.com/thread-11240-1-1.htmlhttp://blog.csdn.net/wwwxxdddx/article/details/50981089修改方法:只用原有的配置在後面增加 -XX:+

SecureRandom生成隨機數超慢 導致tomcat啟動時間解決辦法

tails spa centos 7 屬性 gpo org 解決辦法 hang iss 用騰訊雲的CentOS 7.2 CVM 服務器跑Tomcat時發現,Tomcat啟動的特別慢,通過查看日誌,發現時間主要花在實例化SecureRandom對象上了。 由該日誌可以看

網站響應時間的原因及解決方法

網站打不開 網站程序 cas ron height 出口 javascrip 運算 access 遇到過類似問題,我認為有以下幾個原因: 1、網站服務器故障維修(這種情況只能等段

[轉]解決ssh登錄後閑置時間而斷開連接

tao 發送 ring keep wan end keyword com AC 本文轉自: 轉載自博客園wanghetao的博客 我們通過終端連接服務器時,當鼠標和鍵盤長時間不操作,服務器就會自動斷開連接,我們還的需要重新連接,感覺很麻煩,總結一下解決此問題的方法 方

django 解決ajax 請求csrf跨域問題,解決403 forbidden

現象: 請求403 ,提示跨域 原因: 專案setting.py 中installed app 裡面有 'django.middleware.csrf.CsrfViewMiddleware', ###解決過程:檢視請求發現 cookie 有csrftoken 所以利用j

解決linux登入後總是時間會就斷開(解決ssh登入後閒置時間而斷開連線)

1.vim /etc/ssh/sshd_config 配置如下圖: 2.systemctl reload sshd.service (針對阿里雲centos7(貌似阿里雲的都是這樣) 其他別的伺服器使用:service sshd reload     兩行命令搞定。 &nb

關於.Net mvc 專案在本地vs執行響應時間無法訪問時,解決方法!

  最近可能是剛升級了電腦使用了window10作業系統,總是遇到了一些以前沒有遇到過的事情! 今早來到公司本來準備寫bug的,但是當我開啟vs執行的時候發現今天的電腦響應的時間明顯的要比之前開啟網頁除錯的時間要長的多,到最後不但沒有開啟,而且還提示了一個這樣的問題! 如圖:    這就蛋

啟動時白屏時間解決辦法,第三種方法賊好用

你會很奇怪,為什麼有些app啟動時,會出現一會兒的黑屏或者白屏才進入Activity的介面顯示,但是有些app卻不會如QQ手機端,的確這裡要做處理一下。這裡先了解一下為什麼會出現這樣的現象,其實很簡單,簡歷一個簡單的例子就可以理解了。 其實,黑屏或者白屏這裡並不是不正常,而是還沒載入到佈局檔案,

laravel全域性中介軟體解決ajax請求跨域問題

定義中介軟體CorsMiddleware 定義位置: app/Http/Middleware/CorsMiddleware.php CorsMiddleware內容 <?php namespace App\Http\Middleware; use Closure;

智慧卡上電後返回ATR(即復位應答)時間而無法返ATR的解決方案

關於智慧卡片上電後返回ATR時間過長的問題,是在COS開發完成後的智慧卡相容性測試過程中發現的,不同讀卡器廠商均應遵循ISO7816接觸卡協議來設計接觸型讀卡器,理論上ATR響應時間是一樣的,不過實測之後有一定的差距。這也導致了載入開發COS的智慧IC卡在某些讀

解決ajax請求不能下載檔案

我們在使用ajax請求去向服務端下載檔案時,我們通常從服務端拿到的只是一個字串,jquery自動的將檔案中的內容解析為字串傳給我們,此時,我們便不能再使用jquery的ajax請求來下載檔案 我們可以做如下操作來使用表單提交的方法來獲取下載檔案(推薦): function downloa

【JavaScript】ajax請求的資料返回時間戳使用js處理方案

author:咔咔 wechat:fangkangfk   方法: function formatDate(now) {   var year = now.getFullYear(),   month = now.getMonth() + 1,   

ionic3 使用--prod時間問題解決(完美解決)

如果環境正常的話(我一共也有三四十個頁面吧),就算使用--prod對程式碼進行壓縮打包也不會出現緩慢的情況(ionic build android --prod),時間也就頂多會比平時不加--prod