前端开发工程师应知应会之网页渲染(翻译)

作者:Alexander Skutin , 2014.5.26 . 由Max shirshin与2014年6月30日翻译(俄语 -> 英语)

现今我们应更加注重网页渲染,及其在web开发中的重要性。虽然很多文章都曾谈到这一主题,但大多是分散和割裂的。譬如为了对这个主题有更全面的认识需要去搜索很多的信息来源,而这也是笔者决定写这篇文章的原因。笔者相信本篇文章会有益于初级开发者,当然对希望能够更新和整理已有知识的中高级开发者同样能够有所裨益。

当页面布局定义完成后,页面渲染的过程与样式和脚本所承担的重要角色一样,也需要在初期就开始进行优化。专业的开发者需要了解这些技巧以避免性能的问题。

本篇文章并不会详细介绍浏览器的内部工作机制,但将会提供一些通用的规则。这是由于不同的浏览器引擎有着不同的工作方式,太针对与某一个特定浏览器的研究会使这个过程变得过于复杂。

浏览器如何渲染网页?

首先概述浏览器渲染网页的过程:

1、文档对象模型(Document Object Model = DOM)将首先从来自于服务器的HTML中生成。

2、加载并解析样式,形成样式对象模型(CSS Object Mode = CSSOM)。

3、在DOM和CSSOM上层,创建一个渲染树,这是由将被渲染的对象形成的集合(webkit内核称这些对象为“渲染者”或“渲染对象”,在Gecko内核中则称为“帧”)。渲染树会影响DOM结构,但隐藏元素则不在此列(例如<head>标签,或具有display:none属性的元素)。在渲染树中的每个文本字符串都被表述为一个单独的渲染对象,而每个渲染对象都将包含其应有的DOM结构(或文本块)以及计算后的样式。从另一个角度上说,这个渲染树描述了DOM中的可见表征。

4、计算渲染树中元素的坐标,从而成为“层”。浏览器使用一系列方法(这一系列方法仅需要一个节拍(pass))来放置所有的元素(表格需要多个节拍)。

5、最后,页面将在浏览器窗口中显示出来,这个过程称为“绘制”。

当用户与页面交互时,或者脚本改变页面时,前面提及的这些操作都会重复执行,页面布局改变时同样如此。

重绘

当改变了元素样式,而这个变动并不会影响元素在页面中的位置时(例如background-color,border-color,visibility),浏览器会依据新的样式仅重绘这个元素(即重绘和重新应用样式会发生)

重新布局

当改变影响了文档内容、结构、或元素位置时,布局会重新应用和生成。这些改变通常由以下行为触发:

  • DOM操作(元素的添加、删除、修改以及调整顺序)
  • 内容变更,包括表单域中的文字修改
  • CSS属性的计算和修改
  • 样式表的添加和移除
  • class属性的修改
  • 浏览器窗口变动(大小、滚动)
  • 伪类激活(:hover)

如何优化浏览器渲染

浏览器会尽可能的将重绘和重排限制在受影响的元素区域内。例如,对一个绝对定位/悬浮定位的元素尺寸大小的变更会仅仅影响这个元素及他的后代,然而一个静态定位元素的尺寸变化会让在其之后的所有元素都触发重新布局。

另一个优化的技巧是,当运行javascript代码时,浏览器会缓存这些变更,然后在代码运行之后,将变更放到一个单独的节拍中再应用。例如,下面的代码会仅触发一次重绘和重新布局。

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‘);

最终,我们将造成两次重排而并非只是一次。正因如此,你需要将获取元素属性归到一次,来优化性能。(来看示例

当你不得不触发强制重绘时,会有一些状况发生。例如:我们将要把一条相同的属性两次应用到一个相同的元素上。最初,这个元素会以无动画的方式设为100px,然后需要带动画的调整为50px。你可以通过这个示例研究,但我会更详细的描述这个情况。

我们首先创建一个具有transition属性的css类

.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‘);

//移除has-transition类

$targetElem.removeClass(‘has-transition‘);

// 在css类不再存在后,改变这个属性确认动画已经去除

$targetElem.css(‘margin-left‘, 100);

// 增加has-transition类

$targetElem.addClass(‘has-transition‘);

// 修改属性

