前端技术演进(一):Web前端技术基础

这个来自以前作的培训,删减了一些业务相关的,参考了不少资料( 参考资料列表),谢谢前辈们,么么哒 😘

每一个开发者或多或少都接触过前端,但如今的前端变化有点快,这里是截至2018年的前端,暂且叫:现代前端技术演进。javascript

互联网信息呈现的方式主要依靠终端设备屏幕,现在,终端设备的种类愈来愈多,智能化愈来愈高,交互也愈来愈复杂。css

image.png | center | 827x411.29466666666667

苹果官网的演进

1992年:html

image.png | left | 469x240

1996年:前端

image.png | left | 683x427

1998年:java

image.png | left | 683x427

1999年:git

image.png | left | 683x427

2000年:github

image.png | left | 550x436

2001年:web

image.png | left | 683x427

2003年:面试

image.png | left | 683x427

2005年:chrome

image.png | left | 480x407

2006年:

image.png | left | 827x516.875

2007年:

image.png | left | 827x516.875

2008年:

image.png | left | 827x516.875

2010年:

image.png | left | 827x516.875

2011年:

image.png | left | 827x516.875

乔布斯去世:

image.png | left | 827x516.875

2012年:

image.png | left | 827x516.875

2013年:

image.png | left | 827x516.875

2014年:

image.png | left | 827x516.875

2015年:

image.png | left | 827x516.875

2016年:

image.png | left | 827x385.4697845507094

2017年:

image.png | left | 827x462.73704520396916

2018年:

image.png | center | 827x562

苹果的发展是IT行业的缩影,包含了工业设计、产品设计、硬件技术、用户体验、UI设计、前端技术等方方面面。

仅从前端来看,经过苹果官网的演进,能够看到,随着互联网和移动互联网的快速发展,前端技术也发生了巨大的变化。

前端应用开发模式演变

一、静态黄页
二、服务器组装数据的动态网页
三、后端为主的 MVC
四、先后端分离
五、前端 MV* 框架
六、前端 VIrtual DOM,MNV*,先后端同构

image.png | center | 827x308.0575

全部变化,都是围绕提高前端开发的效率和质量。

浏览器基础

前端大部分时间都是在和浏览器打交道,因此咱们先从浏览器提及。

从一个常见的前端面试题提及:

从咱们打开浏览器输入一个网址到页面展现网页内容这段时间内,浏览器和服务端都发生了什么事情?

这个问题也有一种发散性更强的说法是:从咱们打开浏览器输入一个网址到页面展现网页内容这段时间内,都发生了什么事情?好比下面是百度FEX(Web 前端研发部)的面试题:

image.png | center | 827x435

https://github.com/fex-team/interview-questions

越详细越好,有人可能从移动光电鼠标提及:发光二极管发出的光线照亮鼠标底部表面,而后将鼠标底部表面反射回的一部分光线,通过一组光学透镜,传输到一个光感应器件内成像,当鼠标移动时,其移动轨迹便会被记录为一组高速拍摄的连贯图像,经过DSP分析图像,就能够判断鼠标的移动方向和移动距离,从而完成光标的定位。。。从鼠标键盘屏幕计算机、输入输出、操做系统、编译原理啥的提及,能够说一天,因此这里只关注浏览器和服务端主要的过程。

一个简化的过程是这样的:

  1. 在接收到用户输入的网址后,浏览器会开启一个线程来处理这个请求,对用户输入的URL地址进行分析判断,若是是HTTP协议就按照HTTP方式来处理。
  2. 调用浏览器引擎中的对应方法,好比WebView中的loadUrl方法,分析并加载这个URL地址。
  3. 经过DNS解析获取该网站地址对应的IP地址,查询完成后连同浏览器的Cookie、userAgent等信息向网站目的IP发出请求。
  4. 进行HTTP协议会话,浏览器客户端向Web服务器发送报文。
  5. 进入网站后台上的Web服务器处理请求,如Apache、Tomcat、Nginx、Node.js 等服务器。
  6. 进入部署好的后端应用,如PHP、Java、 JavaScript、 Python 等后端程序,找到对应的请求处理逻辑,这期间可能会读取服务器缓存或查询数据库等。
  7. 服务器处理请求并返回响应报文,此时若是浏览器访问过该页面,缓存上有对应资源,会与服务器最后修改记录对比,一致则返回304,不然返回200和对应的内容。
  8. 浏览器开始下载HTML文档(响应报头状态码为200时)或者从本地缓存读取文件内容(浏览器缓存有效或响应报头状态码为304时)。
  9. 浏览器根据下载接收到的HTML文件解析结构创建DOM文档树,并根据HTML中的标记请求下载指定的MIME类型文件(如CSS、JavaScript 脚本等),同时设置缓存等内容。
  10. 页面开始解析渲染DOM、CSS根据规则解析并结合DOM文档树进行网页内容布局和绘制渲染,JavaScript 根据DOM API操做DOM,并读取浏览器缓存、执行事件绑定等,页面整个展现过程完成。

