浏览器--我是什么鬼

248 阅读16分钟

哲学有云,要搞清我是什么鬼,首先要弄清楚我从哪里来,我到哪里去,孔子到底是圣人,一句话就回避了这个问题:”未知生,焉知死”。是的,搞清浏览器从哪里来,他的发展历史,包含正史和野史,google或baidu都知道,浏览器到哪里去,天知道。而我们关注的是浏览器是做什么用的,怎么来用他为人民服务。


从表现上来看,浏览器是显示网页的,网页里面有什么呢,我们看到的有文字、图片、视频等内容,除了显示内容,我们还要关心如何显示,如何与我们亲爱的用户交互。由此我们有了三种描述网页的最基本的语言,html,css和javascript,html描述了显示内容,css表示了怎么显示,js描述了怎么和用户交互。


我们首先看html,html是一个非常简单、淳朴的标记语言,之所以叫他是标记语言,是因为他用各种标签来表示不同类型的内容,比如<img>标签,你一定会抢答为图片,<video>标签你一看就知道视频,简单吧,比计算机的远古时代用二进制来表示不同的类型不知道强了多少倍,至于显示什么图片和视频,每个标签都会有对应的属性,比如<img>标签的src属性表示了图片的链接,显示啥图片,就设置不同的src属性就可以了,当然到底用哪些标签,哪些属性,都是有统一规定的,详见w3c标准。我们可以把要显示的内容直接放到Html中,但这要的话,html的呈现内容都是一样的了,我们称之为静态网页,而现在要显示的内容都是从服务器的数据库中读取贴到html中了,数据内容可以动态改变,网页的内容就可以动态改变,我们称之为动态网页。另外html是一个特别宽容的语言,像java、c等语言,你必须按照他的格式来写,要不然我就不让你编译过,而html语言就算你梦游说梦话,他都能给你显示出来,只是显示的是不是你想要的,就要遵循他的标准了,html之所以这么宽容,都是浏览器的功劳,就算我们没按照html的标准来写,浏览器也会尽量理解我们要表达的内容,按照标准解析出来,这也增加了浏览器解析负担,w3c表示看不下去了,制定了xhtml标准,像其他语言学习,我们必须按照规定格式写,要不然就不让你编译过,结果写网站的人大部分都不鸟他,结果也不了了之了,人性懒,无办法。我们都知道一图胜万言,西施一瞥胜过小说的各种描述,图像、视频带来的信息是文字没法比的。html一开始是不支持音视频的,后来有了flash,flash有一套协议来播放视频,浏览器提供插件机制承载flash,二者相互配合让我们在网页上也能看视频,像两个人从恋爱一样,一开始还亲亲我我,生死不离,时间长了,html发现flash经常造成自己崩溃,html的标准进行了升级,升级到了Html5。乔布斯大神更是瞧不上flash,一直在排斥,终于有一天,他推动html5替代flash。总之一句话,flash生的光荣,死的可惜。


在来看css,css把网页元素显示成什么样子,比如宽高、背景色等等,就是给每个网页的每个元素一个不同江南style,比如定义两个class属性,一个是.beauty表示美的显示,一个是.ugly表示丑的显示,分别定义背景色和宽高,当然还可以用其他属性.beauty{background-color:white; width:100px; height:100px},.ugly{background-color:black; width:10px; height:100px},如果一个网页元素div想打扮的漂亮点,他就这么引用<div class=”beauty”>,如果另外一个元素a想恶作剧,那么就这么引用<a class=”ugly”>,当然网页想做成什么样子完全可以由html自己做主,把这个功能抽出来作为css完全为了解耦,专业的语言做专业的事,css的这一思路值得android同学学习。


最后,我们看javascript,虽然叫javascript,但和java一点关系都没有,之所以叫javascript,猜测有借java东风,狐假虎威的意思。这个冒牌货的出生完全为了网页服务的,具体一点就是为html服务的,浏览器会把html解析成一棵树,如果能动态的操作这棵树就能实现网页内容的动态变化,而javascript正好提供了操作这颗树的各种接口。js设计者用了20多天就完成了js设计,正是由于他没被重视的出生,造成了他的劣根性,执行速度慢,后来有了各种优化,比之前提高了好多倍,但还是要合理使用,某圈甚至提出一条多余的js造成地球多了多少二氧化碳,所以为了绿色地球,合理使用js。但如何使用js,并不是我们做浏览器能管的到的,很多网站为了money,而技术受限,使用了大量的js,让网页很慢,让浏览器来背锅。浏览器怒了,就对不合理的js杀无赦,这就是我们下面要谈的adblock。


当然,html、css和js是浏览器的基础,除了他本身以外,他还带来了很多资源,比如图片、视频、字体等等。所以单纯的一个html网页是占用了很少部分的,更多的是html引用的各种资源。


聊完了网页,我们聊一下浏览器内核、webview和浏览器的关系。

