UIWebView可能的優化方案

聲明:Socket思想來源于手Q空間團隊,Demo中提供了使用Socket模擬HTTP請求. 本文最初發布在mekor.github.io

我們都知道WebView加載頁面非常緩慢,如果頁面樣式結構比較固定,則可以采用自己的自己封裝的網絡請求去獲取數據,然后拼接成HTML顯示.

優點:

  • 通常webview首次加載非常慢,使用Native網絡請求會很快
  • 離線包+預加載(靜態HTML、靜態JS、靜態CSS它們的加載、它們離線的東西),首屏進入可直接加載默認數據

缺點:

  • 靜態資源包離線下載,不能保證100%

傳統H5加載流程

14737415611533.jpg

這里有兩個問題:

WebView的耗時
根據手Q的統計數據,Android的WebView平均打開啟動的速度耗時是0.8秒,有些Android機型基于系統環境可能需要一點多或者兩秒左右;

HTTP協議的網絡層
HTTP有DNS或者建立鏈接的耗時,HTTPS有建立SSL鏈接的耗時。

所以H5通常帶給用戶的體驗是:我點進來不管是怎么時候,是第一次第二次還是第三次,我點進來先等兩秒再說,看兩秒白屏后頁面才可以加載進來,其實這里我們只做了兩個事情去優化首次加載流程:

1. 把WebView啟動和發送請求改成并行

客戶端在啟動WebView的時候同時發起HTML的頁面請求,這里可以實現一個效果:本來我的耗時是T1+T2,現在為T1或T2的最大值,這樣達到并行加載的效果。

14737420748297.jpg

當然這里還有一個優化的空間,我們其實已經由客戶端接管了發送網絡請求的事情,以前接管的時候是用HTTP協議,比如像iOS用的是URLSession模塊,但已經讓客戶端接管了,為什么不能夠更大膽一些呢?

2. Socket通道

其實我們可以不拘泥于數據傳輸的方式,所以這里我們把一個HTML的加載從HTTP/HTTPS改造成了一個Socket通道,這是一個App里面長連接的管道,如果手機內部有即時通訊模塊的話,我們是用這個長連接的通道來做HTML的傳輸的,它的作用在于只要你的手機QQ能夠收發消息,你的HTML頁面就能夠加載進來,這樣就達到體驗上的一致性,同時網絡也有比較穩定的提升。

![Uploading 14737426997041_567885.jpg . . .]

我們基本上做了兩個事情就達到首次進入加速的目的,但后面才是一個關鍵:首次進入我們已經做過優化了,但二次進入怎么去做優化去提高它的顯示速度呢?

本地緩存

14737426997041.jpg

Demo簡單介紹

關于加載優化Demo,地址:https://github.com/Mekor/Optimization-of-webView

webView加載耗時問題解決方案簡介:

  1. 如果有界面變動不大,可以吧HTML直接在本地存放一份,然后從網上請求數據,拼接成HTML,這樣加載速度會很快.這種可以參考用戶版商品的圖片簡介.
  2. 如果內部動態變化的,但是樣式和交互式規定好的,可以在本地存放一份,當然也可以每次啟動app的時候更新本地存放的靜態資源.這樣的好處就是每次只替換更新的內容.

下面以網易新聞為例,這里我抓包網易新聞的請求,新聞詳情: http://c.m.163.com/nc/article/C0OBRVC7051789DB/full.html
這里我們可以看出,網易新聞也不是直接用webView加載url的方式顯示的.