下图是在服务端的一些展开:

image.png | center | 827x551.3333333333333

做为前端,重点会关注这个过程当中地址栏输入、网络请求、浏览器文档解析、渲染引擎、Javascript执行引擎,客户端存储等部分。因此咱们先了解一下浏览器:

浏览器一般由以下七个部分组成:

image.png | center | 500x339

  1. 用户界面(User Interface): 包括地址栏、前进/后退按钮、书签菜单等。除了浏览器主窗口显示请求的页面外,其余显示的各个部分都属于用户界面。
  2. 浏览器引擎(Browser engine): 在用户界面和呈现引擎之间传送指令,或者在客户端本地缓存中读写数据等,是浏览器中各个部分之间相互通讯的核心。
  3. 呈现(渲染)引擎(Rendering engine): 负责显示请求的内容,并将内容排版到浏览器中显示成有样式的界面。若是请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上,也叫排版引擎,常说的浏览器内核通常也主要是指呈现引擎。
  4. 网络功能模块(Networking): 用于网络调用,好比 HTTP 请求。它的接口与平台无关,并为全部平台提供底层实现。
  5. 用户界面后端(UI Backend): 用于绘制基本的窗口小部件,好比组合框和窗口。它公开了与平台无关的通用接口,而在底层使用操做系统的用户界面方法。
  6. JavaScript 解释器(Javascript Interpreter): 用于解析和执行 JavaScript 代码。
  7. 数据存储(Data Persistence): 持久层。浏览器须要在硬盘上保存各类数据,例如 Cookie、localStorage。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是一个完整(可是轻便)的浏览器内数据库。

浏览器呈现引擎简介

呈现引擎的做用嘛...固然就是“呈现”了,也就是在浏览器的屏幕上显示请求的内容。

目前,主流的浏览器内核有4类:

  • Trident:IE、360、搜狗等;
  • Gecko:Netscape、Firefox等;
  • Presto:Opera(新的 Opera 使用了 Blink 内核,是 Webkit 的一个分支,添加了一些优化特性);
  • Webkit:Safari、Chrome

呈现引擎一开始会从网络层获取请求文档的内容(内容的大小通常限制在 8000 个块之内)。

而后进行以下所示的基本流程:

image.png | center | 600x66

  1. 解析HTML构建DOM树时呈现引擎会先将HTML元素标签解析成由多个DOM元素对象节点组成的且具备节点父子关系的DOM树结构(DOM tree)
  2. 而后根据DOM树结构的每一个节点顺序提取计算使用的CSS规则,并从新计算DOM树结构的样式数据,生成一个带样式描述的DOM渲染树(render tree)对象。
  3. DOM渲染树生成结束后,进入渲染树的布局(Layout)阶段,即根据每一个渲染树节点在页面中的大小和位置,将节点固定到页面的对应位置上,这个阶段主要是元素的布局属性(例如position、float、margin 等属性)生效,即在浏览器中绘制页面上元素节点的位置。
  4. 接下来就是绘制阶段,将渲染树节点的背景、颜色、文本等样式信息应用到每一个节点上,这个阶段主要是元素的内部显示样式(例如color、background. text-shadow 等属性)生效,最终完成整个DOM在页面上的绘制(Painting)显示。

这是一个渐进的过程。为达到更好的用户体验,呈现引擎会力求尽快将内容显示在屏幕上。它没必要等到整个 HTML 文档解析完毕以后,就会开始构建呈现树和设置布局。在不断接收和处理来自网络的其他内容的同时,呈现引擎会将部份内容解析并显示出来。

image.png | center | 624x289

Webkit主流程

image.png | center | 624x290

Gecko主流程

两种呈现引擎工做流程的主要区别在于解析HTML或CSS文档生成呈现树的过程:

  • Webkit 内核中的HTML和CSS解析能够认为是并行的;
  • Gecko 则是先解析HTML,生成内容槽 (Content Sink)后再开始解析CSS。

这两种呈现引擎工做过程当中使用的描述术语也不同:

  • Webkit 内核解析后的渲染对象被称为呈现树(Render Tree),由“呈现对象”组成;
  • Gecko 内核解析后的渲染对象则称为Frame树(Frame Tree),每一个元素都是一个框架。