浏览器内核是从做什么用的,他把我们上面说的html、css、js等代码转化为了我们看不到的网页内容,之所以说看不到是因为他把最后的处理结果放到了内存中,并没有映射到显示器上,如果要显示出来,就需要操作系统来承载,webview是一种android系统对内核输出结果的承载,windows也有一个view在承载内核输出结果。看下图:




我们上面说了浏览器内核是把html代码输出为不显示的网页内容,至于这些代码为什么显示为那些内容是由w3c标准决定的,当然IE当时凭借着自己的垄断,自己制定了一套标准,现在势落,成了人人喊打的对象,而输出的效率是由于内核的算法来决定了,就像车的发动机一样,发动机都能驱动汽车,效率如何,看内功了。现在主流浏览器内核有四种,Trident、Gecko、WebKit和Blink,Trident内核的代表是IE,Gecko的代表是firefox,WebKit的代表是safri,还有android4.4以下的webview,也就是说谷歌一开始还在用webkit内核,后来和苹果的分歧越来越大,干脆自己在webkit的基础上改造了一个内核,称为blink,现在有内核的浏览器用的基本上都在追随google,最早用webkit,后来又用blink内核,在blink内核的基础上定制自己的内核,比如腾讯的X5内核、UC的U8内核。没有内核的浏览器直接用webview就可以了。


我们上面说了浏览器内核的输出结果拷贝到webview内存,使webview这个控件就能显示网页,我们也可以自己建一个surfaceView,让浏览器内核输出结果直接到这个surfaceView中,就少了一步拷贝工作,chrome浏览器就是这么干的。


我们在回到原点,问一句,浏览器到底是什么鬼?就是显示网页吗?经过刚才的分析,webview就能显示网页,这个webview可以集成到任何app中,比如新闻客户端,君不见现在pc上只要和内容相关的app都会用到webview类似的view。按我现在的理解,浏览器就是提供了各种入口和功能,让用户更方便的访问网页内容,比如地址栏、历史/书签、标签等都是浏览器的概念,而对于网页功能的增强,比如网页加速、adblock等,虽然是浏览器做的功能,但完全可以抽成一个SuperWebview,集成到其他app中,比如x5内核,qq浏览器和微信都在用。如果从模块化角度来看,浏览器可以拆成网页浏览模块、搜索模块、新闻推荐模块、下载模块和app属性相关的功能模块,分别对应了信息的浏览、过滤和保存,而网页浏览、搜索模块、新闻推荐、下载每个模块都可以单独成为一个app,也可以组合成一个app。


浏览器是如何显示网页的,我们上面说比较技术化,现在把浏览器工作流程做一个类比来描述这个过程。把一家饭店比作成操作系统,其他菜店或原料店比作成网站服务器,厨师比作成浏览器内核,托盘比作成webview,外面的桌子比作成显示器,首先用户点菜,可以看成输入某个网站的url,厨师收到要点的菜,打电话给这家店,这家店把菜的所有原料送过来,这个过程可以看成浏览器连接服务器接收数据的过程,厨师收到原料后,开始根据食谱做菜,食谱就像w3c标准,做菜的过程就是浏览器内核解析、布局、渲染的过程,炒完菜后放到一个盘子上,可以看成把内核的处理结果放到某个内存中,等待服务员拿着托盘来取,把盘子的菜放到托盘中,看作把内核的处理结果从暂住的内存放到webview内存中,服务员通过托盘把菜放到桌子上,比作成从内存到显示器的过程。上面是基本流程,实际上的过程远远没有这么简单,用过浏览器的人都能体会到,网速慢的时候,浏览器是一点一点显示网页的,像挤牙膏一样,我们可以质问浏览器为什么不等数据加载完给我一下子显示出来,浏览器也是觉得宝宝心里苦,好心当成驴肝肺,如果等所有数据来了才显示,那么在网络慢的时候,不知道加载到猴年马月,我们早就忍受不了,把浏览器痛骂一顿。所以说浏览器的工作都是收一点数据,解析一点数据,布局一点数据,显示一点数据,让我们知道浏览器还没有叛变,还在为人民服务。即便是这样,为什么有时候打开网页还有一段的空白时间呢?首先连接服务器需要时间,特别有时候还要跳转一下,比如从www.facebook.com跳转到m.facebook.com,所以我们在配topsite网址时,尽量配准确了,能不让跳转就不让跳转,当然最费时间的就是接收数据了,html网页整体上可以分成两部分<head>和<body>,<head>标签里面包含<title>、网站图标、需要提前加载的js代码或链接、需要提前加载的css代码和链接,这些数据要么说明当前网页的基本信息,要么为了下面<body>的内容显示做准备,解析<head>里面的数据是不会显示出内容的,直到加载到<body>中的某个可以显示内容的元素,才能显示出来内容来,我们才能看到第一批内容。如果<head>里面的内容又臭又长,网络都不愿意运输,那么白屏事件肯定长了。更有甚者,<head>里面有好多css链接和js链接,那可就麻烦了,浏览器解析到有css链接或js链接就要马上去请求,当没完全收到css和js链接数据时,就算body接收到可以显示的数据了,仍然显示不了,凭啥呢?假设有一个div元素,他想打扮的漂亮一点,class属性为beauty,<div class=”beauty”>….</div>,而beauty到底把背景设置成啥样,把宽高设置成啥样,可能在前面的css链接数据中,当然我也可以先不管class属性,先显示出来,等css数据来了,再刷一遍,这取决于浏览器内核的策略。