$targetElem.css(‘margin-left‘, 50);

这个实现并不会像期望的方式工作。这些改变被缓存起来,并会在最后的代码块中应用。因为我们需要一个强制的重排,通过以下方式可以实现:

//移除has-transition类

$(this).removeClass(‘has-transition‘);

//修改属性

$(this).css(‘margin-left‘, 100);

// 触发强制重排,从而在class和属性中的改变可以立刻生效

$(this)[0].offsetHeight;

// 示例,其他的属性也可以实现

// 增加has-transition类

$(this).addClass(‘has-transition‘);

// 修改属性

$(this).css(‘margin-left‘, 50);

现在将会按设想中的工作了。

实际开发中的优化建议

通过总结一些有用的信息,(作者)提供以下建议:

  • 创建有效的html和css,但不要忘记明确文档编码。样式可以添加到<head>中,脚本则添加到<body>的尾部。
  • 尝试简化和优化css选择器(使用CSS预处理的开发者通常不会注意这种优化方法),尽量保持低级的css嵌套。这也是css选择器标识性能的方法(从最快的那个开始)。
    • 1、标识符 #id
    • 2、类 .class
    • 3、标签: div
    • 4、兄弟选择器:a+i
    • 5、邻接父子节点选择器 ul > li
    • 6、通用选择器:*
    • 7、特性选择器:input[type="text"]
    • 8、伪类和伪元素:a:hover。你需要记住,浏览器处理CSS选择器的顺序是从右至左,这就是为什么最右边的选择器应当是最快的那种,比如#id或.class

div * {...} 坏

.list li {...} 坏

.list-item {...} 好

#list .list-item {...} 好

1、在你的脚本中,尽可能的减少对dom的操作,尽量缓存那些会需要重复用到类型和对象。在执行复杂的操作时,比较好的方法是:操作一个“离线”的元素,并在结束后重新增加到DOM树中(离线的元素即脱离了DOM后在内存中保存的元素)。

2、如果使用jQuery来选择元素,遵循jQuery 选择器优化实践

3、为了修改元素的样式,修改元素的"class"属性是通常会采用的方法。执行这种操作的DOM节点的层次越深越好。(同时也是由于深层次定义有利于逻辑解耦)

4、如果可以的话,仅对那些绝对定位或悬浮定位的元素执行动画。

5、滚动时去除复杂的伪元素动画(例如:hover,可以给body增加一个额外的没有hover动画的样式)。

若需要更详细的说明,请参见以下文章:

1.   How browsers work

2.   Rendering: repaint, reflow/relayout, restyle

希望本文能够有所启发!

30th June 2014

前端开发工程师应知应会之网页渲染(翻译)

时间: 2024-10-22 11:24:48

前端开发工程师应知应会之网页渲染(翻译)的相关文章

细数Web前端开发工程师 应掌握的技能

Web前端开发工程师,主要职责是利用HTML.XHTML.CSS.JAVAScript.FLASH等各种Web前端技术进行客户端产品的开发.完成客户端程序(也就是浏览器端)的开发,开发JavaScript以及Flash模块,同时结合后台开发技术模拟整体效果,进行丰富互联网的Web前端开发,致力于通过技术改善用户体验. 第一阶段:页面制作基础 从这一基础阶段开始,正式学习Web前端开发需要的编程语言HTML,CSS和JavaScript.HTML和CSS用于Web静态内容的展示,JavaScrip

Android开发工程师应该知道的50个开发秘诀、技巧和资源分享

作者撰写本文的初衷,是为了罗列出Android Studio有用的提示.技巧.快捷方式和参考资源,将提高您的整体效率和操作性能. 显然,还有很多优化.快捷方式等,但作者为了保持这篇文章的简短,限制为50个,希望读者会喜欢这篇文章! InfoQ注:本文是以MacOS X操作Android Studio为例,与Windows / Linux不一致的地方已经标注,请读者注意这一点. 可视化 1.Android Logcat的材料颜色主题(Material Colors theme). 要更改Andro

腾讯web前端开发工程师笔试题及答案