对于元素的放置:

  • WebKit 使用的术语是“布局(Layout)”;
  • Gecko 使用的术语是“重排(Reflow)”。

可是它们主要的流程是类似的,都通过HTML DOM解析、CSS样式解析、呈现树生成和呈现树绘制显示阶段。通常呈现引擎的解析过程当中都包含了HTML解析和CSS解析阶段,这也是呈现引擎解析流程中最重要的两个部分。

什么是解析

解析文档是指将文档转化成为有意义的结构,也就是可以让代码理解和使用的结构。解析获得的结果一般是表明了文档结构的节点树,它称做解析树或者语法树。

好比:2 + 3 - 1 解析后会变成下面的树:

image.png | center | 400x155

解析的过程能够分红两个子过程:词法分析(lexer)和语法分析(parser)。简单来讲,一个是拆分标记,一个是匹配规则。

image.png | center | 101x300

通常都会用一些工具来生成解析器,Webkit 用了两个知名的解析器生成器:词法分析器 Flex ,语法分析器 Bison (Lex/Yacc)。

HTML文档解析

<html>
  <body>
    <p>
      Hello World
    </p>
    <div> <img src="example.png"/></div>
  </body>
</html>

会被翻译成以下的DOM树:

image.png | center | 400x219

HTML的解析规则比较复杂,由于HTML有很高的容错性,好比:

</br><br><br /> 都要解析成空行;

<table>
    <table>
        <tr><td>inner table</td></tr>
    </table>
    <tr><td>outer table</td></tr>
</table>

<!-- 离散表格会被解析成 -->

<table>
    <tr><td>outer table</td></tr>
</table>
<table>
    <tr><td>inner table</td></tr>
</table>

CSS解析

Webkit会把CSS文件解析成 StyleSheet 对象,每一个对象都包含CSS规则,CSS 规则对象则包含选择器和声明对象,以及其余与 CSS 语法对应的对象。

image.png | center | 500x393

一个节点上若是有多条不一样的样式规则,会经过权重的方式来计算。通常认为是:

!important > 内联样式规则 > id选择器 > 类选择器 > 元素选择器

在 DOM 树构建的同时,浏览器还会构建另外一个树结构:呈现树。这是由可视化元素按照其显示顺序而组成的树,也是文档的可视化表示。它的做用是按照正确的顺序绘制内容。

image.png | center | 731x396

布局

呈现器在建立完成并添加到呈现树时,并不包含位置和大小信息。计算这些值的过程称为布局(layout)或重排(reflow)。

布局是一个递归的过程。它从根呈现器(对应于 HTML 文档的 <html> 元素)开始,而后递归遍历部分或全部的框架层次结构,为每个须要计算的呈现器计算几何信息。

布局分为全局布局和增量布局。全局布局是指触发了整个呈现树范围的布局,触发缘由可能包括:

  • 影响全部呈现器的全局样式更改,例如字体大小更改。
  • 屏幕大小调整。

增量布局是只对改变的部分(dirty呈现器)进行布局。

绘制

在绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。

和布局同样,绘制也分为全局(绘制整个呈现树)和增量两种。

在发生变化时,浏览器会尽量作出最小的响应。所以,元素的颜色改变后,只会对该元素进行重绘(repaint)。元素的位置改变后,只会对该元素及其子元素(可能还有同级元素)进行布局(layout)和重绘(repaint)。添加 DOM 节点后,会对该节点进行布局(layout)和重绘(repaint)。一些重大变化(例如增大“html”元素的字体)会致使缓存无效,使得整个呈现树都会进行从新布局(relayout)和绘制(repaint)。

浏览器数据持久化存储

浏览器缓存(Browser Caching)是浏览器端用于在本地保存数据并进行快速读取,以免重复资源请求的传输机制的统称。有效的缓存能够避免重复的网络资源请求并让浏览器快速地响应用户操做,提升页面内容的加载速度。浏览器端缓存的实现机制种类较多,通常能够分为九种:

  • HTTP文件缓存
  • LocalStorage
  • SessionStorage
  • indexDB
  • Web SQL
  • Cookie
  • CacheStorage
  • Application Cache
  • Flash缓存

图片描述

HTTP文件缓存

HTTP文件缓存是基于HTTP协议的浏览器端文件级缓存机制。在文件重复请求的状况下,浏览器能够根据HTTP响应的协议头信息判断是从服务器端请求文件仍是从本地读取文件,Chrome控制台下的Frames就能够查看浏览器的HTTP文件资源缓存列表内容。

