關於大型網站技術演進的思考(十三)--網站靜態化處理—CSI(5)
講完了SSI,ESI,下面就要講講CSI了 ,CSI是瀏覽器端的動靜整合方案,當我文章發表後有朋友就問我,CSI技術是不是就是通過ajax來載入資料啊,我當時的回答只是說你的理解有點片面,那麼到底什麼是CSI技術了?這個其實要和動靜資源整合的角度來定義。
CSI技術其實是在頁面進行動靜分離後,將頁面載入分為兩個步驟完成,第一步是載入靜態資源,靜態資源載入完畢後進行第二步驟載入動態資源。不過這個定義還是表述的不全面,不全面的地方就是我們要強調動靜分離的目的,我們把頁面裡的動靜資源拆分出來是為了將靜態資源做有效的快取,這個靜態資源可能是在靜態web容器上,也有可能是在CDN上,也有可能是在瀏覽器上,不管靜態資源是如何快取的,我們的目的都是為了讓靜態資源載入的速度更快,如果我們沒有讓靜態資源載入變得高效,就算我們使用了CSI的形式來設計頁面,其實也沒有發揮CSI的優點,反倒還會一不小心引入CSI的缺點。那什麼是CSI的缺點呢?具體如下:
CSI的缺點一:CSI不利於頁面的SEO即搜尋引擎優化。搜尋引擎的網路爬蟲一般是根據url訪問頁面,獲取頁面的內容後去掉沒用的資訊例如:css樣式,js指令碼,然後分析剩下的文字內容,因此假如頁面的一部分內容需要進行非同步載入,那麼這個載入控制肯定是由javascript程式碼來完成的,因此網路爬蟲爬下來的頁面裡非同步載入的操作是沒法執行的(聽說有些高階的爬蟲可以執行非同步的操作,抓取非同步的內容,即便有這個技術,大部分主流的爬蟲還是會忽略掉javascript程式碼的也會忽略非同步載入的內容的),這就會導致爬蟲爬的頁面裡有部分資訊丟失了,所以說CSI對SEO不太友好。不過這個缺點我們仔細分析下,可能並不會是那麼嚴重,前面我們談論了很多靜態分離的策略,如果我們動靜分離策略做的好,那麼動態資源基本都是不能被快取的內容,經常發生變化的內容,這些變化的內容本來就不需要被網路爬蟲爬到,就算真的被爬到,搜尋引擎有個查詢結果指向了這個頁面,我們點開這個頁面結果也是在頁面找不到被搜尋的關鍵字,這種情形我相信很多朋友在使用搜尋引擎時候都會碰到過。不過我想如果開發人員沒有正確使用CSI,那麼這塊他們可能也不會處理的特別好,因此這個缺點還是很容易被引入的。
CSI的缺點二:我們那麼費時費力想讓自己的網站靜態化,目的就是想讓頁面載入更快點,我們簡簡單單把頁面載入分成了兩個步驟進行,那麼這麼做就真的快嗎?這可不一定啊,其實動靜分離的做法和我上一個系列裡講到的資料庫讀寫分離有類似之處,資料庫讀寫分離我們是通過拆分原表的讀寫之間的關聯關係,從而達到解決讀的瓶頸問題,而網頁的動靜分離是因為靜態資源很容易被優化,所以我們要拆分動靜資源。所以當我們對資源進行了動靜分離,但是又沒有優化靜態資源,這個一看就知道我們缺少一個加速頁面載入速度的操作,那麼真的能讓頁面載入快點,還真的很難說了,而且非同步載入需要執行javascript程式碼才行,但是靜態資源載入時候很容易造成javascript指令碼被阻塞,如果阻塞的指令碼正好是非同步載入的部分,結果只會是比以前載入的更慢了。
由此可見,我在前面講到的SSI和ESI技術對於我們在瀏覽器端發揮CSI技術優點是非常有必要的,SSI和ESI做好了能讓動靜分離出的靜態資源載入的更加高效,這也就讓CSI操作的第一個步驟變得高效,第一個步驟處理好了我們只要在頁面控制好指令碼阻塞對非同步載入的影響,那麼我們就可以達到提升整個頁面載入效率的目的了。此外我覺得CSI對SEO有重大影響是個偽命題,假如使用CSI造成了SEO效果不佳,那麼肯定是我們CSI方案設計的不到位。
有人認為CSI還會有個缺點,不過筆者我並不認為這是一個缺點,這其實是一個設計問題,好與壞是根據個人的操作習慣所決定的。這個別人認為的缺點是什麼呢?它就是使用CSI技術時候,雖然頁面很快的被載入出來了,但是動態內容那部分可能會顯示一個正在載入的提示,那麼這就導致頁面使用者友好性降低,其實這種同步和非同步載入混搭操作實在太常見了,幾乎所有大型入口網站,電商網站還有一大堆數不盡的網站都是採用同步和非同步混搭的載入方式,假如這些網站不這麼做,我相信這些網站例如首頁載入一定會慢的讓人吐血,因為它們很多網頁裡面內容實在太多,圖片也都有點爆棚了,所以它們不得不使用同步和非同步混搭的載入方式,甚至很多靜態資源例如圖片,flash這些東西也會採取非同步載入方式。說到這裡,估計有人還是覺得不服氣,他就是不喜歡頁面載入時候還要出現個正在載入提示,但是網頁裡又非常需要CSI帶來的好處,那麼我們該如何解決這個問題呢?這個問題很好解決,首先願意使用CSI技術也就說明使用者還是很願意使用非同步的載入技術的,不喜歡則是正在載入的提示,這說明使用者想要在做同步載入操作時候不要摻雜非同步操作,雖然現在ajax技術大行其道,但是ajax技術有個同步載入是沒有辦法解決的,那就是我們在瀏覽器位址列裡輸入網站url請求頁面 ,所以面對上面的需求我們只要保證這種同步操作只是一個純粹的同步操作而不要摻雜非同步載入即可,這個方案還是很好實施的,這裡我就不再累述了。
動靜分離後我們會把靜態資源進行快取,前面文章裡講了一大堆都是在講服務端的靜態資源快取,現在講到了CSI已經到了瀏覽器端,那麼我們就得談談瀏覽器的快取操作。頁面的快取操作就是使用http的expires和cache-control,我們首先看看下面的寫法:
<meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0">
這是我現在做的java的web專案裡,jsp和vm檔案都會使用的meta配置,它的目的就是讓頁面不要被瀏覽器快取,但是如果使用CSI技術,同時動靜分離做的很好,那麼在頁面頭部其實我們可以不再這麼寫了,我們可以讓頁面在合理的時間範圍內被瀏覽器快取,如果該頁面做了快取操作,那麼以後我們再訪問該頁面,網頁的載入效率就會變得更高了。
這裡還有個問題,在雅虎優化網站的建議裡,為了充分利用網頁並行載入的特點,我們往往會把圖片,外部的js和css檔案放置在單獨的靜態web容器或CDN上,那麼這些檔案往往也是可以被瀏覽器快取,這個我們又如何設定才能讓瀏覽器知道要快取它們呢?這裡我們以apache為例,為了讓靜態資源被瀏覽器快取,apache需要使用mod_expires模組,然後在apache的配置檔案裡新增如下配置:
<FilesMatch "\.(gif|jpg|png|js|css">ExpiresDefault "access plus 10 years"</FilesMatch>
那麼瀏覽器訪問此apache上的靜態資源後,瀏覽器就會把圖片和該伺服器上的js和css檔案快取在瀏覽器裡。
我們看看被快取的靜態資源是如何被使用的,如下圖所示:
當http的響應碼是304的時候,那麼瀏覽器就會從快取裡讀取資源了,這裡有的朋友可能會感到奇怪為什麼快取的資源還要傳送個http請求了?理解這個我們就要了解下快取的機制,快取的含義是臨時儲存某些東西,既然是臨時儲存,那麼就應該有個儲存的有效期,我們定義快取的方式是通過http完成的,那麼按道理檢查快取是否過期也應該是http來決定的,因此每次使用快取時候我們要發個請求到服務端,服務端會檢查下資源是否過期了,如果沒有過期,服務端返回個304的響應碼,304的返回響應是沒有http報文體的,所以這個http請求的返回資料是非常小的,因此這個http效率還是很高的,如果服務端發現資源過期了那麼服務端就會把新資源返回給瀏覽器了,其實這個檢測資源是否過期的請求有個專有名詞叫做條件Get請求。至於服務端是如何完成檢查操作,本系列在講web前端優化時候會詳細闡述,這裡就不深入了。看到這裡估計有朋友又有疑問了,為什麼快取是否過期不能在瀏覽器端來做了?這主要是瀏覽器做這個檢查非常不準,因為使用者的電腦時鐘不一定準確,或者使用者電腦時鐘和服務端不一致,如果再加上時區那麼就更加麻煩了,所以快取失效最好是在服務端進行,這樣快取的有效期的準確性才能得到保證。html5的出現,瀏覽器快取的能力大大增強了,不過使用html5技術進行快取我還沒有深入研究過,所以這裡也不講述了,有興趣的朋友可以自己研究下。
好了,CSI主題內容講完了,講到CSI技術和瀏覽器我們就可以開始本系列另一個重要內容前後端分離了,這將是我下篇的主題,我在自己部落格裡多次講到前後端分離,馬上又要再次講了,這次講是我這麼長時間做前後端分離研究的大總結了。
相關文件:
關於大型網站技術演進的思考(一)--儲存的瓶頸(1)
關於大型網站技術演進的思考(二)--儲存的瓶頸(2)
關於大型網站技術演進的思考(三)--儲存的瓶頸(3)
關於大型網站技術演進的思考(四)--儲存的瓶頸(4)
關於大型網站技術演進的思考(五)--儲存的瓶頸(5)
關於大型網站技術演進的思考(六)--儲存的瓶頸(6)
關於大型網站技術演進的思考(七)--儲存的瓶頸(7)
關於大型網站技術演進的思考(八)--儲存的瓶頸終篇(8)
關於大型網站技術演進的思考(九)--網站靜態化處理--總述(1)
關於大型網站技術演進的思考(十)--網站靜態化處理—動靜整合方案(2)
關於大型網站技術演進的思考(十一)--網站靜態化處理—動靜分離策略(3)
關於大型網站技術演進的思考(十二)--網站靜態化處理—快取(4)
關於大型網站技術演進的思考(十三)--網站靜態化處理—CSI(5)
關於大型網站技術演進的思考(十四)--網站靜態化處理—前後端分離—上(6)
關於大型網站技術演進的思考(十五)--網站靜態化處理—前後端分離—中(7)
關於大型網站技術演進的思考(十六)--網站靜態化處理—前後端分離—下(8)
關於大型網站技術演進的思考(十七)--網站靜態化處理—滿足靜態化的前後端分離(9)
關於大型網站技術演進的思考(十八)--網站靜態化處理—反向代理(10)
關於大型網站技術演進的思考(十九)--網站靜態化處理—web前端優化—上(11)
關於大型網站技術演進的思考(二十)--網站靜態化處理—web前端優化—中(12)
關於大型網站技術演進的思考(二十一)--網站靜態化處理—web前端優化—下【終篇】(13)
相關文章
- 關於大型網站技術演進的思考(十八):網站靜態化處理—反向代理(10)網站
- 關於大型網站技術演進的思考(十二)--網站靜態化處理—快取(4)網站快取
- 關於大型網站技術演進的思考(十八)--網站靜態化處理—反向代理(10)網站
- 關於大型網站技術演進的思考(九)--網站靜態化處理--總述(1)網站
- 關於大型網站技術演進的思考(十)--網站靜態化處理—動靜整合方案(2)網站
- 關於大型網站技術演進的思考(十一)--網站靜態化處理—動靜分離策略(3)網站
- 關於大型網站技術演進的思考(二十):網站靜態化處理—web前端優化—中(12)網站Web前端優化
- 關於大型網站技術演進的思考(十九):網站靜態化處理—Web前端優化—上(11)網站Web前端優化
- 關於大型網站技術演進的思考(十九)--網站靜態化處理—web前端優化—上(11)網站Web前端優化
- 關於大型網站技術演進的思考(二十)--網站靜態化處理—web前端優化—中(12)網站Web前端優化
- 關於大型網站技術演進的思考(十六)--網站靜態化處理—前後端分離—下(8)網站後端
- 關於大型網站技術演進的思考(十五)--網站靜態化處理—前後端分離—中(7)網站後端
- 關於大型網站技術演進的思考(十四)--網站靜態化處理—前後端分離—上(6)網站後端
- 關於大型網站技術演進的思考(二十一):網站靜態化處理—Web前端優化(下)(13)網站Web前端優化
- 關於大型網站技術演進的思考(十七):網站靜態化處理—滿足靜態化的前後端分離(9)網站後端
- 關於大型網站技術演進的思考(十七)--網站靜態化處理—滿足靜態化的前後端分離(9)網站後端
- 關於大型網站技術演進的思考(二十一)--網站靜態化處理—web前端優化—下【終篇】(13)網站Web前端優化
- 關於大型網站技術演進的思考(五)--儲存的瓶頸(5)網站
- 關於大型網站技術演進的思考(二)--儲存的瓶頸(2)網站
- 關於大型網站技術演進的思考(一)--儲存的瓶頸(1)網站
- 關於大型網站技術演進的思考(三):儲存的瓶頸(3)網站
- 關於大型網站技術演進的思考(一)—儲存的瓶頸(1)網站
- 關於大型網站技術演進的思考(六)--儲存的瓶頸(6)網站
- 關於大型網站技術演進的思考(四)--儲存的瓶頸(4)網站
- 關於大型網站技術演進的思考(三)--儲存的瓶頸(3)網站
- 關於大型網站技術演進的思考(二):儲存的瓶頸(2)網站
- 關於大型網站技術演進的思考(一):儲存的瓶頸(1)網站
- 關於大型網站技術演進的思考(八):儲存的瓶頸(8)網站
- 關於大型網站技術演進的思考(七):儲存的瓶頸(7)網站
- 關於大型網站技術演進的思考(七)--儲存的瓶頸(7)網站
- 大型網站技術架構的演進網站架構
- 關於大型網站技術演進的思考(八)--儲存的瓶頸終篇(8)網站
- 大型網站架構改進歷程(9):網站靜態化處理–總述(1)網站架構
- 大型網站的技術架構演進過程網站架構
- 大型網站技術架構(二)--大型網站架構演化網站架構
- 大型網站技術架構(一)--大型網站架構演化網站架構
- 網站靜態化思想網站
- 頁面靜態化技術演進