剝離靜態資源請求到CDNcss
通常在主域名下的HTTP請求裏都會攜帶大量Cookie信息,最大4KB,每一個域名下最多50條;但若是僅僅訪問js/css/jpeg等靜態資源文件的話是不須要Cookie信息,因此能夠將整個站點的靜態資源放到一個專門的域名下,以求減少網絡開銷,也就是Cookie free domain;html
多域名存儲資源web
瀏覽器在對同一個域名下的併發請求資源數量是有上限的(IE爲8個,chrome爲4-6個),一個完整的html頁面須要加載的資源通常已經超過100個,因此爲了縮短加載速度能夠將下載資源分佈在多個域名下(也不能太多,DNS查詢也須要耗時);這樣不只能夠增長資源加載的併發數,還能夠實現靜態資源Cookie Free加載;chrome
合併HTTP請求apache
加速網頁加載不只須要加快單個請求速度的同時,還須要減小總的請求個數,css spirites能夠將多張圖片合併成一張圖片,這樣只須要一次請求,不一樣css展現圖片上不一樣的位置;經過使用smartspirites命令在打包的時候講圖片合併成一張圖片;json
壓縮請求資源 瀏覽器
將js/css進行concat, minify和compress,最終合併成一個大的js/css,而後使用gzip生成.gz格式的文件,只要在request裏指定accept-encoding=gzip,deflate,則能夠請求打包以後的.gz文件,極大下降http請求的個數和帶寬的負載壓力。基於Ant的構建打包裏js/css的合併、混淆和壓縮能夠經過concat, closure實現,而gzip則須要client browser和web server同時約定一些規定。首先client browser發送的request要寫明accept-encoding=gzip,deflate,表示能夠接受gzip的文件編碼;而後web server將js/css文件打包成跟源文件具備一樣名字路徑的gz後綴文件,而且在response裏寫明content-encoding=gzip,這樣web server響應請求的時候就能夠返回gz文件,web browser也能夠正確對gz文件進行解析。緩存
合理利用瀏覽器cache 服務器
瀏覽器會將網頁資源cache到客戶端本地,而後經過HTTP request header裏的cache-control,expires等來控制cache的生命週期。cookie
典型的HTTP request消息頭
cache-control: no-cache cookie: _xsrf=e6552b76-a418-4409-9ec5-967573ea1cda; origin: https://zhuanlan.zhihu.com pragma: no-cache referer: https://zhuanlan.zhihu.com/c_120823325?utm_source=wechat_session&utm_medium=social&utm_oi=54126419378176 user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
典型的HTTP response消息頭
access-control-allow-credentials: true access-control-allow-origin: https://zhuanlan.zhihu.com cache-control: private, no-store, max-age=0, no-cache, must-revalidate, post-check=0, pre-check=0 content-encoding: br content-type: application/json date: Mon, 09 Jul 2018 11:39:10 GMT etag: W/"88c2b758dbbd144dc7a13a6134675430cc50ad7a" expires: Fri, 02 Jan 2000 00:00:00 GMT pragma: no-cache server: ZWS set-cookie: tgw_l7_route=ec452307db92a7f0fdb158e41da8e5d8; Expires=Mon, 09-Jul-2018 11:54:10 GMT; Path=/ status: 200
expires:web服務器響應的頭字段,表示瀏覽器在某個時間點(絕對時間點,存在服務器時區不匹配問題)以前可使用該資源的緩存;但expires字段是HTTP 1.0的定義,如今瀏覽器通常默認爲HTTP 1.1,因此它的做用基本能夠忽略。(另外一個基本能夠忽略的是pragma: no-cache,因爲其屬於html文件內容的meta信息,因此僅有某些瀏覽器支持)
cache-control:用於替換expires字段,因此優先級通常高於expires字段,cache-control的值解釋以下,max-age用的是當前時間的相對值(Cache-Control: max-age=30000)。
etag;屬於HTTP 1.1的特性,具備比last-modified更高的優先級,表示有web server根據resource的path,size, last modified date進行hash後生成的值,能夠判斷文件在前一次響應以後是否有被修改。etag能夠解決last-modified的幾個問題,last-modified只能精確到秒級別,若是剛好resource在1秒內更新了,則client browser不能根據last-modifed進行判斷;若是文件僅僅是被touch,文件內容沒有改變,last-modified卻改變了。
If-None-Match:在client browser判斷resource cache已經expire後,若是以前的response裏有etag字段,則從新發出請求並帶上該字段,web server收到請求後對比request裏的etag和web server上resource最新生成的etag值,若是不相等,則響應整個resource並設置status code = 200,不然直接返回status code=304。
Last-Modified:表示web server告訴client browser當前resource的最近修改時間。
If-Modified-Since:在client browser判斷resource cache已經expire後,若是以前的response裏有Last-Modified字段的話,則從新發出請求並帶上該字段,web server在收到請求後對比request裏的Last-Modified和web server上resource的實際的修改時間,若是實際修改時間較新,則響應整個resource並設置status code=200,不然直接返回status code=304。
使用靜態頁面
將內容變更頻次低的頁面作成靜態頁面(相對於JSP等內容須要實時生成的動態頁面),並緩存到web server內存或者CDN上,常見的技術有freemarker;JSP頁面須要依賴app server提供的容器環境,而freemarker能夠徹底脫離app server(Jetty),簡單的web server(Nginx)就能夠知足訪問需求。https://freemarker.apache.org/
直接使用freemarker合併ftl文件和data,並生成html文件,html文件能夠直接放置到CDN或者web server上供用戶訪問。
1 class App1 { 2 private static final Configuration freeMarkerConfig; 3 static { 4 freeMarkerConfig = new Configuration(Configuration.VERSION_2_3_23); 5 try { 6 freeMarkerConfig.setDefaultEncoding("UTF-8"); 7 freeMarkerConfig.setTemplateExceptionHandler( 8 TemplateExceptionHandler.RETHROW_HANDLER); 9 freeMarkerConfig.setTemplateLoader( 10 new ClassTemplateLoader(App1.class, "/template")); 11 //freeMarkerConfig.setDirectoryForTemplateLoading(dir); 12 } catch (Exception e) {} 13 } 14 public void generateHtmlByTemplate(String ftlFileName, 15 String htmlFileName, Map<String, Object> params) { 16 String dir = ""; 17 Writer fileWriter = null; 18 try { 19 File file = new File(dir + File.separator + htmlFileName); 20 Template template = freeMarkerConfig.getTemplate(ftlFileName); 21 fileWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); 22 template.process(params, fileWriter); 23 } catch (Exception e) { 24 } finally { 25 if (Objects.nonNull(fileWriter)) { 26 try { 27 fileWriter.flush(); 28 fileWriter.close(); 29 } catch (Exception e) {} 30 } 31 } 32 } 33 }