HTTP文件缓存处理的流程图以下:

image.png | center | 747x464

好比:

image.png | center | 400x528.8000000000001

若是同时设置了 Expires 和 Cache-Control,则只有 Cache-Control 生效。

image.png | center | 500x553.5279805352799

localStorage

localStorage 是HTML5的一种本地缓存方案。支持目前的主流浏览器,在不一样浏览器中的长度限制各不相同,好比 Chrome 是 2.6MB,IE 是 5MB,这个长度限制是指单个域名下的 localStorage 大小限制。

image.png | left | 827x291

localStorage 不适合存放太多的数据,它遵循同源策略,可是它是持续存在的。

当浏览器进入隐私浏览模式,会建立一个新的、临时的数据库来存储localStorage的数据;当关闭隐私浏览模式时,该数据库将被清空并丢弃。

sessionStorage

sessionStorage 和 localStorage 相似,不过 sessionStorage 在浏览器关闭时会自动清空。用到的比较少,好比能够自动保存表单输入框的内容,若是浏览器因偶然因素被刷新了,输入框里面的内容会被恢复,所以写入的内容不会丢失。

Cookie

Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。一条Cookie记录主要由键、值、域、过时时间和大小组成,通常用于保存用户网站认证信息或个性化设置。Cookie 最大长度限制通常为 4KB。

持久型Cookie会保存在用户的硬盘上。

image.png | center | 827x264.6714150047483

WebSQL

WebSQL是独立于HTML5的单独规范,如今支持的浏览器不多,因此用的很少。

WebSQL容许用SQL语句进行查询,至关于集成在浏览器里的小型数据库。

image.png | center | 827x404.0266253869969

IndexDB

IndexDB支持的浏览器比较普遍,通常推荐使用IndexDB来进行大量数据的存储。浏览器对IndexDB的大小限制一般约为50MB。

DEMO:https://girliemac.com/stickies/

Application Cache

Application Cache 是一种容许浏览器经过manifest 配置文件在本地有选择性地存储JavaScript、CSS、图片等静态资源的文件级缓存机制。当页面不是首次打开时,经过一个特定的manifest文件配置描述来选择读取本地Application Cache里面的文件。
.
使用Application Cache来实现浏览器应用具备如下三个优点。

  1. 离线浏览:经过manifest配置描述来读取本地文件,用户可在离线时浏览完整的页面内容。
  2. 快速加载:因为缓存资源为本地资源,所以页面加载速度较快。
  3. 服务器负载小:只有在文件资源更新时,浏览器才会从服务器端下载,这样就减少了服务器资源请求的压力。

image.png | center | 827x327.6083995459705

Application Cache 已经开始慢慢被弃用,被 Service Worker 取代。

cacheStorage

cacheStorage是在ServiceWorker规范中定义的,可用于保存每一个ServiceWorker声明的Cache对象,是将来可能用来代替Application Cache的离线方案。

示例代码:

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('mysite-static-v3').then(function(cache) {
      return cache.addAll([
        '/css/whatever-v3.css',
        '/css/imgs/sprites-v6.png',
        '/css/fonts/whatever-v8.woff',
        '/js/all-min-v4.js'
        // etc
      ]);
    })
  );
});

演示:https://fed.renren.com/

具体使用能够参考:https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/

前端调试工具——Chrome 开发者工具

Chrome 开发者工具是一套内置于Google Chrome中的Web开发和调试工具,可用来对网站进行迭代、调试和分析,是前端开发人员最经常使用的调试工具之一。

元素面板(Elements)

使用 Chrome DevTools 的 Elements 面板检查和实时编辑页面的 HTML 与 CSS。

image.png | center | 747x433

🖥 演示:

  • 实时编辑DOM节点;
  • 查看元素事件侦听器;
  • 实时编辑样式;
  • 检查和编辑盒模型参数;
  • 查看本地更改;
  • 切换 Device Mode
  • 模拟传感器

控制台面板(Console)

控制台主要是用来查看动态信息和执行Javascript代码。

使用 Console API 能够向控制台写入信息、建立 JavaScript 配置文件,以及启动调试会话。

  • console.log
  • console.info
  • console.warn
  • console.error
  • console.assert
  • console.count
  • console.time
  • console.timeEnd
  • console.timeStamp
  • console.group
  • console.groupEnd
  • console.profile
  • console.profileEnd
  • console.trace
  • console.clear

🖥 演示:

console.time("Array initialize");
var array= new Array(1000000);
for (var i = array.length - 1; i >= 0; i--) {
    array[i] = new Object();
};
console.timeEnd("Array initialize");
var user = "jsmith", authenticated = false;
console.group("Authentication phase");
console.log("Authenticating user '%s'", user);
// authentication code here...
if (!authenticated) {
    console.log("User '%s' not authenticated.", user)
}
console.groupEnd();
function add(num) {
    if(num > 0) {
        console.trace('num:', num);
        return num + add(num - 1);
    } else {
        return 0;
    }
}
add(5);

便捷函数:

  • $_ 返回最近评估的表达式的值。
  • $(selector) <span data-type="color" style="color:rgb(33, 33, 33)">返回带有指定的 CSS 选择器的第一个 DOM 元素的引用。</span>
  • $$(selector) 返回与给定 CSS 选择器匹配的元素数组。

一些有趣的console:
https://www.zhihu.com/
https://www.tmall.com/
https://www.baidu.com/
http://www.iqiyi.com/

源代码面板(Sources)

源代码面板主要是用来查看和调试代码。

image.png | center | 827x394

🖥 演示:https://googlechrome.github.io/devtools-samples/debug-js/get-started

网络面板(Network)

咱们的开发不少都是基于HTTP接口的调试,因此网络面板很是重要。

Network 面板记录页面上每一个网络操做的相关信息,包括详细的耗时数据、HTTP 请求与响应标头和 Cookie等等。

Network 面板由五个窗格组成:

image.png | center | 827x423

  1. Controls。使用这些选项能够控制 Network 面板的外观和功能。
  2. Filters。 使用这些选项能够控制在 Requests Table 中显示哪些资源。按住 Cmd (Mac) 或 Ctrl (Windows/Linux) 并点击过滤器能够同时选择多个过滤器。
  3. Overview。 此图表显示了资源检索时间的时间线。若是看到多条竖线堆叠在一块儿,则说明这些资源被同时检索。
  4. Requests Table。 此表格列出了检索的每个资源。 默认状况下,此表格按时间顺序排序,最先的资源在顶部。点击资源的名称能够显示更多信息。 提示:右键点击 Timeline 之外的任何一个表格标题能够添加或移除信息列。
  5. Summary。 此窗格能够一目了然地查看请求总数、传输的数据量和加载时间。

Network 面板能够在页面加载期间捕捉屏幕截图。此功能称为幻灯片。

Network 面板突出显示两种事件:DOMContentLoaded 和 load。解析页面的初始标记时会触发 DOMContentLoaded。页面彻底加载时将触发 load。

🖥 演示:面板、幻灯片

Filter 文本字段还支持各类关键词,Ctrl+空格能够查看全部命令:

  • domain。仅显示来自指定域的资源。可使用通配符字符 (*) 来包含多个域。 例如,*.com 将显示来自以 .com 结尾的全部域名的资源。 DevTools 会使用它遇到的全部域填充自动填充下拉菜单。
  • has-response-header。显示包含指定 HTTP 响应标头的资源。 DevTools 会使用它遇到的全部响应标头填充自动填充下拉菜单。
  • is。使用 is:running 能够查找 WebSocket 资源。
  • larger-than。显示大于指定大小的资源(以字节为单位)。 将值设为 1000 等同于设置为 1k。
  • method。显示经过指定 HTTP 方法类型检索的资源。 DevTools 会使用它遇到的全部 HTTP 方法填充下拉菜单。
  • mime-type。显示指定 MIME 类型的资源。DevTools 会使用它遇到的全部 MIME 类型填充下拉菜单。
  • mixed-content。显示全部混合内容资源 (mixed-content:all),或者仅显示当前显示的资源 (mixed-content:displayed)。
    scheme。显示经过未保护 HTTP (scheme:http) 或受保护 HTTPS (scheme:https) 检索的资源。
  • set-cookie-domain。显示具备 Set-Cookie 标头并带有与指定值匹配的 Domain 属性的资源。 DevTools 会使用它遇到的全部 Cookie 域填充自动填充下拉菜单。
  • set-cookie-name。显示具备 Set-Cookie 标头而且名称与指定值匹配的资源。 DevTools 会使用它遇到的全部 Cookie 名称填充自动填充下拉菜单。
  • set-cookie-value。显示具备 Set-Cookie 标头而且值与指定值匹配的资源。 DevTools 会使用它遇到的全部 Cookie 值填充自动填充下拉菜单。
  • status-code。仅显示 HTTP 状态代码与指定代码匹配的资源。 DevTools 会使用它遇到的全部状态代码填充自动填充下拉菜单。