了解了浏览器的显示网页的流程,我们看一下如何优化浏览器的显示速度,要优化显示速度,首先要了解显示速度的标准是什么,我们可以根据用户的体验把速度分为下面几种:首批内容显示的时间、主要内容显示的时间、首屏内容显示的时间、整个网页显示的时间。有了标准,我们看一下网页速度优化的思路,下面只是思路不是具体方案,目的是为了抛砖引玉。


1.预加载。预加载有两种场景的预加载,第一种是用户进入到首页,根据用户的使用习惯,提前给他加载网页,这种机制的好处是不管弱网还是网速较快的时候,都可以用,当网速较快时,如果猜中了用户要访问的网页,就能让用户享受到秒开的感觉,另外一种是当网络好的时候,定时的给用户保存经常访问的网页。预加载在强网还是弱网都可以用,但除了猜中用户的习惯,而且只能给用户保存主页上的内容,因为子页面的内容经常变。搜狗宣称他采用的预加载方式,速度提升了多少多少。


2.减少网页体积。我们了解到网页速度慢的罪魁祸首就是网页体积和网速慢之间的矛盾,在印度网速慢是不可改变的,我们看一下如何优化网页体积。


(1)如果网站有wap站,就访问wap网页,wap网站是针对于2g年代定制的,特别小,现在大部分网站都不再支持,目前我知道的用户经常访问的google、youtube、xvideos都有wap网站,他的好处是显而易见的,不好的地方就是支持wap的网站少了一些。


(2)服务器压缩,最典型就是在2g时代称霸武林的uc和opera,我们已经讲过浏览器显示网页的过程有接收数据、解析、布局和渲染,而他们采用的方案是把解析和布局过程都放到自己的服务器上做了,而客户端只要渲染一下就可以了,再拿上面做菜的过程做类比,正常网页的加载流程是需要从其他店买到原料,然后加工,然后在送到桌子上,而uc采用的流程是先把原料运到另外一家店,另外一家店比作自己的服务器,运到另外一家店的速度要快很多,然后在这家店做半加工,放到盘子里,送到饭店,饭店的厨师只要翻炒一下就可以了,这种方案节省流量,速度快,但有技术门槛,并且耗费服务器资源,显示出来的网页乱的一塌糊涂,视频不能播放,他们走的路线是”有总比没有强”。另外一种是现在chrome做的只对图片和视频进行压缩,这种机制虽然节省了部分流量,但对于加载速度没多大作用。还有一种方案是利用googlelightweight来压缩,从印度人民对这个网站的访问量就能看出来印度人民对这个网站的饥渴程度,至于如何利用这个网站压缩,还需要再调研,测的有些网站压缩不了,不知道为啥。


(3)客户端不接收无用的数据,最典型的就是广告拦截,广告拦截最大的作用是还用户一个清爽,再一个节省部分流量,至于提升加载速度,需要看具体的网页,假设有网页根本没有广告,你还对每个资源搜身一遍,无耻,所以说广告拦截算法的效率就特别重要。对有些网站就特别有效,特别有些网站无良的乱用js,不但拖慢网页速度,而且耗大量内存。还有一种思路是”有总比没有强”只接收主网页,像js和css、字体等资源都不接收,图片等网页加载完在加载。至于显示乱,可以采用阅读模式的思路。至于有些js不加载导致网页数据出不来,就要对网站做适配了,用到下面的缓存机制。


(4)自我缓存,通过前面描述,我们知道浏览器速度慢还有一个原因是加载要使用的js和css资源,我们可以把用户经常访问的网站的重要的js和css资源下到我们自己的服务器,然后下发给用户,当用户访问网页时,通过对比url加载我们下发的资源。这种机制需要我们制定缓存更新策略,而且有些css和js资源的url故意难为我们,同一个资源经常变。


(5)网页速度特别慢,确实加载不出来,应该如何做,chrome一开始给的方案是在错误页面有个h5小游戏安慰安慰你,后来添加了一个按钮是”有网络时加载”。而苹果手机的chrome和safri采用的是”稍后读”的方案,我先把我想看的网页加到稍后读的列表中,浏览器有网络时就帮我下,而且当网络特别慢时,我在主页上浏览,我们在网页根据标题选择我们感兴趣的链接,长按加入到稍后读列表中,当我们浏览完主页后,第一个加入稍后读的网页可能已经加载完了。还有一种思路是我们根据用户打开网页的title从我们服务器上搜是否有相似的内容推给用户。



当然上面列出来的只是客户端的优化思路,实际上,网页优化不是单纯的客户端优化,需要后台、前端、内核、w3c标准、客户端共同努力,只不过我们目前只能做客户端的优化。