1. 如何实现事件委托? 首先要知道什么是事件委托. 考虑一个列表,在li的数量非常少的时候,为每一个li添加事件侦听当然不会存在太多性能方面的问题,但是当列表非常的长,长到上百上千甚至上万的时候(当然只是一个解释,实际工作中很少遇到这么多li的情况),为每个li添加事件侦听就会对页面性能产生很大的影响. 就像下面这段代码: <!DOCTYPE HTML><html><head><meta charset="utf-8" /><ti

HTML5前端开发工程师工资为什么那么高?

现代社会的就业压力可以说是非常的大,大学毕业生一抓一大把,要是没有一技之长很难在这个社会中立足,所以为了能够跟上时代的脚步,就必须掌握一个特长,就目前的发展来说,企业对于HTML5前端开发人才需求量可以说是非常的大.那么HTML5前端开发工程师工资为什么那么高呢? 越来越多的企业开始注重到用户体验,小到企业网站.个人主页,大到政府部门,都是通过网站向外界展示形象.传播信息,网站离不开HTML5前端开发人员,所以学习HTML5前端开发在当前社会里非常受用,工资也就越来越高. HTML5前端开发工程

2015 前端[JS]工程师必知必会

2015 前端[JS]工程师必知必会 本文摘自:http://zhuanlan.zhihu.com/FrontendMagazine/20002850 ,因为好东东西暂时没看懂,所以暂时保留下来,供以后参考! MrSunny · 12 天前 上次我写<前端工程师必知必会>已经是三年前了,那是我写过最火的文章了.三年了,我仍然会在Twitter上收到关于这篇文章的消息. 从2012年到现在,一篇文章都没发过让我觉得有点羞羞哒.三年是一段很长的时间,很多东西都发生了改变.2012年,我鼓励同学们去

移动前端开发人员必知必会:移动设备概述

因为工作岗位的变换带来工作内容的变动,对于移动网站的前端开发已经疏远了好几个月,在这好几个月中有很多新的东西出现,自己所掌握的一些东西也已经陈旧,所以选择了这本书<HTML5触摸界面设计与开发>来系统地学习和整理一下关于移动网站前端开发的知识体系. 之所以选择这本书,一是因为这本书比较新,2014年04月发的第一版.其二是因为作者Stephen Woods,这是Flickr团队的资深前端,Yahoo主页的Javascript技术平台正是出自此人之手. 接下来的时间里会陆续上传关于这本书学习的一

我也想成为一名出色的web前端开发工程师

随着互联网的发展,正式的前端工程师角色被行业认可,到了2010年,互联网开始全面进入移动时代,前端工程师的地位越来越重要,前端领域的技术发展也越来越快,各种新的思想.设计模式.工具和平台都快速发展,对前端工程师的技能要求也越来越高. 何为前端工程师?前端工程师,也叫Web前端开发工程师.他是随着web发展,细分出来的行业.它要求前端开发工程师不仅要掌握基本的Web前端开发技术,网站性能优化.SEO和服务器端的基础知识,而且要学会运用各种工具进行辅助开发以及理论层面的知识,包括代码的可维护性.组件

麦子学院-Web前端开发工程师系列培训教程

HTML+CSS基础入门1.课程介绍2.html的语法3.html的基本结构4.html的文档设置标记上(格式标记)5.html的文档设置标记下(文本标记)6.html图像标记img7.html超链接的使用8.html表格相关的标记9.html表格实战<简单的网页布局>10.html框架详解与框架布局实战11.HTML表单设计(上)12.HTML表单设计(下)13.使用CSS样式的方式14.定义CSS样式(CSS选择器)15.CSS常用属性(颜色属性)16.css常用属性(字体相关属性)17.

怎么才能成为优秀的前端开发工程师?

怎样才能成为优秀的前端开发工程师 很多刚入门的前端攻城师会有一个疑问:如何才能成为一名优秀的前端工程师呢?其实这个问题说大也大,说小也小,展开了说可以写一本书.当然我相信大部分人并不希望去读一本厚厚的书,大道至简,下面总结的几条方法或许能成为走向优秀前端的进阶之路. 1. 多写.很多问题都是积累得来的.写了,遇到了,才能去真正理解解决方案,才会随着自己的不断成长而有进步.别人问我为什么知道那么多 CSS 兼容解决方案,为什么一看就出的时候,我只能告诉他,我写了 20 几个 Wordpress 主