🖥 演示:Filter、复制、保存和清除网络信息

一个请求生命周期的主要阶段包括:

image.png | center | 827x347

  • 重定向

    • 当即开始 startTime。
    • 若是正在发生重定向,redirectStart 也会开始。
    • 若是重定向在本阶段末发生,将采集 redirectEnd。
  • 应用缓存

    • 若是是应用缓存在实现请求,将采集 fetchStart 时间。
  • DNS

    • domainLookupStart 时间在 DNS 请求开始时采集。
    • domainLookupEnd 时间在 DNS 请求结束时采集。
  • TCP

    • connectStart 在初始链接到服务器时采集。
    • 若是正在使用 TLS 或 SSL,secureConnectionStart 将在握手(确保链接安全)开始时开始。
    • connectEnd 将在到服务器的链接完成时采集。
  • 请求

    • requestStart 会在对某个资源的请求被发送到服务器后当即采集。
  • 响应

    • responseStart 是服务器初始响应请求的时间。
    • responseEnd 是请求结束而且数据完成检索的时间。

Timing 标签能够查看网络请求完整的耗时信息:

image.png | center | 500x433.2688588007737

  • Queuing:请求排队时间,通常排队是由于请求优先级低,或者被暂停(在 HTTP 1 上,浏览器仅容许每一个源拥有六个 TCP 链接)等。
  • Stalled/Blocking:请求等待发送所用的时间。
  • Proxy Negotiation:与代理服务器链接协商所用的时间。
  • DNS Lookup:执行 DNS 查询所用的时间。
  • Initial Connection / Connecting:创建链接所用的时间,包括 TCP 握手/重试和协商 SSL 的时间。
  • SSL:完成 SSL 握手所用的时间。
  • Request Sent / Sending:发出网络请求所用的时间。 一般不到一毫秒。
  • Waiting (TTFB):等待初始响应所用的时间,也称为至第一字节的时间。 此时间将捕捉到服务器往返的延迟时间,以及等待服务器传送响应所用的时间。
  • Content Download / Downloading:接收响应数据所用的时间。

经过 Network 面板能够发现大量可能的问题,好比:

有不少被中止的条目:
代表正在从单个域检索太多的资源。在 HTTP 1.0/1.1 链接上,Chrome 会将每一个主机强制设置为最多六个 TCP 链接。要解决此问题,须要实现域分片。也就是在应用上设置多个子域,以便提供资源。好比京东的首页,就有不少的子域名来加载图片:

image.png | center | 500x750

至第一字节的时间很长:
又称:大片绿色,通常是由于:客户端与服务器之间的网络条件较差或者服务器应用的响应慢。若是本地托管后 TTFB 仍然漫长,那么问题通常出在客户端与服务器之间的网络上。

image.png | center | 257x247

达到吞吐量能力:
又称:大片蓝色。通常是返回的报文太大了,首要的解决办法是减小发送的字节数。

image.png | center | 410x243

🖥 演示:京东首页 https://www.jd.com/;使用 DevTools 能够模拟不一样的网络条件,解决加载时间问题。

性能面板(Performance)

性能面板以前叫 Timeline,在 Chrome 57 以后改名为性能面板。主要用来记录和分析应用在运行时的全部活动。

Performance 面板包含如下四个窗格:

  1. Controls。开始记录,中止记录和配置记录期间捕获的信息。
  2. Overview。 页面性能的高级汇总。
  3. 火焰图。 CPU 堆叠追踪的可视化。能够在火焰图上看到一到三条垂直的虚线。蓝线表明 DOMContentLoaded 事件。 绿线表明首次绘制的时间。 红线表明 load 事件。
  4. Details。选择事件后,此窗格会显示与该事件有关的更多信息。 未选择事件时,此窗格会显示选定时间范围的相关信息。

image.png | center | 827x649

Overview 窗格包含如下三个图表:

image.png | center | 827x150

  1. FPS。每秒帧数。绿色竖线越高,FPS 越高。 FPS 图表上的红色块表示长时间帧,极可能会出现卡顿。
  2. CPU。 CPU 资源。此面积图指示消耗 CPU 资源的事件类型。
  3. NET。每条彩色横杠表示一种资源。横杠越长,检索资源所需的时间越长。 每一个横杠的浅色部分表示等待时间(从请求资源到第一个字节下载完成的时间)。横杠按照如下方式进行彩色编码:

    • HTML 文件为<span data-type="color" style="color:rgb(110, 161, 226)">蓝色</span>
    • 脚本为<span data-type="color" style="color:rgb(239, 196, 87)">黄色</span>
    • 样式表为<span data-type="color" style="color:rgb(155, 127, 230)">紫色</span>
    • 媒体文件为<span data-type="color" style="color:rgb(116, 178, 102)">绿色</span>
    • 其余资源为<span data-type="color" style="color:rgb(179, 179, 179)">灰色</span>

