本文原始碼:GitHub·點這裡 || GitEE·點這裡
一、頁面靜態化
1、動靜態頁面
靜態頁面
即靜態網頁,指已經裝載好內容HTML頁面,無需經過請求伺服器資料和編譯過程,直接載入到客戶瀏覽器上顯示出來。通俗的說就是生成獨立的HTML頁面,且不與伺服器進行資料互動。
優缺點描述:
- 靜態網頁的內容穩定,頁面載入速度極快;
- 不與伺服器互動,提升安全性;
- 靜態網頁的互動性差,資料實時性很低;
- 維度成本高,生成很多HTML頁面;
動態頁面
指跟靜態網頁相對的一種網頁程式設計技術,頁面的內容需要請求伺服器獲取,在不考慮快取的情況下,服務介面的資料變化,頁面載入的內容也會實時變化,顯示的內容卻是隨著資料庫操作的結果而動態改變的。
優缺點描述:
- 動態網頁的實時獲取資料,延遲性低;
- 依賴資料庫互動,頁面維護成本很低;
- 與資料庫實時互動,安全控制的成本高;
- 頁面載入速度十分依賴資料庫和服務的效能;
動態頁面和靜態頁面有很強的相對性,對比之下也比較好理解。
2、應用場景
動態頁面靜態化處理的應用場景非常多,例如:
- 大型網站的頭部和底部,靜態化之後統一載入;
- 媒體網站,內容經過渲染,直接轉為HTML網頁;
- 高併發下,CDN邊緣節點代理的靜態網頁;
- 電商網站中,複雜的產品詳情頁處理;
靜態化技術的根本:提示服務的響應速度,或者說使響應節點提前,如一般的流程,頁面(客戶端)請求服務,服務處理,響應資料,頁面裝載,一系列流程走下來不僅複雜,而且耗時,如果基於靜態化技術處理之後,直接載入靜態頁面,好了請求結束。
二、流程分析
靜態頁面轉換是一個相對複雜的過程,其中核心流程如下:
- 開發一個頁面模板,即靜態網頁樣式;
- 提供介面,給頁面模板獲取資料;
- 頁面模板中編寫資料介面返參的解析流程;
- 基於解析引擎,把資料和頁面模板合併;
- 頁面模板內容載入完成後轉換為HTML靜態頁面;
- HTML靜態頁面上傳到檔案伺服器;
- 客戶端(Client)獲取靜態頁面的url載入顯示;
主流程大致如上,如果資料介面響應引數有變,則需要重新生成靜態頁,所以在資料的載入實時性上面會低很多。
三、程式碼實現案例
1、基礎依賴
FreeMarker是一款模板引擎:即一種基於模板和要改變的資料,並用來生成輸出文字(HTML網頁、電子郵件、配置檔案、原始碼等)的通用工具。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2、頁面模板
這裡既使用FreeMarker開發的模板樣式。
<html>
<head>
<title>PageStatic</title>
</head>
<body>
主題:${myTitle}<br/>
<#assign text="{'auth':'cicada','date':'2020-07-16'}" />
<#assign data=text?eval />
作者:${data.auth} 日期:${data.date}<br/>
<table class="table table-striped table-hover table-bordered" id="editable-sample">
<thead>
<tr>
<th>規格描述</th>
<th>產品詳情</th>
</tr>
</thead>
<tbody>
<#list tableList as info>
<tr class="">
<td>${info.desc}</td>
<td><img src="${info.imgUrl}" height="80" width="80"></td>
</tr>
</#list>
</tbody>
</table><br/>
<#list imgList as imgIF>
<img src="${imgIF}" height="300" width="500">
</#list>
</body>
</html>
FreeMarker的語法和原有的HTML語法基本一致,但是具有一套自己的資料處理標籤,用起來不算複雜。
3、解析過程
通過解析,把頁面模板和資料介面的資料合併到一起即可。
@Service
public class PageServiceImpl implements PageService {
private static final Logger LOGGER = LoggerFactory.getLogger(PageServiceImpl.class) ;
private static final String PATH = "/templates/" ;
@Override
public void ftlToHtml() throws Exception {
// 建立配置類
Configuration configuration = new Configuration(Configuration.getVersion());
// 設定模板路徑
String classpath = this.getClass().getResource("/").getPath();
configuration.setDirectoryForTemplateLoading(new File(classpath + PATH));
// 載入模板
Template template = configuration.getTemplate("my-page.ftl");
// 資料模型
Map<String, Object> map = new HashMap<>();
map.put("myTitle", "頁面靜態化(PageStatic)");
map.put("tableList",getList()) ;
map.put("imgList",getImgList()) ;
// 靜態化頁面內容
String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
LOGGER.info("content:{}",content);
InputStream inputStream = IOUtils.toInputStream(content,"UTF-8");
// 輸出檔案
FileOutputStream fileOutputStream = new FileOutputStream(new File("F:/page/newPage.html"));
IOUtils.copy(inputStream, fileOutputStream);
// 關閉流
inputStream.close();
fileOutputStream.close();
}
private List<TableInfo> getList (){
List<TableInfo> tableInfoList = new ArrayList<>() ;
tableInfoList.add(new TableInfo(Constant.desc1, Constant.img01));
tableInfoList.add(new TableInfo(Constant.desc2,Constant.img02));
return tableInfoList ;
}
private List<String> getImgList (){
List<String> imgList = new ArrayList<>() ;
imgList.add(Constant.img02) ;
imgList.add(Constant.img02) ;
return imgList ;
}
}
生成後的HTML頁面直接使用瀏覽器開啟即可,不再需要依賴任何資料介面服務。
四、原始碼地址
GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent
推薦閱讀:微服務架構系列