{
    "C0OBRVC7051789DB": {
        "body": "<p>  郭德綱的成功除了自身堅持不懈的努力外,當然也因郭德綱遇到了不少“貴人”的幫助,在這其中有一位也是其“貴人”,郭德綱曾經也在很多場合說其是自己的貴人,他就是大鵬。</p><!--IMG#0--><p>  不過,此大鵬非彼大鵬。如今一說到大鵬,都會想到導演電影《煎餅俠》的大鵬,那是趙本山的弟子,卻和郭德綱沒有什么關系。而幫助過郭德綱,使得其相聲在北京能廣受歡迎的大鵬,則是北京文藝廣播《開心茶館》主持人康大鵬。</p><!--IMG#1--><p>  康大鵬作為電臺節目主持人,在沒有聽到郭德綱相聲之前,給聽眾播放的也是一些經典的相聲段子,不過翻來覆去時間長了也令聽眾生厭,久而久之就沒有了興趣。在這種情況下,大鵬聽了郭德綱的相聲后,才感到眼前一亮。</p><!--IMG#2--><p>  當時的郭德綱,雖然在北京也開始站住了腳跟,但是僅限于小部分觀眾知道,并且據說還備受各方打擊,所以才會在相聲中經常有“怨言”。在大鵬看了德云社郭德綱的相聲后,認為這是個機會,德云社也需要聽眾,也需要幫助。</p><!--IMG#3--><p>  于是,大鵬就開始到德云社錄音,然后播放給聽眾聽。這在當時,也是一個不小的舉動。畢竟郭德綱在當時還名不見經傳,而為郭德綱錄音還需要大鵬自己掏腰包購買錄音器材,至于播出后效果如何也擔有一定風險。</p><!--IMG#4--><p>  也正如大鵬所想象,郭德綱的相聲在電臺播出后便反響強烈,使得很多觀眾都開始迷上了相聲,也迷上了郭德綱。在擁有了大批粉絲后,據說郭德綱隨后開辦了一場大型紀念演出,當時有不少電視臺和電臺的領導觀看,而在郭德綱相聲結束后,大鵬還給臺下領導來了一個驚人的一跪。</p><!--IMG#5--><p>  雖然只是單膝點地,但在當時的報紙也給出了驚天一跪的標題,而大鵬的這一跪,也使得郭德綱和電視臺結緣。盡管郭德綱的成名和大鵬有著不可分割的關系,但大鵬還是很謙虛的說兩者是相互的關系,因為節目需要聽眾。</p><!--IMG#6--><p>  在郭德綱進入北京電視臺主持《星夜故事秀》節目時,這也是郭德綱和北京電視臺合作最好的時期,堪稱兩者的“蜜月期”。只是隨著郭德綱的成名,郭德綱后來又轉戰到了天津衛視,自己在北京電視臺的節目則交給了何云偉和李菁來做。</p><!--IMG#7--><p>  這其中的原因,有人說是因為報酬方面產生了分歧,說白了其他電視臺給了更高的價錢。所以北京電視臺才會批郭德綱“忘恩負義”,因北京電視臺為郭德綱的宣傳做了很大的努力,但也有人說是因郭德綱的加盟,才使得北京電視臺節目火了起來。誰是誰非莫衷一是。</p><!--IMG#8--><p>  至于后來,兩者鬧得更是不可開交,直到最后變成了“冤家”。而和北京電視臺鬧分裂后,對原電臺主持人大鵬自然也是有很大的影響,畢竟電視臺和電臺也是一脈相承的關系,不可能不對大鵬產生影響。</p><!--IMG#9--><p>  對與錯是與非都是難以說清,正如大鵬所說,郭德綱的相聲給其節目帶來了聽眾,而電臺也給郭德綱帶去了名氣,兩者也是相輔相成。但不管怎樣,大鵬的確是郭德綱演藝路上的一位“恩人”,起碼讓其早點脫穎而出揚眉吐氣了。</p><p> 特別聲明:本文為網易自媒體平臺“網易號”作者上傳并發布,僅代表該作者觀點。網易僅提供信息發布平臺。</p>",
        "users": [],
        "replyCount": 1893,
        "ydbaike": [],
        "link": [],
        "shareLink": "http://c.m.163.com/news/a/C0OBRVC7051789DB.html?spss=newsapp&spsw=1",
        "votes": [],
        "img": [
            {
                "ref": "<!--IMG#0-->",
                "pixel": "400*263",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/s9VWjHPwFtTeqKoYJBULaIbs5TmzcYeGFQeljU0IFvZrD1473633706236.jpg"
            },
            {
                "ref": "<!--IMG#1-->",
                "pixel": "412*256",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/6DXnTuxZs2jvgFJLMW2svrKoh1=KTYXhGwGUH2JlqdpZq1473633736663.jpg"
            },
            {
                "ref": "<!--IMG#2-->",
                "pixel": "380*246",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/H5jHhCfSD5uhRhMFrHwze4LgrK97qwcG1GkwWGRZcOeqe1473633752645.jpg"
            },
            {
                "ref": "<!--IMG#3-->",
                "pixel": "360*286",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/udjNFCksz6Fc7fCFAzCBwzUYxWB1TJUVis97X5ZRHpqg61473633775305.jpg"
            },
            {
                "ref": "<!--IMG#4-->",
                "pixel": "407*255",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/7mbZrlli2D70eS9WHoRmd54RDkr6onqv8Zl1h6V5zJraj1473633824123compressflag.jpg"
            },
            {
                "ref": "<!--IMG#5-->",
                "pixel": "400*266",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/HVmr=qRm5YReXaRAJBcSaI6WJpMn6DkKHJIVJBdbqMOYY1473633850729compressflag.jpg"
            },
            {
                "ref": "<!--IMG#6-->",
                "pixel": "380*232",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/HQUW=i7soYmJqlUDaS1iv6pGBI9NzCdFqYU=yC=QT8BDQ1473633896632.jpg"
            },
            {
                "ref": "<!--IMG#7-->",
                "pixel": "294*220",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/lEs43YivpKRxQqZPlmaIo=SpEOdRTqeYUywHCLqwIqR111473633914904.jpg"
            },
            {
                "ref": "<!--IMG#8-->",
                "pixel": "402*238",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/bhzvrmx8JUQHVViXI5VKqvHG=c5RIIxx0dssbfTNM7mfE1473633962043.jpg"
            },
            {
                "ref": "<!--IMG#9-->",
                "pixel": "329*220",
                "alt": "",
                "src": "http://dingyue.nosdn.127.net/tN7dLuyOJ0SU3kXoPRrLdXkVMZGJtiS97Qh46opqH2Q0N1473634186617.jpg"
            }
        ],
        "digest": "",
        "topiclist_news": [],
        "dkeys": "null",
        "topiclist": [
            {
                "hasCover": false,
                "subnum": "2.8萬",
                "alias": "娛樂八卦、影視評論",
                "tname": "娛樂大嘴",
                "ename": "T1439876075818",
                "tid": "T1439876075818",
                "cid": "C1374475306828"
            }
        ],
        "docid": "C0OBRVC7051789DB",
        "picnews": true,
        "title": "郭德綱從他的節目走紅 此“貴人”卻不求回報",
        "sourceinfo": {
            "alias": "娛樂八卦、影視評論",
            "ename": "T1439876075818",
            "tname": "娛樂大嘴",
            "tid": "T1439876075818"
        },
        "tid": "",
        "template": "normal1",
        "threadVote": 108,
        "askbar": [
            {
                "title": "主持人",
                "headpicurl": "http://dingyue.nosdn.127.net/27vmGgL=A4BbmMAUJIEOEJ2vUlnvIGE9Ufum0roxEDigT1472456332076.jpg",
                "alias": " 我是河北交通廣播主持人月色,關于主持、情感和各種天馬行空的問題,問我吧! ",
                "expertId": "EX880112773195081120",
                "name": "月色",
                "concernCount": 6341
            }
        ],
        "threadAgainst": 49,
        "boboList": [],
        "articleTags": "網易號",
        "replyBoard": "dy_wemedia_bbs",
        "source": "娛樂大嘴",
        "huati": [
            {
                "topicId": "SJ02345751487819348812",
                "topicName": "郭德綱"
            },
            {
                "topicId": "SJ1851570047893940154",
                "topicName": "趙本山"
            }
        ],
        "hasNext": false,
        "voicecomment": "off",
        "apps": [],
        "relative_sys": [
            {
                "id": "C0RN7O7N00034VR2",
                "title": "郭德綱的綜藝版圖:交人脈、捧新人、強化德云IP",
                "source": "網易娛樂專稿",
                "imgsrc": "http://cms-bucket.nosdn.127.net/a11079eb004f445abdb7146850e4810d20160913141047.jpeg",
                "docID": "C0RN7O7N00034VR2",
                "from": "HZ",
                "type": "doc",
                "ptime": "2016-09-13 14:13:21",
                "href": ""
            },
            {
                "id": "C0DBP4LV0517ACQ1",
                "title": "老梁說天下:郭德綱為什么這么能“惹事兒”",
                "source": "縱橫娛樂",
                "imgsrc": "http://dingyue.nosdn.127.net/sYo3zfohiqrXHHZIhYV0wqZTpE7RavK7qWneE4BsRH6O=1473265404780compressflag.png",
                "docID": "C0DBP4LV0517ACQ1",
                "from": "HZ",
                "type": "doc",
                "ptime": "2016-09-08 00:23:46",
                "href": ""
            },
            {
                "id": "C0R1QGIN051789DB",
                "title": "唯一被戲稱德云社第一女弟子女星,卻是郭德綱鐵桿粉絲",
                "source": "娛樂大嘴",
                "imgsrc": "http://dingyue.nosdn.127.net/I=T7AyADVhb6T8KiCoR0Yw0mKqBXyzUNKWyafBy9PRvxF1473724249899.jpg",
                "docID": "C0R1QGIN051789DB",
                "from": "HZ",
                "type": "doc",
                "ptime": "2016-09-13 08:01:08",
                "href": ""
            }
        ],
        "ptime": "2016-09-12 06:59:42"
    }
}