通常性能面板主要用于优化页面的加载时间,提升页面的流畅度,对于用户量很大的页面调优很是有用。好比:

  • 经过找出较长的Evaluate Script 事件,经过 JS 分析器获取究竟调用了哪些 JS 函数以及调用每一个函数须要多长时间的更详细信息。
  • 样式更改开销较大,在这些更改会影响 DOM 中的多个元素时更是如此。经过检查大型 Recalculate Style 事件的记录(以紫色显示),若是样式更改须要较长时间,对性能的影响会很是大。
  • “布局抖动”是指反复出现强制同步布局状况。 这种状况会在 JavaScript 从 DOM 反复地写入和读取时出现,将会强制浏览器反复从新计算布局。经过观察红色竖线标记的 Layout 事件,能够发现布局方面的问题。
  • 绘制是填充像素的过程。这常常是渲染流程开销最大的部分。 在任何状况下注意到页面出现卡顿现象,颇有可能存在绘制问题。

🖥 演示:快速肯定绘制瓶颈,Paint flashing(在Rendering面板中),打开此选项后,每次发生绘制时,Chrome 将让屏幕闪烁绿色。https://www.jd.com/

内存面板(Memory)

内存面板以前叫 Profile,在 Chrome 57 以后改名为内存面板。主要用于查找影响页面性能的内存问题,包括内存泄漏、内存膨胀和频繁的垃圾回收。

用户通常会经过如下方式察觉到有内存问题:

  • 页面的性能随着时间的延长愈来愈差。 这多是内存泄漏的症状。 内存泄漏是指,页面中的错误致使页面随着时间的延长使用的内存愈来愈多。
  • 页面的性能一直很糟糕。 这多是内存膨胀的症状。 内存膨胀是指,页面为达到最佳速度而使用的内存比本应使用的内存多。
  • 页面出现延迟或者常常暂停。 这多是频繁垃圾回收的症状。 垃圾回收是指浏览器收回内存。 浏览器决定什么时候进行垃圾回收。 回收期间,全部脚本执行都将暂停。所以,若是浏览器常常进行垃圾回收,脚本执行就会被频繁暂停。

内存泄漏很容易肯定。若是网站使用的内存愈来愈多,则说明发生内存泄漏。内存膨胀比较难以界定,通常会考虑网站常常访问的设备的配置,说到这里,插播一下RAIL模型。

使用 RAIL 模型评估性能

RAIL 是一种以用户为中心的性能模型。每一个网络应用均具备与其生命周期有关的四个不一样方面,且这些方面以不一样的方式影响着性能:

image.png | center | 827x300

让用户成为性能工做的中心。用户花在网站上的大多数时间不是等待加载,而是在使用时等待响应。

延迟与用户反应:

0 - 16 毫秒 用户能够感知每秒渲染 60 帧的平滑动画转场。也就是每帧 16 毫秒
0 - 100 毫秒 在此时间窗口内响应用户操做,他们会以为能够当即得到结果。时间再长,操做与反应之间的链接就会中断。
100 - 300 毫秒 用户会遇到轻微可觉察的延迟。
300 - 1000 毫秒 对于网络上的大多数用户,这个时间段表明任务还在继续,是合理的延迟。
1000+ 毫秒 超过 1 秒,用户的注意力将离开他们正在执行的任务。
10,000+ 毫秒 用户感到失望,可能会放弃任务;以后他们或许不会再回来。

响应:尽可能在 100 毫秒之内响应,对于须要超过 500 毫秒才能完成的操做,要始终提供反馈。

动画:尽可能在 10 毫秒内生成一帧,由于浏览器须要花费时间将新帧绘制到屏幕上,因此只有 10 毫秒来执行代码。

空闲:最大程度增长空闲时间,利用空闲时间完成推迟的工做。例如,尽量减小预加载数据,以便应用快速加载,并利用空闲时间加载剩余数据。

加载:尽可能在 1000 毫秒之内呈现内容。

使用 Chrome 任务管理器实时监视内存使用,打开任务管理器,右键点击任务管理器的表格标题并启用 JavaScript memory。

内存能够表示为一个由多个互连的点组成的图表:

