浏览器渲染HTML的过程和原生JS获取样式

今天来说说

  • 浏览器如何渲染HTML
  • 如何加快浏览器的渲染速度
  • 如何用 JS 获取浏览器样式

1. 首先我们要知道样式是在什么时候被渲染的。浏览器是如何渲染的?

前端面试-浏览器渲染机制
浏览器渲染-这篇写得非常好

  • URL请求对应的资源
  • HTML解析文件,并且构建 DOM 树
  • 构建DOM的时候 遇到 JS 和 CSS, 控制权转让
  • JS解析或者CSS 解析器 解析完当前元素,继续 解析 下个元素,直至 DOM树构建完成
  • DOM 树构建完成,浏览器 把 DOM 树的 一些 不可见元素去掉。此后,与 CSS DOM 合成一颗 render 树。
  • 浏览器根据这棵 render 树,计算出 各个节点所在屏幕的位置。这个位置叫做 layout,输出layout 树。
  • 最后根据 layout 树,将页面 渲染至 屏幕。

A. 为了更好的用户体验,渲染引擎会 尽可能快 的将内容呈现到屏幕上,并不会等到所有的 html 都解析完成采取构建和布局 render 树。(解析一部分,显示一部分,同时,可能还在网络下载其他内容)

B. 因为上面那句话。浏览器 发现了一个 img 标签的请求,向服务器发出请求,此时浏览器不会等图片下载完,而是继续渲染后面的代码。

C. 服务器返回图片文件,由于图片占用了一定面积,影响后面的布局。需要回头重新渲染这部分代码。

D. 为了确保 DOM 树早于 脚本执行,防止 脚本阻塞了 DOM树的构建,页面持续空白。所以,我们通常将script标签放在页面底部。或者使用window.onload.

  • Reflow(回流):浏览器要花时间去渲染,当它发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。
  • Repaint(重绘):如果只是改变了某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的repaint,重画某一部分。
Reflow要比Repaint更花费时间,也就更影响性能。所以在写代码的时候,要尽量避免过多的Reflow。

2. 如何加快浏览器的渲染速度,提高 Web 网站的性能呢?

  • 减少文件数量。这也是 Webpack 火的原因。JS 都打包成 1个了。css、js合并。
  • 减少请求。域名查询、域名解析,也是消耗时间的。
  • 使用CDN。原因同上面的原因。
  • 页面减肥。删除不必要的空格。 这也是那些 gulp、webpack 插件火的原因。
  • 缓存重用数据。
  • 指定图像和table的大小。上面说了。浏览器可以立即决定大小的话,就不用等图片请求下载完成后,重新布局。少 回流、回流、回流 reflow。

image 使用 width 和 height。

3. 如何用 JS 获取浏览器样式

首先来介绍一下样式表的种类

  • 内嵌样式
  • 内部样式
  • 外部样式表

网上疯狂查找,一下就出了很多答案。再来看一下张鑫旭大佬有没有写什么有趣的东西。一看,果然有东西,写的还是那么有趣。完美清晰,从鞋子到脚。

A. 采用 window.getComputedStyle

getComputedStyle 是一个可以获取当前元素所有 最终使用的 CSS属性值。返回的是一个 CSS 样式声明对象。

使用语法:const style = window.getComputedStyle("元素", "伪类")
,伪类不存在则使用 null / 也可以直接不写。

const oBox = document.querySelector("#box");
const style = window.getComputedStyle(oBox);
console.log(style.height);

注意事项:

  • 1.IE8 不兼容。
  • 2.只读、不可写。

B. 采用 element.style

能读能写,能屈能伸。

使用语法(不是直接写在内嵌 style 里面的获取不到):

<div id="box" style="height:100px;"></div>
  const oBox = document.querySelector("#box");
  console.log(oBox.style.height);

注意事项:

  • 1.只能获取元素 style 属性里面的样式。内嵌样式、只有内嵌,所以它基本用不上。

C. document.defaultView.getComputedStyle

jQuery源码采用的。

使用方法

  const style1 = document.defaultView.getComputedStyle(oBox, null);
  const style2 = window.getComputedStyle(oBox, null);
  console.log(style1, style2);   //  长的差不多
  console.log(style1 == style2); //  false,有细微的差别
  console.log(style1.height === style2.height);  // true,获取的样式一致

注意事项:
具体和上面的方法A是一样的。主要原因可能是 不一定平台 用 Windows。

D. element.currentStyle。张鑫旭大佬说的 IE 自娱自乐的属性。 坑爹的 IE 啊。

从作用上来说 getComputedStyle 和 currentStyle 属性走得很近。

使用方法:

看起来好像和 element.style 很像,但是其实两者差很多。
作用上 和 getComputedStyle 一样。不过,currentStyle 没法获取伪类的样式。

var oBox = document.querySelector("#box");
  console.log(oBox.currentStyle.height);
坑爹的还不让用 const。愿我以后不写 IE8 兼容。谢谢上天。

注意事项:

  • 不支持伪类样式获取。
posted @ 2017-05-19 19:57  海客无心x  阅读(797)  评论(0)    收藏  举报