因?yàn)镠5的存在可以快速發(fā)布,不受審核影響的特點(diǎn)痛倚。目前存在很多公司,對(duì)于一些嘗試性的功能澜躺,會(huì)優(yōu)先采用H5來實(shí)現(xiàn)蝉稳。甚至有些公司為了節(jié)省用人成本,直接在原生APP的殼子里完全嵌入H5頁面掘鄙。但是H5的體驗(yàn)比起原生來還是差了挺多的耘戚,那么怎么優(yōu)化就成為一個(gè)需要解決的問題了。
首先操漠,要先研究一下為啥H5的體檢比較差收津,只有知道問題所在,才能更好的解決問題浊伙。H5頁面給人直觀上的感覺的就是加載的速度太慢撞秋,常常存在一段時(shí)間的空白情況。
那么為啥會(huì)存在這樣的情況的嚣鄙,我們可以了解一下吻贿,H5的加載過程干了些啥東西。
初始化 webview -> 請(qǐng)求頁面 -> 下載數(shù)據(jù) -> 解析HTML -> 請(qǐng)求 js/css 資源 -> dom 渲染 -> 解析 JS 執(zhí)行 -> JS 請(qǐng)求數(shù)據(jù) -> 解析渲染 -> 下載渲染圖片
哇塞哑子,好大一堆事情舅列,辛苦了。那么那些方面我們可以進(jìn)行優(yōu)化呢卧蜓,這里就得看看為了解決這個(gè)問題而掉光頭發(fā)的老前輩們的想法了剧蹂。
- 降低請(qǐng)求量:合并資源,減少 HTTP 請(qǐng)求數(shù)烦却,minify / gzip 壓縮宠叼,webP,lazyLoad其爵。
- 加快請(qǐng)求速度:預(yù)解析DNS冒冬,減少域名數(shù),并行加載摩渺,CDN 分發(fā)简烤。
- 緩存:HTTP 協(xié)議緩存請(qǐng)求,離線緩存 manifest摇幻,離線數(shù)據(jù)緩存 localStorage横侦。
- 渲染:JS/CSS優(yōu)化挥萌,加載順序,服務(wù)端渲染模板直出枉侧。
方法很多引瀑,本文就介紹的方法就是要怎么減少網(wǎng)絡(luò)請(qǐng)求從而提升H5的加載速度。
存在原生開發(fā)經(jīng)驗(yàn)的同志都知道 WebView 加載H5的方式存在兩種榨馁,一種是加載HTMLString憨栽,而另外一種就是加載url地址嘍。本文就從這兩方面來解讀翼虫。
加載HTMLString
先奉上代碼再做解釋屑柔。
let htmlContent = "<p>我們都知道有些食物能治病,但如果吃不對(duì)珍剑,它們也能致病掸宛。有些食物,對(duì)于我們一般人來說招拙,有著滋補(bǔ)的功效唧瘾,但是對(duì)于高血壓患者,它們最好別碰迫像!<span >高血壓的“三大殺手”</span></p><h1>1劈愚、韭 菜</h1><p>韭菜也具有發(fā)散性瞳遍,有溫腎助陽的功效闻妓。而大多數(shù)高血壓患者屬于陰虛體質(zhì),燥熱掠械、陽火過盛由缆,多吃韭菜不但不利于血壓控制,反而會(huì)加重病情猾蒂。</p><p>2均唉、豬 肝</span></p><p>豬肝中膽固醇含量很高甸昏,患有高血壓减江、冠心病像屋、肥胖癥及血脂高的人忌食豬肝蛇受。</p><p><span >3趾牧、雞 湯</span></p><p>雞湯的營養(yǎng)價(jià)值很高涨醋,而多喝雞湯又會(huì)使膽固醇和血壓增高果善。因此都办,雞湯不能盲目地作為病人的營養(yǎng)品烙荷,特別是患有高血壓的人镜会,不宜喝雞湯。否則只會(huì)進(jìn)一步加重病情终抽,對(duì)身體有害無益戳表。</p><p><br></p><blockquote> <span >除了上面三種美食桶至,下面這些東西高血壓患者也要少碰。</span></blockquote><p><span >1匾旭、味 精</span></p><p>研究表明镣屹,味精的主要成分是谷氨酸鈉,如果平時(shí)鈉的含量已經(jīng)達(dá)到閾值季率,再多吃味精野瘦,顯然會(huì)增高鈉的攝入量,從而不利于高血壓的控制飒泻。</p><p><span >2鞭光、“隱 形 鹽”</span></p><p>醬油、黃醬泞遗、腐乳等調(diào)味脂高的人忌食豬肝惰许。</p><p><span >3、雞 湯</span></p><p>雞湯的營養(yǎng)價(jià)值很高史辙,而多喝雞湯又會(huì)使膽固醇和血壓增高汹买。因此,雞湯不能盲目地作為病人的營養(yǎng)品聊倔,特別是患有高血壓的人晦毙,不宜喝雞湯。否則只會(huì)進(jìn)一步加重病情耙蔑,對(duì)身體有害無益见妒。</p><p><br></p><blockquote> <span >除了上面三種美食,下面這些東西高血壓患者也要少碰甸陌。</span></blockquote><p><span >1须揣、味 精</span></p><p>研究表明,味精的主要成分是谷氨酸鈉钱豁,如果平時(shí)鈉的含量已經(jīng)達(dá)到閾值耻卡,再多吃味精,顯然會(huì)增高鈉的攝入量牲尺,從而不利于高血壓的控制卵酪。</p><p><span >2、“隱 形 鹽”</span></p><p>醬油谤碳、黃醬溃卡、腐乳等調(diào)味\\345\\223品含鹽量高;臘肉估蹄、奶酪塑煎、火腿、榨菜也都含鹽臭蚁;話梅最铁、薯片讯赏、椒鹽花生等零食均是含鹽食物。買食品時(shí)看下食品包裝上的營養(yǎng)成分表冷尉,“NRV%”超過30%就要少買少吃漱挎。</p><p><br></p><p><span >3、濃 茶</span></p><p>高血壓病患者忌飲濃茶雀哨,尤其是忌飲濃烈紅茶磕谅。因?yàn)榧t茶中所含的茶堿最高,可以引起大腦興奮雾棺、不安膊夹、失眠、心悸等不適捌浩,從而使血壓上升放刨。</p><p><span >4、飲 酒</span></p><p>研究表明尸饺,飲酒在一般情況下會(huì)讓血壓升高4到8毫米汞柱进统。大量、長期飲酒浪听,更易誘發(fā)動(dòng)脈硬化螟碎,加重高血壓。因此迹栓,高血壓患者應(yīng)戒酒掉分。</p><p>5、吸 煙</span></p><p>香煙中的尼古丁迈螟,能刺激心臟和血管叉抡,使血壓升高尔崔,加速動(dòng)脈粥樣硬化的形成答毫。高血壓被稱為“安靜的殺手”,患病后可能沒有癥狀季春,而大多數(shù)患者可能只有到體檢的那天才知道自己得了高血壓洗搂。</p><blockquote> <span >幫你“穩(wěn)住”血壓</span></blockquote><p><span >1、定期監(jiān)測血壓</span></p><p>家庭自測血壓正常值應(yīng)小于135/85毫米汞柱载弄,非同一天測量耘拇、3次超標(biāo)需及時(shí)就醫(yī)。</p><p><br></p><p><span >2宇攻、清淡飲食</span></p><p>飲食上不要大魚大肉惫叛,注意清淡一些,每天鹽攝入量控制在6克以下逞刷,吃油量在25~30克之間嘉涌。豬肉等紅肉妻熊、高鹽的腌制食品應(yīng)限量,甜食和糖果盡量不吃仑最。</p><p><span >3扔役、控制體重</span></p><p>體質(zhì)指數(shù)【BMI=體重(千克)÷身高的平方(米的平方)】盡可能保持在19~24之間。</p><p><span >4警医、補(bǔ)點(diǎn)鉀</span></p><p>適當(dāng)吃些鉀含量較高的食物有助于降低血壓亿胸,還能降低高血壓患者發(fā)生中風(fēng)的風(fēng)險(xiǎn)。建議多吃香蕉预皇、桃子侈玄、西瓜、紅薯吟温、菠菜拗馒、芹菜、土豆等溯街。</p><p><span >5诱桂、增加鎂、鈣的攝入</span></p><p>鎂有助于血管擴(kuò)張呈昔,補(bǔ)充鎂的最安全方法是通過含鎂豐富的食物來補(bǔ)充挥等。富含鎂的食物有各種干豆、鮮豆堤尾、香菇肝劲、菠菜、桂圓郭宝、豆芽等辞槐。鈣不足也可使血壓升高,鈣增加會(huì)使血壓下降粘室。富含鈣的食物有奶類榄檬、豆類等。</p><p><span >6衔统、吃點(diǎn)醋</span></p><p>醋是通過抑制血管緊張素轉(zhuǎn)換酶生成而直接抑制血壓升高的鹿榜。醋還具有利尿作用和有利于身體對(duì)鈣的吸收,這些作用對(duì)降低血壓有一定幫助锦爵。</p><p><span >7舱殿、抽空多走走</span></p><p>慢走5分鐘、散步5分鐘交替進(jìn)行险掀,可軟化血管沪袭。建議利用零散時(shí)間鍛煉,如出門少開車樟氢,多步行一會(huì)冈绊;養(yǎng)成晚飯后溜達(dá)一圈的習(xí)慣创倔。</p><p><br></p><blockquote> <span >喝喝茶調(diào)血壓</span></blockquote><p><span >葛 根 茶</span></p><p>葛根具有改善腦部血液循環(huán)之效,對(duì)因高血壓引起的頭痛焚碌、眩暈畦攘、耳鳴及腰酸腿痛等癥狀有較好的緩解功效。經(jīng)常飲用葛根茶對(duì)治療高血壓具有明顯的療效十电。</p><p>做法:將葛根洗凈切成薄片知押,每天30克,加水煮沸后當(dāng)茶飲用鹃骂。</p><p><span >蓮子心茶</span></p><p>蓮子心其味清苦台盯,可以祛五臟之火,具有極好的降壓去脂的功效畏线。</p><p>做法:取蓮子心12克静盅,開水沖泡代茶飲,每天早晚各1次寝殴。</p><p><span >高血壓是個(gè)終身性疾病蒿叠,需要終身用藥控制。但是除合理用藥外蚣常,健康的生活方式必不可少市咽。合理膳食、適量運(yùn)動(dòng)抵蚊、戒煙限酒及心理健康施绎,才是人類健康的四大基石。</span></p>"
//加載遠(yuǎn)程css 依賴網(wǎng)絡(luò)速度
let string = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0,user-scalable=no\"><meta content=\"yes\" name=\"apple-mobile-web-app-capable\"><meta content=\"yes\" name=\"apple-touch-fullscreen\"><meta name=\"format-detection\" content=\"telephone=no\"><link href=\"https://app.h5.ihaozhuo.com/lib/css/newscss.css\" rel=\"stylesheet\"></head><body>\(htmlContent)</body></html>"
self.webView.loadHTMLString(string, baseURL: nil)
//加載本地css
let link:String = Bundle.main.url(forResource: "newscss", withExtension: "css")!.absoluteString
let baseUrl = URL.init(fileURLWithPath: "file:///assets/")
let string = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0,user-scalable=no\"><meta content=\"yes\" name=\"apple-mobile-web-app-capable\"><meta content=\"yes\" name=\"apple-touch-fullscreen\"><meta name=\"format-detection\" content=\"telephone=no\"><link href=\"" + link + "\" rel=\"stylesheet\"></head><body>\(htmlContent)</body></html>"
self.webView.loadHTMLString(string, baseURL: baseUrl)
代碼挺簡單的贞绳,看文章的小伙伴應(yīng)該都能理解谷醉,其中主要區(qū)別就是這兩句話,
//資源為網(wǎng)絡(luò)路徑
<link href=\"https://app.h5.ihaozhuo.com/lib/css/newscss.css\" rel=\"stylesheet\">
//資源為本地路徑
<link href=\"" + link + "\" rel=\"stylesheet\">
可能有些小伙伴冈闭,加載本地資源不成功俱尼,其中需要兩個(gè)點(diǎn)要注意:
1、就是需要設(shè)置baseURL拒秘。
2号显、baseUrl 可以寫的我代碼中完全一樣臭猜,另外.css文件需要和webview在同級(jí)目錄躺酒。
加載url地址
上面的那種加載H5的方法很簡單粗暴,只需要替換網(wǎng)絡(luò)連接為本地連接就好啦蔑歌,但是我們項(xiàng)目實(shí)戰(zhàn)中通過加載url地址的方式其實(shí)更常見些羹应。這時(shí)候我們改怎么處理呢?修改資源為本地路徑就別想啦次屠,想破腦袋园匹、查遍資料發(fā)現(xiàn)了這個(gè)好東西 WKURLSchemeHandler雳刺。不過這個(gè)東西在 iOS 11之后才有支持,不過iOS系統(tǒng)的更新占比完全不用擔(dān)心的裸违,直接搞起來掖桦。(可以通過添加 user-agent 來區(qū)分是否用指定的協(xié)議,H5遇到這個(gè)標(biāo)識(shí)就使用customScheme,否則就是用原來的http或https)
先看看代碼怎么寫:
let configuration = WKWebViewConfiguration.init();
//這里是個(gè)注意點(diǎn) yjkCustomScheme 這個(gè)玩意兒就是和H5約定的規(guī)則哦供汛,H5加載的資源用這個(gè)作為協(xié)議就好啦
configuration.setURLSchemeHandler(CustomURLSchemeHandler.init(), forURLScheme: "yjkCustomScheme")
webView = WKWebView.init(frame: CGRect.init(x: 0, y: 0, width: view.frame.width, height: view.frame.height), configuration: configuration)
webView.scrollView.decelerationRate = UIScrollView.DecelerationRate.normal
webView.navigationDelegate = self
self.view.addSubview(webView)
//***加載H5的地址就應(yīng)該使用這個(gè)規(guī)則來加載枪汪,不然直接加載https的地址是無法進(jìn)行攔截的
webView.load(URLRequest.init(url: URL.init(string: "yjkCustomScheme://app.h5.ihaozhuo.com/native/yjkdemo/index.html?v=6")!))
處理代理的完整代碼:
//攔截類
class CustomURLSchemeHandler: NSObject {
}
extension CustomURLSchemeHandler:WKURLSchemeHandler{
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
//文件名
let fileName = urlSchemeTask.request.url?.lastPathComponent
//文件擴(kuò)展名(文件類型)
let pathExtension = urlSchemeTask.request.url?.pathExtension
//獲取本地資源
let fileURL = Bundle.main.url(forResource: fileName?.components(separatedBy: ".").first, withExtension: pathExtension)
//本地存在文件
if fileURL != nil{
//獲取本地資源異常
do {
//返回本地?cái)?shù)據(jù)
let data:NSData = try Data.init(contentsOf: fileURL!) as NSData
let pathExtension = fileURL!.pathExtension
let mime = mimeType(forPathExtension: pathExtension)
let response:URLResponse = URLResponse.init(url: urlSchemeTask.request.url!, mimeType: mime, expectedContentLength: data.length, textEncodingName: nil)
urlSchemeTask.didReceive(response)
urlSchemeTask.didReceive(data as Data)
urlSchemeTask.didFinish()
}catch {
//本地資源獲取異常
requestWebViewData(urlSchemeTask: urlSchemeTask)
}
}else{
//無本地資源
requestWebViewData(urlSchemeTask: urlSchemeTask)
}
}
func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
}
/// 代替H5發(fā)出網(wǎng)絡(luò)請(qǐng)求
///
/// - Parameter urlSchemeTask:
private func requestWebViewData(urlSchemeTask: WKURLSchemeTask){
let schemeUrl:String = urlSchemeTask.request.url?.absoluteString ?? "" //***這個(gè)搞過來好像都是小寫的
//換成原始的請(qǐng)求地址
let replacedStr = schemeUrl.replacingOccurrences(of: "yjkcustomscheme", with: "https")
//發(fā)出請(qǐng)求結(jié)果返回
let request = URLRequest.init(url: URL.init(string: replacedStr)!)
let config = URLSessionConfiguration.default
let session = URLSession.init(configuration: config)
let dataTask = session.dataTask(with: request) { (data:Data?, response:URLResponse?, error:Error?) in
if error != nil{
urlSchemeTask.didFailWithError(error!)
}else{
urlSchemeTask.didReceive(response!)
urlSchemeTask.didReceive(data!)
urlSchemeTask.didFinish()
}
}
dataTask.resume()
}
/// 獲取文件類型
///
/// - Parameter pathExtension:
/// - Returns:
private func mimeType(forPathExtension pathExtension: String) -> String {
if
let id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue(),
let contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue()
{
return contentType as String
}
return "application/octet-stream"
}
}
所有代碼都在上面了,不多嗶嗶了怔昨。主要思想就是攔截掉H5發(fā)出去的請(qǐng)求雀久,返回給他本地?cái)?shù)據(jù),從而減少H5網(wǎng)絡(luò)請(qǐng)求的時(shí)長趁舀。
最后要說的就是這幾點(diǎn):
1赖捌、目前影響H5體驗(yàn)的主要因素就是網(wǎng)絡(luò)請(qǐng)求的速度,在5G高速發(fā)展的今天矮烹,H5勢(shì)必會(huì)成為將來發(fā)展的大趨勢(shì)越庇。
2、通過實(shí)測加載HTMLString比加載url的速度確實(shí)要快很多奉狈。因此悦荒,能通過后臺(tái)返回Html標(biāo)簽的,盡量就使用Html標(biāo)簽嘹吨。
3搬味、本文只是介紹一個(gè)思路,要想完整應(yīng)用的項(xiàng)目中蟀拷,還是要做一些列的工作的碰纬。比如肯定是需要一個(gè)版本管理的機(jī)制的。
參考文章:
iOS WKWebView 加載本地HTML问芬、CSS悦析、JS文件
iOS app秒開H5優(yōu)化總結(jié)
移動(dòng)端本地 H5 秒開方案探索與實(shí)現(xiàn)