講完了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技術和瀏覽器我們就可以開始本系列另一個重要內容前后端分離了,這將是我下篇的主題,我在自己博客里多次講到前后端分離,馬上又要再次講了,這次講是我這么長時間做前后端分離研究的大總結了。
最后,祝大家新年快樂,新的一年喜氣洋洋,開開心心哦。
文章列表