摘要:在高性能服務器上該配置將非常有用。小結(jié)前端高性能優(yōu)化一二總結(jié)了前端性能問題定位以及圖片優(yōu)化的幾種方式,將它們歸結(jié)起來,在讀者需要的時候,可以查看本文的內(nèi)容,相信按照本文的方法,可以輔助讀者進行前端性能優(yōu)化。
上回我們主要從圖片的合并、壓縮等方面介紹前端性能優(yōu)化問題(詳見Java Web 前端高性能優(yōu)化(一))
本次我們主要從圖像BASE64 編碼、GZIP壓縮、懶加載與預加載以及 OneAPM Browser Insight 的定位分析功能四個方面介紹前端優(yōu)化方法
不管如何,圖片的下載始終都要向服務器發(fā)出請求,要是圖片的下載不用向服務器發(fā)出請求,而可以隨著 HTML 的下載同時下載到本地那就太好了。而目前,瀏覽器已經(jīng)支持了該特性,我們可以將圖片數(shù)據(jù)編碼成 BASE64 的字符串,使用該字符串代替圖像地址。
假設用 S代表這個 BASE64 字符串,那么就可以使用
我們?yōu)?Connector 添加了如下幾個屬性,他們意義分別是:
compression="on" 打開壓縮功能
compressionMinSize="2048" 啟用壓縮的輸出內(nèi)容大小,這里面默認為 2KB
noCompressionUserAgents="gozilla, traviata" 對于以下的瀏覽器,不啟用壓縮
compressableMimeType="text/html,text/xml, image/png" 壓縮類型
有時候,我們無法配置 server.xml,比如如果我們只是租用了別人的空間,但是它并沒有啟用GZIP,那么我們就要使用程序啟用 GZIP 功能。我們將需要壓縮的文件,放到指定的文件夾,使用一個過濾器,過濾對這個文件夾里文件的請求。
清單 4. 自定義 Filter 壓縮 GZIP
// 監(jiān)視對 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,才執(zhí)行壓縮,目的是測試用 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 壓縮字節(jié)數(shù)組 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(); } …… }
該程序的主體思想是:在響應流寫回之前,對響應的字節(jié)數(shù)據(jù)進行 GZIP 壓縮。
因為并不是所有的瀏覽器都支持 GZIP 解壓縮,如果瀏覽器支持 GZIP 解壓縮,會在請求報頭的 Accept-Encoding 里包含 gzip。這是告訴服務器瀏覽器支持 GZIP 解壓縮,因此如果用程序控制壓縮,為了保險起見,還需要判斷瀏覽器是否發(fā)送 accept-encoding: gzip 報頭,如果包含了該報頭,才執(zhí)行壓縮。為了驗證壓縮前后的情況,使用 Firebug 監(jiān)控請求和響應報頭。
清單 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
可以看到,壓縮后的數(shù)據(jù)比壓縮前數(shù)據(jù)小了很多。壓縮后的響應報頭包含 Content-Encoding: gzip。
同時 Content-Length 包含了返回數(shù)據(jù)的大小。GZIP 壓縮是一個重要的功能,前面提到的是對單一服務器的壓縮優(yōu)化,在高并發(fā)的情況,多個 Tomcat 服務器之前,需要采用反向代理的技術(shù),提高并發(fā)度,而目前比較火的反向代理是 Nginx(這在后續(xù)的文章會進行詳細的介紹)。
對 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 具有更高的性能,利用該配置可以更好的提高性能。在高性能服務器上該配置將非常有用。
預加載和懶加載,是一種改善用戶體驗的策略,它實際上并不能提高程序性能,但是卻可以明顯改善用戶體驗或減輕服務器壓力。
預加載原理是在用戶查看一張圖片時,就將下一張圖片先下載到本地,而當用戶真正訪問下一張圖片時,由于本地緩存的原因,無需從服務器端下載,從而達到提高用戶體驗的目的。為了實現(xiàn)預加載,我們可以實現(xiàn)如下的一個函數(shù)。
清單 9. 預加載函數(shù)
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) { // 如果圖片已經(jīng)存在于瀏覽器緩存,直接調(diào)用回調(diào)函數(shù) callback.call(imageObj); } else { imageObj.onload = function () {// 圖片下載完畢時異步調(diào)用 callback 函數(shù) callback.call(imageObj);// 將回調(diào)函數(shù)的 this 替換為 Image 對象 }; } } } function callback() { alert(this.src + “已經(jīng)加載完畢 , 可以在這里繼續(xù)預加載下一組圖片”); }
上面的代碼,首先定義了 Image 對象,并且聲明了需要預加載的圖像數(shù)組,然后逐一的開始加載(.src=images[i])。如果已經(jīng)在緩存里,則不做其他處理;如果不在緩存,監(jiān)聽 onload 事件,它會在圖片加載完畢時調(diào)用。
而懶加載則是在用戶需要的時候再加載。當一個網(wǎng)頁中可能同時有上百張圖片,而大部分情況下,用戶只看其中的一部分,如果同時顯示上百張,則浪費了大量帶寬資源,因此可以當用戶往下拉動滾動條時,才去請求下載被查看的圖像,這個原理與 word 的顯示策略非常類似。
在 JavaScript 中,它的基本原理是首先要有一個容器對象,容器里面是 img 元素集合。用隱藏或替換等方法,停止 img 的加載,也就是停止它去下載圖像。然后歷遍 img 元素,當元素在加載范圍內(nèi),再進行加載(也就是顯示或插入 img 標簽)。
加載范圍一般是容器的視框范圍,即瀏覽者的視覺范圍內(nèi)。當容器滾動或大小改變時,再重新歷遍元素判斷。如此重復,直到所有元素都加載后就完成。當然對于開發(fā)來講,選擇已有的成熟組件,并不失為一個上策,Lazy Load Plugin for jQuery 是基于 JQuery 的懶加載組件,它有自己的官方網(wǎng)站。
這是一個不錯的免費插件。可以幫助程序員快速的開發(fā)懶加載應用。
Java Web 前端高性能優(yōu)化(一)、(二)總結(jié)了前端性能問題定位以及圖片優(yōu)化的幾種方式,將它們歸結(jié)起來,在讀者需要的時候,可以查看本文的內(nèi)容,相信按照本文的方法,可以輔助讀者進行前端性能優(yōu)化。
注:本文轉(zhuǎn)載自 IBM 社區(qū),由 OneAPM 產(chǎn)品運營編輯整理,原文鏈接為:
http://www.ibm.com/developerworks/cn/java/j-lo-javawebhiperf1/#icomments
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65319.html
摘要:一引言前端的高性能部分,主要是指減少請求數(shù)減少傳輸?shù)臄?shù)據(jù)以及提高用戶體驗,在這個部分,圖片的優(yōu)化顯得至關重要。 Web 發(fā)展的速度讓許多人嘆為觀止,層出不窮的組件、技術(shù),只需要合理的組合、恰當?shù)脑O置,就可以讓 Web 程序性能不斷飛躍。所有 Web 的思想都是通用的,它們也可以運用到 Java Web。這一系列的文章,主要講解網(wǎng)頁前端性能優(yōu)化,是與用戶最直接接觸的。事實證明,與其消耗...
摘要:服務教程在它提出十多年后的今天,已經(jīng)成為最重要的應用技術(shù)之一。全方位提升網(wǎng)站打開速度前端后端新的技術(shù)如何在內(nèi)完整打開網(wǎng)站會直接影響用戶的滿意度及留存率,在前端后端數(shù)據(jù)緩存加速等等方面都有諸多可以提升。 HTTPS 原理剖析與項目場景 最近手頭有兩個項目,XX 導航和 XX 產(chǎn)業(yè)平臺,都需要使用 HTTPS 協(xié)議,因此,這次對 HTTPS 協(xié)議做一次整理與分享。 使用緩存應該注意哪些問題...
摘要:服務教程在它提出十多年后的今天,已經(jīng)成為最重要的應用技術(shù)之一。全方位提升網(wǎng)站打開速度前端后端新的技術(shù)如何在內(nèi)完整打開網(wǎng)站會直接影響用戶的滿意度及留存率,在前端后端數(shù)據(jù)緩存加速等等方面都有諸多可以提升。 HTTPS 原理剖析與項目場景 最近手頭有兩個項目,XX 導航和 XX 產(chǎn)業(yè)平臺,都需要使用 HTTPS 協(xié)議,因此,這次對 HTTPS 協(xié)議做一次整理與分享。 使用緩存應該注意哪些問題...
摘要:服務教程在它提出十多年后的今天,已經(jīng)成為最重要的應用技術(shù)之一。全方位提升網(wǎng)站打開速度前端后端新的技術(shù)如何在內(nèi)完整打開網(wǎng)站會直接影響用戶的滿意度及留存率,在前端后端數(shù)據(jù)緩存加速等等方面都有諸多可以提升。 HTTPS 原理剖析與項目場景 最近手頭有兩個項目,XX 導航和 XX 產(chǎn)業(yè)平臺,都需要使用 HTTPS 協(xié)議,因此,這次對 HTTPS 協(xié)議做一次整理與分享。 使用緩存應該注意哪些問題...
閱讀 3134·2021-09-28 09:42
閱讀 3464·2021-09-22 15:21
閱讀 1136·2021-07-29 13:50
閱讀 3589·2019-08-30 15:56
閱讀 3378·2019-08-30 15:54
閱讀 1205·2019-08-30 13:12
閱讀 1188·2019-08-29 17:03
閱讀 1211·2019-08-29 10:59