漫谈网站优化提速
前几天的一个晚上,在和一个偶然认识的小白,聊了半个晚上的网站加速的事情,总觉本身最后没有讲清楚,固有此文产生。css
本篇文章只涉及前端优化,暂不涉及后端操做,默认后端能抗住全部访问,算力无限大,响应时间无限小。由于加上后端的话,这个命题不是短短的几篇文章搞的定的,大多数都要依据具体的业务来肯定。html
本文涉及到的浏览器为Chrome浏览器,不具备统一性,仅供参考使用。前端
用户和网站的交互是经过浏览器来完成的,要谈前端优化,那么,咱们就要搞清楚,从用户输入了一串url之后,浏览器到底作了什么。web
1. 浏览器如何打开一个网页
这里咱们先不考虑路由寻址的事情,后面咱们再细细道来,在Chrome浏览器中先打开F12,打开network,能够看到一个网站从输入url到页面显示,具体发送了多少请求。咱们以百度为示例,看一下:后端
首先第一行,能够看到浏览器请求了百度这个页面的主题文件HTML,当浏览器收到这个HTML以后,浏览器和这个页面的缘分,就此开始。浏览器
1.1 浏览器渲染流程
用户请求的HTML文本(text/html)经过浏览器的网络层到达渲染引擎后,渲染工做开始。每次一般渲染不会超过8K的数据块,其中基础的渲染流程图:缓存
webkit引擎渲染的详细流程,其余引擎渲染流程稍有不一样:服务器
渲染流程有四个主要步骤:网络
-
解析HTML生成DOM树 - 渲染引擎首先解析HTML文档,生成DOM树前端优化
-
构建Render树 - 接下来无论是内联式,外联式仍是嵌入式引入的CSS样式会被解析生成CSSOM树,根据DOM树与CSSOM树生成另一棵用于渲染的树-渲染树(Render tree),
-
布局Render树 - 而后对渲染树的每一个节点进行布局处理,肯定其在屏幕上的显示位置
-
绘制Render树 - 最后遍历渲染树并用UI后端层将每个节点绘制出来
以上步骤是一个渐进的过程,为了提升用户体验,渲染引擎试图尽量快的把结果显示给最终用户。它不会等到全部HTML都被解析完才建立并布局渲染树。它会在从网络层获取文档内容的同时把已经接收到的局部内容先展现出来。
1.2 渲染细节
浏览器渲染一个页面的过程叫作“关键渲染路径(Critical Rendering Path 简称CRP)”,下面咱们来聊一下什么是CRP,这对咱们进行代码级的优化有很大的指导意义。
- CRP的相关知识对于如何提高网站性能是至关有用的,共有6个步骤:
- 构建DOM树
- 构建CSSOM树
- 运行JavaScript
- 建立渲染树
- 生成布局
- 绘制页面
以下图:
下面详细聊一下什么是CRP,不感兴趣的童鞋能够直接跳过这一段看结论。
1.1.1 构建DOM树
DOM(Document Object Model)树是一个表示整个解析过的HTML页面的对象,从根节点<html>开始,会建立页面中的每一个元素/文本节点。
举个栗子:
<html> <head> <title>Understanding the Critical Rendering Path</title> <link rel="stylesheet" href="style.css"> </head> <body> <header> <h1>Understanding the Critical Rendering Path</h1> </header> <main> <h2>Introduction</h2> <p>Lorem ipsum dolor sit amet</p> </main> <footer> <small>Copyright 2017</small> </footer> </body> </html>
上面的 HTML 将会被解析成下面的DOM树:
HTML的优势在于它没必要等待整个页面加载完成才呈现页面,能够解析一部分,显示一部分。
- 可是像CSS、JavaScript等其余资源会阻止页面渲染。
1.1.2 构建CSSOM树
CSSOM(CSS Object Model) 是一个跟DOM相关的样式对象。它跟DOM的表示方法是类似的,可是不论显式声明仍是隐式继承,每一个节点都存在关联样式。
在上面提到的html页面的style.css中的样式以下
body { font-size: 18px; } header { color: plum; } h1 { font-size: 28px; } main { color: firebrick; } h2 { font-size: 20px; } footer { display: none; }
它会被构建成下面的CSSOM树
CSS 被认为是 “渲染阻塞资源”,它意味着若是不首先彻底解析资源,渲染树是没法构建的。CSS因为它的层叠继承的性质,不能像HTML同样解析一部分,显示一部分。定义在文档后面的样式会覆盖或改写以前定义的样式,由于在整个样式表都被解析以前,若是咱们使用了在样式表中较早定义的样式,那错误的样式将被应用。这意味着CSS必须被所有解析以后,才能开始下一步。
1.1.3 运行JavaScript
JavaScript被认为是解析阻塞资源,这意味着HTML的解析会被JavaScript阻塞。
当解析器解析到 <script> 标签时,不管该资源是内部仍是外链的都会中止解析,先去下载资源。这也是为何,当页面内有引用JavaScript文件时,引用标签要放到可视元素以后了。
为避免JavaScript解析阻塞,它能够经过设定 async 属性来要求其异步加载。
<script async src="script.js">
1.1.4 建立渲染树
渲染树是DOM和CSSOM的结合体,它表明最终会渲染在页面上的元素的结构对象。这意味着它只关注可见内容,对于被隐藏或者CSS属性 display:none 的属性,不会被包含在结构内。
使用上面例子的DOM和CSSOM,渲染树被建立以下:
1.1.5 生成布局
布局决定了浏览器视窗的大小,它提供了上下文依赖的CSS样式,如百分比或窗口的单位。视窗尺寸一般经过 <head> 标签中的 <meta> 中的 viewport 设定来决定。若是不存在该标签,则一般默认为 980px
例如,最经常使用的 meta veiwport 的值将会被设置为和设备宽度相符:
<meta name="viewport" content="width=device-width,initial-scale=1">
若是用户访问网页的设备宽度为1000px。而后总体视窗尺寸就会基于这个宽度值了,好比 50% 就是500px, 10vw 就是100px 等等。
1.1.6 绘制页面
最后,在绘制页面步骤。页面上的全部可见内容都会被转换为像素并呈如今屏幕上。
具体的绘制时间跟DOM数以及应用的样式有关。有些样式会花费更多的执行时间,好比复杂的渐变背景图片所须要的计算时间远超过简单固定背景色。
1.2 总结
纵观整个CRP流程,CSS,JS等静态资源加载是阻塞式的,而咱们的目标是让整个页面最快呈如今用户面前,并可使用,而一个页面的呈现和HTML、CSS息息相关,那么这两个必定是要最早被加载的:
- 关键的css须要放在html的头部位置,保证被最早加载,加载完成后能够开始渲染页面。
JS只是关系了网站的一些交互操做,包括一些动态效果,那么:
- js应该放在html的最下部,和渲染视图脱离,保证视图渲染完成后再加载js,同时,js应尽可能保持异步加载,不要阻塞主线程。
页面除了HTML,JS,CSS还有一个使用最多的那就是图片
- 图片要作压缩,不少时候高清大图并非一个好的选择
- 图片尽可能使用jpg格式(体积小)
- 图片除了首屏之外,最好使用懒加载的方式,减小初次页面渲染所须要的时间
- 小的icon整合成一张大图,减小图片加载请求数(使用时可使用css对图片显示作定位)
同时,还能够从网络层考虑优化方向:
- 从新review整个页面,去除全部没必要要的资源加载
- css样式表能够合并成为一个文件,减小浏览器请求数
- css样式表须要作压缩,减小网络传输时间(具体有工具,你们能够本身去网上找)
还有不少我一下想不到的地方,不过整体的思想就几句话:
- 尽一切可能减小网络请求数
- 尽一切可能减小网络传输数据
- 若是以上两点都作到了,那么除了关键html和css之外,其余资源的加载请尽可能走异步的形式。
2. 从url到浏览器之间到底都经历了什么?
上面咱们聊了浏览器接受到资源请求后的一些操做处理,那么从url输入浏览器到浏览器接收到资源中间到底都经历了什么,这一块咱们能作什么优化呢?
首先,咱们来看一下从url到浏览器之间到底都经历了什么?
- 首先,在浏览器地址栏中输入url
- 浏览器先查看浏览器缓存-系统缓存-路由器缓存,若是缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操做。
- 在发送http请求前,须要域名解析(DNS解析),解析获取相应的IP地址。
- 浏览器向服务器发起tcp链接,与浏览器创建tcp三次握手。
- 握手成功后,浏览器向服务器发送http请求,请求数据包。
- 服务器处理收到的请求,将数据返回至浏览器
- 浏览器收到HTTP响应
- 读取页面内容,浏览器渲染,解析html源码
- 生成Dom树、解析css样式、js交互
- 客户端和服务器交互
首先,咱们能作优化的地方只有可怜的2,包括四、五、六、七、8都是标准的处理流程,咱们也没法干涉。
2.1 缓存查找
- 浏览器缓存:浏览器会记录DNS一段时间,所以,只是第一个地方解析DNS请求;
- 操做系统缓存:若是在浏览器缓存中不包含这个记录,则会使系统调用操做系统,获取操做系统的记录(保存最近的DNS查询缓存);
- 路由器缓存:若是上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
- ISP缓存:若上述均失败,继续向ISP搜索。
小结:
- 在不多有改动的页面上开启浏览器缓存,在打开页面时尽量的利用浏览器缓存
3. 网站访问慢还有什么可能?
网站打开速度慢受不少因素的影响,简单概括下常见的几个缘由:
- 主机服务器不堪重负,响应速度慢;
- 静态资源占用了主机服务大量的带宽,达到了上限;
- 网站的图片和内容太大,须要花费不少时间下载;
- 网站使用了太多不一样的脚本和图片,这些脚本和图片没有针对快速加载网站进行优化,加载时间长;
- 网站的服务器位置与终端用户位于不一样的地理位置。
其实还有许多其余的缘由,但这些以上列举的几点是比较常见的。
3.1 终极大杀器——CDN
3.1.1 什么是CDN?
CDN指的是内容分发网络。其基本思路是尽量的避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。
经过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统可以实时地根据网络流量和各节点的链接、负载情况以及到用户的距离和响应时间等综合信息将用户的请求从新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决Internet网络拥挤的情况,提升用户访问网站的响应速度。
简单打个比方,咱们常喜欢在京东上买东西,今天下单明天就能送到。而在淘宝上,咱们享受不到这样的速度。为何呢?由于京东的物流体系完善。假设你在上海购买了海南的一件商品,淘宝走快递可能要走3天才到你手上,可是京东在全国设有仓库物流点,从就近的杭州发货点发货到上海,一天就能够到。
而CDN通常都由运营商或者大型云服务提供商来提供,能够给更大的网络带宽,能够部署的离终端用户位置更近,有智能DNS,有效缓解全部流量所有回源对咱们的主服务形成的流量冲击,带来更高的可用性,固然,这样会形成静态资源缓存,若是咱们须要更新静态资源,面临着缓存的挑战,不过,也不是没有解决方案的,全部的静态资源在访问的时候都应该加上版本号,防止访问到前面版本的资源,形成更新不及时。
参考:
http://www.javashuo.com/article/p-nookqfpg-y.html
原文出处:https://www.cnblogs.com/babycomeon/p/11173611.html