摘要:在高性能服務器上該配置將非常有用。小結前端高性能優化一二總結了前端性能問題定位以及圖片優化的幾種方式,將它們歸結起來,在讀者需要的時候,可以查看本文的內容,相信按照本文的方法,可以輔助讀者進行前端性能優化。
上回我們主要從圖片的合并、壓縮等方面介紹前端性能優化問題(詳見Java Web 前端高性能優化(一))
本次我們主要從圖像BASE64 編碼、GZIP壓縮、懶加載與預加載以及 OneAPM Browser Insight 的定位分析功能四個方面介紹前端優化方法
不管如何,圖片的下載始終都要向服務器發出請求,要是圖片的下載不用向服務器發出請求,而可以隨著 HTML 的下載同時下載到本地那就太好了。而目前,瀏覽器已經支持了該特性,我們可以將圖片數據編碼成 BASE64 的字符串,使用該字符串代替圖像地址。
假設用 S代表這個 BASE64 字符串,那么就可以使用
我們為 Connector 添加了如下幾個屬性,他們意義分別是:
compression="on" 打開壓縮功能
compressionMinSize="2048" 啟用壓縮的輸出內容大小,這里面默認為 2KB
noCompressionUserAgents="gozilla, traviata" 對于以下的瀏覽器,不啟用壓縮
compressableMimeType="text/html,text/xml, image/png" 壓縮類型
有時候,我們無法配置 server.xml,比如如果我們只是租用了別人的空間,但是它并沒有啟用GZIP,那么我們就要使用程序啟用 GZIP 功能。我們將需要壓縮的文件,放到指定的文件夾,使用一個過濾器,過濾對這個文件夾里文件的請求。
清單 4. 自定義 Filter 壓縮 GZIP
// 監視對 gzipCategory 文件夾的請求 @WebFilter(urlPatterns = { "/gzipCategory/*" }) public class GZIPFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String parameter = request.getParameter("gzip"); // 判斷是否包含了 Accept-Encoding 請求頭部 HttpServletRequest s = (HttpServletRequest)request; String header = s.getHeader("Accept-Encoding"); //"1".equals(parameter) 只是為了控制,如果傳入 gzip=1,才執行壓縮,目的是測試用 if ("1".equals(parameter) && header != null && header.toLowerCase().contains("gzip")) { HttpServletResponse resp = (HttpServletResponse) response; final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); HttpServletResponseWrapper hsrw = new HttpServletResponseWrapper( resp) { @Override public PrintWriter getWriter() throws IOException { return new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding())); } @Override public ServletOutputStream getOutputStream() throws IOException { return new ServletOutputStream() { @Override public void write(int b) throws IOException { buffer.write(b); } }; } }; chain.doFilter(request, hsrw); byte[] gzipData = gzip(buffer.toByteArray()); resp.addHeader("Content-Encoding", "gzip"); resp.setContentLength(gzipData.length); ServletOutputStream output = response.getOutputStream(); output.write(gzipData); output.flush(); } else { chain.doFilter(request, response); } } // 用 GZIP 壓縮字節數組 private byte[] gzip(byte[] data) { ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240); GZIPOutputStream output = null; try { output = new GZIPOutputStream(byteOutput); output.write(data); } catch (IOException e) { } finally { try { output.close(); } catch (IOException e) { } } return byteOutput.toByteArray(); } …… }
該程序的主體思想是:在響應流寫回之前,對響應的字節數據進行 GZIP 壓縮。
因為并不是所有的瀏覽器都支持 GZIP 解壓縮,如果瀏覽器支持 GZIP 解壓縮,會在請求報頭的 Accept-Encoding 里包含 gzip。這是告訴服務器瀏覽器支持 GZIP 解壓縮,因此如果用程序控制壓縮,為了保險起見,還需要判斷瀏覽器是否發送 accept-encoding: gzip 報頭,如果包含了該報頭,才執行壓縮。為了驗證壓縮前后的情況,使用 Firebug 監控請求和響應報頭。
清單 5. 壓縮前請求
GET /testProject/gzipCategory/test.html HTTP/1.1 Accept: */* Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) Host: localhost:9090 Connection: Keep-Alive
清單 6. 不壓縮的響應
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 ETag: W/"5060-1242444154000" Last-Modified: Sat, 16 May 2009 03:22:34 GMT Content-Type: text/html Content-Length: 5060 Date: Mon, 18 May 2009 12:29:49 GMT
清單 7. 壓縮后的響應
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 ETag: W/"5060-1242444154000" Last-Modified: Sat, 16 May 2009 03:22:34 GMT Content-Encoding: gzip Content-Type: text/html Content-Length: 837 Date: Mon, 18 May 2009 12:27:33 GMT
可以看到,壓縮后的數據比壓縮前數據小了很多。壓縮后的響應報頭包含 Content-Encoding: gzip。
同時 Content-Length 包含了返回數據的大小。GZIP 壓縮是一個重要的功能,前面提到的是對單一服務器的壓縮優化,在高并發的情況,多個 Tomcat 服務器之前,需要采用反向代理的技術,提高并發度,而目前比較火的反向代理是 Nginx(這在后續的文章會進行詳細的介紹)。
對 Nginx 的 HTTP 配置部分里增加如下配置。
清單 8. Nginx 的 GZIP 配置
gzip on; gzip_min_length 1000; gzip_buffers 4 8k; gzip_types text/plain application/x-javascript text/css text/html application/xml;
由于 Nginx 具有更高的性能,利用該配置可以更好的提高性能。在高性能服務器上該配置將非常有用。
預加載和懶加載,是一種改善用戶體驗的策略,它實際上并不能提高程序性能,但是卻可以明顯改善用戶體驗或減輕服務器壓力。
預加載原理是在用戶查看一張圖片時,就將下一張圖片先下載到本地,而當用戶真正訪問下一張圖片時,由于本地緩存的原因,無需從服務器端下載,從而達到提高用戶體驗的目的。為了實現預加載,我們可以實現如下的一個函數。
清單 9. 預加載函數
function preload(callback) { var imageObj = new Image(); images = new Array(); images[0]="pre_image1.jpg"; images[1]=" pre_image2.jpg"; images[2]=" pre_image3.jpg"; for(var i=0; i<=2; i++) { imageObj.src=images[i]; if (imageObj.complete) { // 如果圖片已經存在于瀏覽器緩存,直接調用回調函數 callback.call(imageObj); } else { imageObj.onload = function () {// 圖片下載完畢時異步調用 callback 函數 callback.call(imageObj);// 將回調函數的 this 替換為 Image 對象 }; } } } function callback() { alert(this.src + “已經加載完畢 , 可以在這里繼續預加載下一組圖片”); }
上面的代碼,首先定義了 Image 對象,并且聲明了需要預加載的圖像數組,然后逐一的開始加載(.src=images[i])。如果已經在緩存里,則不做其他處理;如果不在緩存,監聽 onload 事件,它會在圖片加載完畢時調用。
而懶加載則是在用戶需要的時候再加載。當一個網頁中可能同時有上百張圖片,而大部分情況下,用戶只看其中的一部分,如果同時顯示上百張,則浪費了大量帶寬資源,因此可以當用戶往下拉動滾動條時,才去請求下載被查看的圖像,這個原理與 word 的顯示策略非常類似。
在 JavaScript 中,它的基本原理是首先要有一個容器對象,容器里面是 img 元素集合。用隱藏或替換等方法,停止 img 的加載,也就是停止它去下載圖像。然后歷遍 img 元素,當元素在加載范圍內,再進行加載(也就是顯示或插入 img 標簽)。
加載范圍一般是容器的視框范圍,即瀏覽者的視覺范圍內。當容器滾動或大小改變時,再重新歷遍元素判斷。如此重復,直到所有元素都加載后就完成。當然對于開發來講,選擇已有的成熟組件,并不失為一個上策,Lazy Load Plugin for jQuery 是基于 JQuery 的懶加載組件,它有自己的官方網站。
這是一個不錯的免費插件。可以幫助程序員快速的開發懶加載應用。
Java Web 前端高性能優化(一)、(二)總結了前端性能問題定位以及圖片優化的幾種方式,將它們歸結起來,在讀者需要的時候,可以查看本文的內容,相信按照本文的方法,可以輔助讀者進行前端性能優化。
注:本文轉載自 IBM 社區,由 OneAPM 產品運營編輯整理,原文鏈接為:
http://www.ibm.com/developerworks/cn/java/j-lo-javawebhiperf1/#icomments
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65319.html
摘要:一引言前端的高性能部分,主要是指減少請求數減少傳輸的數據以及提高用戶體驗,在這個部分,圖片的優化顯得至關重要。 Web 發展的速度讓許多人嘆為觀止,層出不窮的組件、技術,只需要合理的組合、恰當的設置,就可以讓 Web 程序性能不斷飛躍。所有 Web 的思想都是通用的,它們也可以運用到 Java Web。這一系列的文章,主要講解網頁前端性能優化,是與用戶最直接接觸的。事實證明,與其消耗...
摘要:服務教程在它提出十多年后的今天,已經成為最重要的應用技術之一。全方位提升網站打開速度前端后端新的技術如何在內完整打開網站會直接影響用戶的滿意度及留存率,在前端后端數據緩存加速等等方面都有諸多可以提升。 HTTPS 原理剖析與項目場景 最近手頭有兩個項目,XX 導航和 XX 產業平臺,都需要使用 HTTPS 協議,因此,這次對 HTTPS 協議做一次整理與分享。 使用緩存應該注意哪些問題...
閱讀 3096·2021-09-28 09:42
閱讀 3448·2021-09-22 15:21
閱讀 1122·2021-07-29 13:50
閱讀 3564·2019-08-30 15:56
閱讀 3367·2019-08-30 15:54
閱讀 1196·2019-08-30 13:12
閱讀 1172·2019-08-29 17:03
閱讀 1198·2019-08-29 10:59