我們可以看出, body 里面是配置好的html,同時里面也給出了圖片占位符類似于 ``,通過 img 數組里面的的內容進行替換,img里面提供類似

{
    "ref": "<!--IMG#0-->", 
    "pixel": "400*263", 
    "alt": "", 
    "src": "http://dingyue.nosdn.127.net/s9VWjHPwFtTeqKoYJBULaIbs5TmzcYeGFQeljU0IFvZrD1473633706236.jpg"
},

提供了 body 里面的占位符,同時還提供了,pixel,alt,src等.這時我們可以做的事情就多了,根據占位符替換 body 中的占位,通過原生網絡下載圖片等等.Demo中我只做了簡單的HTML拼接.拼接好HTML在把本地的模板添加進去,比如css,js等.最后直接把拼接好的完整的HTML給webView,讓其顯示.具體Demo已經提供了,僅供參考.效果圖:

14738361521187.gif

(僅供參考,css我只是簡單的按照大概寫的,勿噴)

Socket模擬HTTP請求

第二個Demo中模擬了Socket發送HTTP請求的方式,當然我這里只是猜測手Q的實現方式.需要注意的地方就是拼接請求頭.

    //拼接http請求
    NSString *request = @"GET / HTTP/1.1\n"
    "Connection: Close\n"
    "Host: m.baidu.com\n"
    //告訴服務器客戶端是mac
    "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36\n\n";
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,076評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,200評論 4 61
  • 師德,是作為教師的我們每個個體所追求的目標,一種很高的思想境界。俄羅斯教育家烏申斯基指出:"在教育工作中,...
    靜靜然閱讀 496評論 0 10
  • 11月24日咖啡冥想 1、一早一邊洗漱一邊給老公上課:你想不想財富自由?老公:嗯!算是應聲。 那你要和媽媽搞好關系...
  • 我家兄妹兩個,童年是在一個和美的大家庭中度過。當村支書的爺爺,賢惠的奶奶,一個叔還是三個姑。就因為有著眾多長輩的...
    沙灘上的魚_9ae6閱讀 820評論 3 9