页面从输入 URL 到页面加载显示完成,性能优化

URL规范HTTP协议DNSCDN数据库查询、 到浏览器流式解析CSS规则构建layoutpaintonload/domreadyJS执行JS API绑定等等;

详细版:

  1. 预处理URL,浏览器会开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;
  2. 调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法;
  3. 通过DNS解析获取网址的IP地址,设置 UA 等信息发出第二个GET请求;
  4. 进行HTTP协议会话,客户端发送报头(请求报头);
  5. 进入到web服务器上的 Web Server,如 Apache、Tomcat、Node.JS 等服务器;
  6. 进入部署好的后端应用,如 PHP、Java、JavaScript、Python 等,找到对应的请求处理;
  7. 处理结束回馈报头,此处如果浏览器访问过,缓存上有对应资源,会与服务器最后修改时间对比,一致则返回304;
  8. 浏览器开始下载html文档(响应报头,状态码200),同时使用缓存;
  9. 文档树建立,根据标记请求所需指定MIME类型的文件(比如css、js),同时设置了cookie;
  10. 页面开始渲染DOM,JS根据DOM API操作DOM,执行事件绑定等,页面显示完成。

Webkit的渲染引擎网页渲染过程

  

资源加载顺序

1、Layout和Paint

  当渲染对象被创建并添加到树中,它们并没有位置和大小,计算这些值的过程称为 layout reflow。所以在元素的大小和位置发生变化时都会触发 layout

  浏览器针对Layout做了一定优化,如采用Dirty bit系统,只针对具有dirty标记的元素进行重新layout,即增量layout,且此过程是异步的;如果元素只是位置发生变化,其大小从缓存里读取,就不用再次计算。

  绘制阶段,遍历渲染树并调用渲染对象的paint方法将它们的内容显示在屏幕上,绘制使用UI基础组件。当元素的位置和大小没有变化,如改变背景颜色等等,只会进行重新paint。Paint也采用dirty机制进行增量Paint

2、CSS阻塞

  CSS会阻塞渲染树的构建,不阻塞DOM构建,但是在CSSOM构建完成之前,页面不会开始渲染(一片空白),

  与js不一样,js虽然会阻塞后续DOM构建,但是前面已经就绪的内容会进行渲染。

  CSS虽然不阻塞DOM构建,但是会阻塞后面js的执行,从而间接阻塞完整DOM的构建,  

 针对性优化

  • 尽早加载css文件并生成CSSOM.
  • 不使用@import
  • 利用媒体查询,处理特定设备下的CSS,以减少不必要的阻塞. 

3、JS阻塞

  JS默认也是会阻塞DOM和渲染树的构建。HTML解析器在遇到脚本文件时,默认为停下来去获取脚本(不考虑资源预加载优化),然后执行,期间阻塞DOM构建

4、defer脚本

  声明为defer的脚本会延迟到DOM构建完成后(DOMInteractive事件),DOMContentLoadedwindow.onload事件之前执行(但依然会被浏览器的预加载策略提前下载)。只针对外联脚本有效。多个defer会按照先后顺序串行执行。  

<script type="text/javascript" src="/js/script1.js" defer></script>
<script defer>
    console.log('inserted');
</script>

5、async脚本

  声明 为异步的脚本会异步地下载和执行,会在window.onload事件之前执行,但是可能会在DOMContenLoaded事件前后执行。

6、资源优先级

  样式和脚本的优先级是比图片更高的,因为这两个都具有阻塞性,浏览器让它们尽快下载下来。

  第一个图片资源会和css一起下载,但浏览器发现后面还有许多图片就会优先去下载脚本文件。

浏览器优化策略

1、DNS预解析 DNS-Prefetch

  通过 DNS 预解析来告诉浏览器未来我们可能从某个特定的 URL 获取资源,当浏览器真正使用到该域中的某个资源时就可以尽快地完成 DNS 解析。

例如,我们将来可能从example.com获取图片或音频资源,那么可以在文档顶部的<head>标签中加入以下内容:

<link rel="dns-prefetch" href="//example.com">

2、预连接 Preconnect

  现代浏览器都试着预测网站将来需要哪些连接,然后预先建立 socket 连接,从而消除昂贵的 DNS 查找、TCP 握手和 TLS 往返开销。

  然而,浏览器还不够聪明,并不能准确预测每个网站的所有预链接目标。好在,在 Firefox 39 和 Chrome 46 中我们可以使用preconnect告诉浏览器我们需要进行哪些预连接

<link rel="preconnect" href="http://example.com">

3、预获取 Prefetching

  如果我们确定某个资源将来一定会被使用到,我们可以让浏览器预先请求该资源并放入浏览器缓存中。例如,一个图片和脚本或任何可以被浏览器缓存的资源:

<link rel="prefetch" href="image.png">

4、Subresources

  这是另一个预获取方式,这种方式指定的预获取资源具有最高的优先级,在所有prefetch项之前进行:

<link rel="subresource" href="styles.css">

5、预渲染 Prerender

  这类似于在一个隐藏的 tab 页中打开了某个链接 – 将下载所有资源、创建 DOM 结构、完成页面布局、应用 CSS 样式和执行 JavaScript 脚本等。

  当用户真正访问该链接时,隐藏的页面就切换为可见,使页面看起来就是瞬间加载完成一样。Google 搜索在其即时搜索页面中已经应用该技术多年了,微软也宣称将在 IE11 中支持该特性。

<link rel="prerender" href="http://example.com">

****https://github.com/laoqiren/web-performance,如上所述均出自该地

猜你喜欢

转载自www.cnblogs.com/slightFly/p/11882310.html