赞
踩
打开浏览器从输入网址到网页呈现在大家面前,背后到底发生了什么?经历怎么样的一个过程?现在带大家来看看流程。
首先我们需要通过 DNS(域名解析系统)将 URL 解析为对应的 IP 地址,然后与这个 IP 地址确定的那台服务器建立起 TCP 网络连接,随后我们向服务端抛出我们的 HTTP 请求,服务端处理完我们的请求之后,把目标数据放在 HTTP 响应里返回给客户端,拿到响应数据的浏览器就可以开始走一个渲染的流程。渲染完毕,页面便呈现给了用户
总体来说分为以下几个过程:
web
前端应用的开发与部署过程:
输入url
到页面显示出来的过程
请求过程中一些潜在的性能优化点:
dns
是否可以通过缓存减少dns
查询时间?http
请求的大小和次数?http
请求的过程是前端性能优化的核心。优化核心
http
请求数量;google
首页案例学习
html
压缩;css
压缩;js
的压缩和混乱;gzip
;html
压缩HTML
代码压缩就是压缩一些在文本文件中有意义,但是在HTML
中不显示的字符,包括空格,制表符,换行符等,还有一些其他意义的字符,如HTML
注释也可以被压缩;
一个简单的计算:
google
的流量,占到整个互联网的40%
,如果2016
年全球网络流量是1.3ZB(1ZB = 10^9TB)
,那么google
在2016
年的流量就是1.3ZB * 40%
,如果google
每1MB
请求减少一个字节,每年可以节省流量近500TB
流量。
如何进行html
压缩
nodejs
提供的html-minifier
工具;css
代码压缩分为两部分:
css
语义合并;如何进行css
压缩
html-minifier
对html
中的css
进行压缩;clean-css
对css
进行压缩;js
压缩与混乱(丑化)包括:
JS
压缩与混乱(丑化)
html-minifier
对html
中的js
进行压缩;uglify.js2
对js
进行压缩;文件合并的好处:
左边的表示使用http
长链接keep-alive
但不合并请求的情况,需要分三次去获取a.js
、b.js
、c.js
;右边是使用长链接并且合并请求的情况,只需要发送一次获取合并文件a-b-c.js
的请求,就能将三个文件都请求回来。
不合并请求有下列缺点:
N-1
个网络延迟;keep-alive
本身也存在问题:经过代理服务器时可能会被断开;文件合并存在的问题
js
文件的时候,如果页面渲染只依赖a.js
文件,由于文件合并,需要等待合并后的a-b-c.js
文件请求回来才能继续渲染,这样就会导致页面渲染速度变慢。这种情况大多出现在现代化的前端框架,如Vue
等的使用过程中;a-b-c.js
中只要其中一个文件(比如a.js
)发生变化,那么整个合并文件都将失效,而不采用文件合并就不会出现这种情况;使用建议
js
文件单独合并:比如在单页面应用SPA
中,当路由跳转到具体的页面时才请求该页面需要的js
文件;如何进行文件合并
nodejs
实现文件合并;webpack
等前端构件化工具也可以很好地实现;前置知识:二进制位数与色彩的关系 在计算机中,像素用二进制数来表示。不同的图片格式中像素与二进制位数之间的对应关系是不同的。一个像素对应的二进制位数越多,它可以表示的颜色种类就越多,成像效果也就越细腻,文件体积相应也会越大。
关键字:有损压缩、体积小、加载快、不支持透明。
JPG或Joint Photographic Experts Group联合图像专家小组,(JPEG)可能是最知名并且使用最广的图像格式。 这是大多数图像保存的默认选项,因为它几乎可以无限制地显示彩色照片。
JPG 的优点:
JPG 的缺点:
JPG 的应用场景:
JPG 适用于呈现色彩丰富的图片,在我们日常开发中,JPG 图片经常作为大的背景图、轮播图或 Banner 图出现。
关键字:无损压缩、质量高、体积大、支持透明。
PNG是便携式网络图形,是一种为网络设计的格式,提供JPG无法提供的东西—透明度。 这就是为什么PNG如此受欢迎,这种格式的图像元素可以很方便被上传到网站设计中。
有两种类型的PNG格式: PNG-8和PNG-24。 PNG-8使用更有限的调色板,只有256种颜色,透明度更好,保存尺寸更小。 PNG-24使用无限的调色板,可以呈现约 1600 万种颜色,保持透明度,但保存尺寸更大。 两种PNG类型都具有无损压缩。
虽然PNG格式与GIF类似,但它们不支持动画。 此格式最常用于图标,小型静止图像或任何需要透明度的图像。
PNG 的优点:
PNG 的缺点:
PNG 的应用场景:
考虑到 PNG 在处理线条和颜色对比度方面的优势,我们主要用它来呈现小的 Logo、颜色简单且对比强烈的图片或背景等。
关键字:文本文件、体积小、不失真、兼容性好。
SVG是可缩放矢量图形。它非常实用,适用于除照片之外的任何类型的图像。这就是设计师更频繁地使用它的原因
SVG的优点:
SVG的缺点:
SVG 的使用方式与应用场景:
常用于网络上的图形和LOGO以及将在视网膜或其他高分辨率屏幕上查看的项目。
将 SVG 写入 HTML
将 SVG 写入独立文件后引入 HTML将 SVG 写入 HTML
关键字:文本文件、依赖编码、小图标解决方案
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一。Base64编码可用于在HTTP环境下传递较长的标识信息, 直接把base64当成是字符串方式的数据就好了。
Base的优点:
Base的缺点:
ie8
以上浏览器;1000kb
的图片,base64
编码会使图片大小增大,导致网页整体下载速度减慢;Base64 的应用场景:
图片的实际尺寸很小(大家可以观察一下掘金页面的 Base64 图,几乎没有超过 2kb 的)
图片无法以雪碧图的形式与其它小图结合(合成雪碧图仍是主要的减少 HTTP 请求的途径,Base64 是雪碧图的补充)
图片的更新频率非常低(不需我们重复编码和修改文件内容,维护成本较低)
将图片的内容内嵌到html
当中,减少网站的HTTP
请求数量,常用于处理小图标和背景图片。网页内联图片写法为:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAiCAYAAAA3WXuFAAAAAXNSR0IArs4c6QAAA1dJREFUWAnNl0tIVGEUx//XBxpWGmGUVmAPUoiMngZRpDNTmkWb3FSki2wRRi160aKCsqAWWq2cmSyJWrgIEhVsYLSsRQgRQYSE9lgEQU+sHGfmfv2/xpvjnYf36jz8YLj3u/d85/zuOd853xkF02SU3xK5XhX7U6cDT+UdkT/ihZss/pRkA9nsomB4BE8EUChZkgpksYsivyCMQIHmmKQBWZvEakL08JevwchrUoDKnGKTqsBNz+QGwyQFiHumFH50QSBHD5NwIItD7PQD7TQ8MxxMQoEsTaJKqHhAz2RGgkkYELOpBgru0WB6NJiEANEzdawxTm5gQ0U4rllW5hBnCHOdYVIm8oz2Pm5ArDP1UFGvGTJ6TTMqaFROCKFYHWhUBeqMrgmWiynQeSFSCOPgfqkJNmLmPmZAtX0ivdeBu4SpMgOgl40JUHWzyBx4gVbCVOoNmJ1PGcjWIrI+evCQmVRq1ng4+Sll2Z5mkaN68MgMTA7r9IE1wIZF4XCASXtItpxDPnQxTLKNMDSyCdOwG1iYDfhUYN994Mvv8UsnBWR1ijyvHy7CFI1XF3mWSUv1OwIwUmrEBwx5QuVNh0y2nDwkZZdnGCaVdfqcBVgx2v346Z0r3YCHR79+mAKyNYvC0ZZziV7Rsc0Mxy6geIH+DXBiK7A+aM80PgWevQ+Vk08MA213imLVh8dcM67llEqWzgUq6a+V84HL5UDJYvk0MGo3Apbl2gy43Qd0vBmb6+8MncBsH0p4FLiYTTQdOn4MA2XLgFkZQCo/cQv99+5bIJMOrh2Tb3sN2J+PzfV3ioKXE57C9Mw2n591JkqXJxXPywKusSzmzQ6Ykfskhdpp5N/oHQQuuMBvijwo2xI1ZFa7qGB6dlBFxJZTU//5F3C8DfjwPfBEekqDefUJuOSODqPpiRgyq0PsZZhaKchAGBt/vPxfMwCs4waeMyOwZvArcLITGGaaTzRkyMICsZeppmtbqMB0nZKGJVQGV0qYqz3AzzD1JhycBArZQwzTEYb/BoMd8i6cklg+C9lDzKbTDNPNZMCMflj/fy8Q5iKr79lYfrEZXfROf3o+VqXJltPmQAM9c9SMgjjIHu6sUDxpbDlPUXkFCd/GwYghlYxMu+uQ0i2F/wIQpwzQdGJ/EQAAAABJRU5ErkJggg==">
浏览器上的表现形式为:
这里提供一个将:image
转 DataUrI
的网址:图片转 DataURI 编码 - Image to Data URI | 小影的工具箱
关键字:年轻的全能型选手 是 Google 专为 Web 开发的一种旨在加快图片加载速度的图片格式,它支持有损压缩和无损压缩。
webp的优点:
WebP 像 JPEG 一样对细节丰富的图片信手拈来,像 PNG 一样支持透明,像 GIF 一样可以显示动态图片——它集多种图片文件格式的优点于一身。体积小巧.
webp
的优势体现在它具有更优的图像压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha
透明以及动画的特性。在JPEG
和PNG
上的转化效果都非常优秀、稳定和统一。安卓上不存在兼容性问题,推荐安卓下使用。
webp的缺点:
兼容性不太好, 只有opera,和chrome支持;
以下为淘宝网首页请求的图片:
可以通过在线网站将图片转换为webp
:智图客户端下载_图片压缩在线工具_在线制作webp
GIF图形交换格式是一种位图图形文件格式,以8位色(即256种颜色)重现真彩色的图像。它实际上是一种压缩文档,采用LZW压缩算法进行编码,有效地减少了图像文件在网络上传输的时间。它是目前广泛应用于网络传输的图像格式之一。
GIF的优点:
① 优秀的压缩算法使其在一定程度上保证图像质量的同时将体积变得很小。
② 可插入多帧,从而实现动画效果。
③可设置透明色以产生对象浮现于背景之上的效果。
GIF的缺点:
由于采用了8位压缩,最多只能处理256种颜色(2的8次方),故不宜应用于真彩图像。
SVG
与iconfont
使用iconfont
解决icon
问题
应尽量使用该方式,比如可以采用阿里巴巴矢量图库:
可以选择格式进行下载:
可以看到它们的大小有着明显的差异:
使用SVG
进行矢量图的控制
SVG
意为可缩放矢量图形(Scalable Vector Graphics
)。SVG
使用 XML
格式定义图像。下为示例:
在线转换网站:在线jpg,png图片转SVG工具-BeJSON.com
css
雪碧图将网站上用到的一些图片整合到一张单独的图片中,从而减少网站HTTP
请求数量。原理为:设定整张雪碧图可示区域,将想要显示的图标定位到该处(左上角);缺点:整合图片比较大时,一次加载比较慢。
如天猫的雪碧图:
很多情况下,并不是所有的小图标都放在一张雪碧图中,而是会适当进行拆分。现在使用雪碧图的场景比较少了。
自动生成雪碧图样式的网站:Sprite Cow - Generate CSS for sprite sheets
选中雪碧图中对应的图标,就会生成对应的样式。
图片进入可视区域之后再请求图片资源的方式称为图片懒加载。适用于图片很多,页面很长的业务场景,比如电商;
懒加载的作用:
js
的加载,影响网站正常的使用:host name
是有并发度上限的,如果图片资源所在的CDN
和静态资源所在的CDN
是同一个的话,过多图片的并发加载就会阻塞后续js
文件的并发加载。懒加载实现的原理:
监听onscroll
事件,判断可视区域位置:
图片的加载是依赖于src
路径的,首先可以为所有懒加载的静态资源添加自定义属性字段,用于存储真实的url
。比如是图片的话,可以定义data-src
属性存储真实的图片地址,src
指向loading
的图片或占位符。然后当资源进入视口的时候,才将src
属性值替换成data-src
中存放的真实url
。
<img src="" class="image-item" alt="" lazyload = "true" data-src="TB27YQvbm_I8KJjy0FoXXaFnVXa_!!400677031.jpg_180x180xzq90.jpg_.webp">
懒加载实例
可以使用元素的getBoundingRect().top
来判断当前位置是否在视口内,也可以使用元素距离文档顶部的距离offsetTop
和scrollTop
是否小于视口高度来判断:
举例
比如手机淘宝首页:
当快要滚动到需要展示的图片时才进行图片的请求,可以看到图片上有一个lazyload
的属性:
预加载与懒加载正好是相反的过程:懒加载实际上是延迟加载,将我们所需的静态资源加载时间延后;而预加载是将图片等静态资源在使用之前的提前请求,这样资源在使用到时能从缓存中直接加载,从而提升用户体验;
预加载的作用:
WebGL
页面,会依赖一些3D
模型,这些都是页面渲染所必须的资源。如果资源都没有加载完毕就进行页面的渲染,就会造成非常不好的体验。WebGL
页面依赖的3D
模型加载完之后才进行页面渲染。这样渲染的过程就不会有任何阻碍,具有较好的用户体验;预加载的实例
例如九宫格抽奖业务,每个奖品都有一个选中态和非选中态,实际上这是由两张图片组合而成的。由于每个奖品的选中过程都是一瞬间,这就对图片的选中态和非选中态切换效率要求很高,如果选中态的图片没有预加载的话显然是来不及的。
所以,实际上对于九宫格中所有图片选中态的样式和对应的图片都需要进行预加载,从而让我们在抽奖的过程中,能够瞬间从缓存中读取到选中态的图片,从而不影响抽奖效果的展示。
除此之外还有网站登录或活动时需要用到的动画,这是在动画需要的每帧图片都完全预加载完之后才会进行显示的。
客户端渲染模式下,服务端会把渲染需要的静态文件发送给客户端,客户端加载过来后,自己在浏览器里跑一遍js,根据js的运行结果,生成相应的DOM
<!doctype html> <html> <head> <title>我是客户端渲染的页面</title> </head> <body> <div id='root'></div> <script src='index.js'></script> </body> </html>
根节点下到底是什么内容呢?只有浏览器把 index.js 跑过一遍后才知道,这就是典型的客户端渲染。
页面上呈现的内容,你在 html 源文件里里找不到——这正是它的特点。
服务端渲染的模式下,当用户第一次请求页面时,由服务器把需要的组件或页面渲染成 HTML 字符串,然后把它返回给客户端。客户端拿到手的,是可以直接渲染然后呈现给用户的 HTML 内容,不需要为了生成 DOM 内容自己再去跑一遍 JS 代码。
使用服务端渲染的网站,可以说是“所见即所得”,页面上呈现的内容,我们在 html 源文件里也能找到
事实上,很多网站是出于效益(seo)的考虑才启用服务端渲染,性能倒是在其次。
假设 A 网站页面中有一个关键字叫“前端性能优化”,这个关键字是 JS 代码跑过一遍后添加到 HTML 页面中的。那么客户端渲染模式下,我们在搜索引擎搜索这个关键字,是找不到 A 网站的——搜索引擎只会查找现成的内容,不会帮你跑 JS 代码。A 网站的运营方见此情形,感到很头大:搜索引擎搜不出来,用户找不到我们,谁还会用我的网站呢?为了把“现成的内容”拿给搜索引擎看,A 网站不得不启用服务端渲染。
但性能在其次,不代表性能不重要。服务端渲染解决了一个非常关键的性能问题——首屏加载速度过慢。在客户端渲染模式下,我们除了加载 HTML,还要等渲染所需的这部分 JS 加载完,之后还得把这部分 JS 在浏览器上再跑一遍。这一切都是发生在用户点击了我们的链接之后的事情,在这个过程结束之前,用户始终见不到我们网页的庐山真面目,也就是说用户一直在等!相比之下,服务端渲染模式下,服务器给到客户端的已经是一个直接可以拿来呈现给用户的网页,中间环节早在服务端就帮我们做掉了,用户岂不“美滋滋”?。
服务端渲染本质上是本该浏览器做的事情,分担给服务器去做。这样当资源抵达浏览器时,它呈现的速度就快了
但仔细想想,在这个网民遍地的时代,几乎有多少个用户就有多少台浏览器。用户拥有的浏览器总量多到数不清,那么一个公司的服务器又有多少台呢?我们把这么多台浏览器的渲染压力集中起来,分散给相比之下数量并不多的服务器,服务器肯定是承受不住的
除非网页对性能要求太高了,以至于所有的招式都用完了,性能表现还是不尽人意,这时候我们就可以考虑向老板多申请几台服务器,把服务端渲染搞起来了~
viewport
:viewport
可以加速页面的渲染;requestAnimationFrame
动画代替 setTimeout
(跑在主线程上,一般一秒刷新 60 次,提高动画帧的利用效率),参考文章 requestAnimationFrame & CSS3 animation;Touchmove
和 Scroll
事件可导致多次渲染requestAnimationFrame
监听帧变化,使得在正确的时间进行渲染;浏览器内核可以分成两部分:渲染引擎(Layout Engine 或者 Rendering Engine)和 JS 引擎
渲染引擎包括了 HTML 解释器、CSS 解释器、布局、网络、存储、图形、音视频、图片解码器等等零部件。
6.3.1CSS 选择符是从右到左进行匹配的
#myList li {}
浏览器必须遍历页面上每个 li 元素,并且每次都要去确认这个 li 元素的父元素 id 是不是 myList
6.3.2具体优化
flexbox
代替传统的布局模型display
属性:display:inline
后边不应再使用 width
、height
、margin
、padding
以及 float
display:inline-block
后不应该使用 float
display:block
后不应该再使用 vertical-align
display:table
后不应该再使用 margin
或 float
float
:float
在渲染时的计算量比较大,尽量减少使用font-size
: 尽量使用语义化标签的默认字体大小,提高 CSS 树的效率-webkit-
无前缀
两种即可)-webkit-
、-moz-
、-ms-
、无前缀
四种HTML、CSS 和 JS,都具有阻塞渲染的特性。 HTML 阻塞,天经地义——没有 HTML,何来 DOM?没有 DOM,渲染和优化,都是空谈。
6.4.1 加载优化(最耗时)
6.4.2CSS 的阻塞
在刚刚的过程中,我们提到 DOM 和 CSSOM 合力才能构建渲染树。这一点会给性能造成严重影响:默认情况下,CSS 是阻塞的资源。浏览器在构建 CSSOM 的过程中,不会渲染任何已处理的内容。即便 DOM 已经解析完毕了,只要 CSSOM 不 OK,那么渲染这个事情就不 OK(这主要是为了避免没有 CSS 的 HTML 页面丑陋地“裸奔”在用户眼前)。
只有当我们开始解析 HTML 后、解析到 link 标签或者 style 标签时,CSS 才登场,CSSOM 的构建才开始。 很多时候,DOM 不得不等待 CSSOM。因此我们可以这样总结:
CSS 是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。
尽早(将 CSS 放在 head 标签里)和尽快(启用 CDN 实现静态资源加载速度的优化)
6.4.3 js的阻塞
JS 的作用在于修改,它帮助我们修改网页的方方面面:内容、样式以及它如何响应用户交互。这“方方面面”的修改,本质上都是对 DOM 和 CSSDOM 进行修改。因此 JS 的执行会阻止 CSSOM,在我们不作显式声明的情况下,它也会阻塞 DOM。
JS 引擎是独立于渲染引擎存在的。我们的 JS 代码在文档的何处插入,就在何处执行。当 HTML 解析器遇到一个 script 标签时,它会暂停渲染过程,将控制权交给 JS 引擎。JS 引擎对内联的 JS 代码会直接执行,对外部 JS 文件还要先获取到脚本、再进行执行。等 JS 引擎运行完毕,浏览器又会把控制权还给渲染引擎,继续 CSSOM 和 DOM 的构建。 因此与其说是 JS 把 CSS 和 HTML 阻塞了,不如说是 JS 引擎抢走了渲染引擎的控制权。
之所以会阻塞对标签的解析是因为加载的js中可能会创建,删除节点等,这些操作会对dom树产生影响,如果不阻塞,等浏览器解析完标签生成dom树后,js修改了某些节点,那么浏览器又得重新解析,然后生成dom树,性能比较差。
6.4.4js的三种加载方式
正常模式
这种情况下 JS 会阻塞浏览器,浏览器必须等待 index.js 加载和执行完毕才能去做其它事情。
<script src="index.js"></script>
async(异步) 模式
async 模式下,JS 不会阻塞浏览器做任何其它的事情。它的加载是异步的,当它加载结束,JS 脚本会立即执行。
<script async src="index.js"></script>
defer(延缓) 模式
defer 模式下,JS 的加载是异步的,执行是被推迟的。等整个文档解析完成、DOMContentLoaded 事件即将被触发时,被标记了 defer 的 JS 文件才会开始依次执行。
<script defer src="index.js"></script>
从应用的角度来说,一般当我们的脚本与 DOM 元素和其它脚本之间的依赖关系不强时,我们会选用 async;当脚本依赖于 DOM 元素和其它脚本的执行结果时,我们会选用 defer。
6.4.5JavaScript执行优化
document.write()
;drawImage
;Touch
事件优化:使用 touchstart
、touchend
代替 click
,但注意 Touch
响应过快,易引发误操作;赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。