image.png | center | 538x339

对象可经过如下两种方式占用内存:

  • 直接经过对象自身占用。
  • 经过保持对其余对象的引用隐式占用,这种方式能够阻止这些对象被垃圾回收器(GC)自动处置。

堆分析器中:

  • Shallow Size(浅层大小),这是对象自身占用内存的大小。
  • Retained Size(保留大小),这是将对象自己连同其相关对象一块儿删除后释放的内存大小。

image.png | center | 775x257

内存图从根开始,根能够是浏览器的 window 对象或 Node.js 模块的 Global 对象。距离(Distance)字段,表示与 GC 根之间的距离。

image.png | center | 478x295

任何没法从根到达的对象都会被 GC 回收。

🖥 演示:按函数调查内存分配 Allocation sampling

应用面板(Application)

应用面板用来检查加载的全部资源,包括IndexedDB与Web SQL数据库,本地和会话存储,cookie,应用程序缓存,图像,字体和样式表。在持久化存储已经聊过。

🖥 演示:查看和编辑本地存储。

安全面板(Security)

安全面板主要是用来查看页面的总体安全性。

🖥 演示:

非安全页面会经过消息 This page is not secure. 提示

比较:https://www.google.com/

其余面板

🖥 演示:Audit 基于 Lighthouse,能够用于分析页面性能。

Chrome 的高性能网络(High Performance Networking)

Chrome 从2008年推出以来,如今已经在全世界浏览器市场中占了第一的份额,并且不断的在增加。

image.png | center | 827x136

驱动 Chrome 浏览器发展的主要是这几个原则:

  • Speed: 作最快的浏览器。
  • Security: 给用户提供最安全的上网环境。
  • Stability: 提供一个健壮且稳定的Web应用平台。
  • Simplicity: 提供简洁的用户体验。

这里所说的高性能网络,就是遵循了第一个原则:Speed。

以前说过一个网络请求的生命周期中间有不少步骤:

image.png | center | 635x348

这中间DNS查找、TCP三次握手、SSL握手等等,都会耗费必定的时间,对于响应比较快的请求,可能80%以上的开销都在网络上。

Chrome 的多进程架构为浏览器的网络请求处理带来了重要意义,它目前支持四种不一样的执行模式:

  • Process-per-site-instance:就是打开一个网站,而后从这个网站开的每个Tab属于一个进程。优势:隔离性很强;缺点:内存开销大,实现复杂。
  • Process-per-site:同域名的网站Tab放在一个进程。
  • Process-per-tab:一个Tab一个进程。
  • Single process:传统模式,只有一个进程。

默认状况下,桌面的 Chrome 浏览器使用 process-per-site 模式, 将不一样的网站页面隔离起来, 相同网站的页面组织在一块儿。

Chrome Predictor 预测功能优化:

Chrome会随着使用变得更快。Predictor 会观察和学习当前网络活动方式,提早预估用户下一步的操做。好比:

  • 用户将鼠标停留在一个连接上,就预示着一个用户的偏好以及下一步的浏览行为。这时 Chrome 就能够提早进行 DNS Lookup 及 TCP 握手。用户的点击操做平均须要将近 200ms,在这个时间就可能处理完 DNS 和 TCP 相关的操做, 也就是省去几百毫秒的延迟时间。
  • 当在地址栏触发高可能性选项时,就一样会触发一个 DNS lookup 和 TCP 预链接(pre-connect),甚至在一个不可见的页签中进行预渲染(pre-render)。
  • 咱们每一个人都一串每天会访问的网站, Chrome 会研究在这些页面上的子资源, 而且尝试进行预解析(pre-resolve), 甚至可能会进行预加载(pre-fetch)以优化浏览体验。

Chrome采用了四种核心优化技术:

  • DNS pre-resolve:DNS 预解析,提早解析主机地址,以减小 DNS 延迟。
  • TCP pre-connect:TCP 预链接,提早链接到目标服务器,以减小 TCP 握手延迟。
  • Resource prefetching:资源预加载,提早加载页面的核心资源,以加快页面显示。
  • Page prerendering:页面预渲染,提早获取整个页面和相关子资源。

🖥 演示:chrome://predictors/

Chrome会维护用户输入的前缀的历史记录,建议的操做以及每一个前缀的命中率。好比我平时输入了 appl,那么 100% 是要访问苹果官网。

TL;DR

此次主要聊了前端大概的演变,浏览器的一些基础,以后有时间会聊聊协议、安全、框架、实践、跨栈之类的,你们辛苦!

相关文章
相关标签/搜索