为什么每个前端开发者都要理解页面的渲染?
浏览器是怎样渲染一个页面的?
- 由从服务器接收到的 HTML 形成 DOM(文档对象模型)。
- 样式被加载和解析,形成 CSSOM(CSS 对象模型)。
- 紧接着 DOM 和 CSSOM 创建了一个渲染树,这个渲染树是一些被渲染对象的集合( Webkit 分别叫它们”renderer”和”render object”,而在Gecko 引擎中叫”frame”)。除了不可见的元素(比如 head 标签和一些有 display:none 属性的元素),渲染树映射了 DOM 的结构。在渲染树中,每一个文本字符串都被当做一个独立的 renderer。每个渲染对象都包含了与之对应的计算过样式的DOM 对象(或者一个文本块)。换句话说,渲染树描述了 DOM 的直观的表现形式。
- 对每个渲染元素来说,它的坐标是经过计算的,这被叫做“布局(layout)”。浏览器使用一种只需要一次处理的“流方法”来布局所有元素(tables需要多次处理)。
- 最后,将布局显示在浏览器窗口中,这个过程叫做“绘制(painting)”。
重绘
重排
- DOM 操作(如元素增、删、改或者改变元素顺序)。
- 内容的改变,包括 Form 表单中文字的变化。
- 计算或改变 CSS 属性。
- 增加或删除一个样式表。
- 改变”class”属性。
- 浏览器窗口的操作(改变大小、滚动窗口)。
- 激活伪类(如:hover状态)。
浏览器如何优化渲染?
- var $body = $('body');
- $body.css('padding', '1px'); // 重排, 重绘
- $body.css('color', 'red'); // 重绘
- $body.css('margin', '2px'); // 重排, 重绘
- // 实际上只有一次重排和重绘被执行。
如上面所说,访问一个元素的属性会进行一次强制重排。如果我们给上面的代码加上一行读取元素属性的代码,这个情况就会出现:
- var $body = $('body');
- $body.css('padding', '1px');
- $body.css('padding'); // 这里读取了一次元素的属性,一次强制重排就会发生。
- $body.css('color', 'red');
- $body.css('margin', '2px');
- .has-transition {
- -webkit-transition: margin-left 1s ease-out;
- -moz-transition: margin-left 1s ease-out;
- -o-transition: margin-left 1s ease-out;
- transition: margin-left 1s ease-out;
- }
然后进行实现:
- //我们的元素默认有"has-transition"属性
- var $targetElem = $('#targetElemId');
- //删除包含transition的class
- $targetElem.removeClass('has-transition');
- // 当包含transition的class已经没了的时候,改变元素属性
- $targetElem.css('margin-left', 100);
- // 再将包含transition的class添加回来
- $targetElem.addClass('has-transition');
- // 改变元素属性
- $targetElem.css('margin-left', 50);
- //删除包含transition的class
- $(this).removeClass('has-transition');
- // 改变元素属性
- $(this).css('margin-left', 100);
- //触发一次强制重排,从而使变化了的class或属性能够立即执行。
- $(this)[0].offsetHeight; // offsetHeight仅仅是个例子,其他的属性也可以奏效。
- // 再将包含transition的class添加回来
- $(this).addClass('has-transition');
- // 改变元素属性
- $(this).css('margin-left', 50);
现在这段代码如我们所期望的运行了。
实际的优化建议
- 创建合法的 HTML 和 CSS ,别忘了制定文件编码,Style 应该写在 head 标签中,script 标签应该加载 body 标签结束的位置。
- 试着简化和优化 CSS 选择器(这个优化点被大多数使用 CSS 预处理器的开发者忽略了)。将嵌套层数控制在最小。以下是 CSS 选择器的性能排行(从最快的开始):
- ID选择器:#id
- class选择器: .class
- 标签: div
- 相邻的兄弟元素:a + i
- 父元素选择器: ul > li
- 通配符选择器: *
- 伪类和伪元素: a:hover ,你应该记住浏览器处理选择器是从右向左的,这也就是为什么最右面的选择器会更快——#id或.class。
-
- div * {...} // bad
- .list li {...} // bad
- .list-item {...} // good
- #list .list-item {...} // good
- 在你的脚本中,尽可能的减少 DOM 的操作。把所有东西都缓存起来,包括属性和对象(如果它可被重复使用)。进行复杂的操作的时候,最好操作一个“离线”的元素(“离线”元素的意思是与 DOM 对象分开、仅存在内存中的元素),然后将这个元素插入到 DOM 中。
- 如果你使用 jQuery,遵循jQuery 选择器最佳实践
- 要改变元素的样式,修改“class”属性是最高效的方式之一。你要改变 DOM 树的层次越深,这一条就越高效(这也有助于将表现和逻辑分开)。
- 尽可能的只对 position 为 absolute 或 fix 的元素做动画。
- 当滚动时禁用一些复杂的 :hover动画是一个很好的主意(例如,给 body 标签加一个 no-hover 的 class)关于这个主题的文章。

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

The official account web page update cache, this thing is simple and simple, and it is complicated enough to drink a pot of it. You worked hard to update the official account article, but the user still opened the old version. Who can bear the taste? In this article, let’s take a look at the twists and turns behind this and how to solve this problem gracefully. After reading it, you can easily deal with various caching problems, allowing your users to always experience the freshest content. Let’s talk about the basics first. To put it bluntly, in order to improve access speed, the browser or server stores some static resources (such as pictures, CSS, JS) or page content. Next time you access it, you can directly retrieve it from the cache without having to download it again, and it is naturally fast. But this thing is also a double-edged sword. The new version is online,

The article discusses using HTML5 form validation attributes like required, pattern, min, max, and length limits to validate user input directly in the browser.

This article demonstrates efficient PNG border addition to webpages using CSS. It argues that CSS offers superior performance compared to JavaScript or libraries, detailing how to adjust border width, style, and color for subtle or prominent effect

Article discusses best practices for ensuring HTML5 cross-browser compatibility, focusing on feature detection, progressive enhancement, and testing methods.

The article discusses the HTML <datalist> element, which enhances forms by providing autocomplete suggestions, improving user experience and reducing errors.Character count: 159

The article discusses the HTML <progress> element, its purpose, styling, and differences from the <meter> element. The main focus is on using <progress> for task completion and <meter> for stati

This article explains the HTML5 <time> element for semantic date/time representation. It emphasizes the importance of the datetime attribute for machine readability (ISO 8601 format) alongside human-readable text, boosting accessibilit

The article discusses the HTML <meter> element, used for displaying scalar or fractional values within a range, and its common applications in web development. It differentiates <meter> from <progress> and ex
