热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

每个前端开发人员应该知道的网页呈现

2014年5月26日,由AlexanderSkutin撰写;由MaxShirshin于2014年6月30日翻译今天我想关注网页呈现的主题,以及为什么它在网页开发中很重要。有很多文章

2014年5月26日, 由Alexander Skutin撰写; 由Max Shirshin于2014年6月30日翻译

今天我想关注网页呈现的主题,以及为什么它在网页开发中很重要。有很多文章可用于涵盖这个主题,但是信息是分散的,以某种方式分散。例如,为了包围我的头脑,我不得不学习很多来源。这就是为什么我决定写这篇文章。我相信这篇文章对于初学者以及想要刷新和构建他们已经知道的更多高级开发人员将是有用的。

当页面布局被定义时,渲染必须从一开始就进行优化,因为样式和脚本在页面呈现中起关键作用。专业人士必须了解某些技巧以避免性能问题。

本文不详细研究内部浏览器的机制,而是提供一些常见的原则。不同的浏览器引擎的工作方式不同,这将使浏览器特定的研究变得更加复杂。

浏览器如何呈现网页
我们从绘制页面时浏览浏览器操作的概述开始:

1.DOM(文档对象模型)由从服务器接收的HTML形成。
2.样式被加载和解析,形成了CSSOM(CSS对象模型)。
3.在DOM和CSSOM之上,创建一个渲染树,它是一组要渲染的对象(Webkit调用那些“渲染器”或“渲染对象”,而在Gecko中它是一个“框架”)。渲染树反映除了不可见元素之外的DOM结构(如标签或已display:none;设置的元素)。每个文本字符串在渲染树中作为单独的渲染器表示。每个渲染对象都包含其对应的DOM对象(或文本块)加上计算的样式。换句话说,渲染树描述了DOM的视觉表示。
对于每个渲染树元素,计算其坐标,称为“布局”。浏览器使用一个流程方法,只需要一次传递来布局所有元素(表需要多个遍)。
最后,这实际上显示在浏览器窗口中,一个称为“绘画”的过程。
当用户与页面进行交互或脚本进行修改时,必须重复上述某些操作,因为底层页面结构发生变化。

重印
当改变不影响页面上的元素的位置元素的样式(例如background-color,border-color,visibility),浏览器只是应用了新样式再次重绘元素(即意味着“重画”或“restyle”正在发生的事情)。

回流
当更改影响文档内容或结构或元素位置时,会发生回流(或重新传输)。这些更改通常是由以下机制触发的:

DOM操作(元素添加,删除,更改或更改元素顺序);
内容更改,包括表单字段中的文本更改;
1计算或改变CSS属性;
2添加或删除样式表;
3改变“类”属性;
4浏览器窗口操纵(调整大小,滚动);
5伪类激活(:hover)。
浏览器如何优化渲染
浏览器正在尽最大努力将重绘/回流限制到仅覆盖已更改元素的区域。例如,绝对/固定定位元素中的大小变化仅影响元素本身及其后代,而静态定位元素中的相似变化会触发所有后续元素的回流。

另一种优化技术是在运行Javascript代码时,浏览器会缓存这些更改,并在代码运行后将其应用于单次传递。例如,这段代码只会触发一个回流和重绘:

var $body = $(‘body’);
$body.css(‘padding’, ‘1px’); // reflow, repaint
$body.css(‘color’, ‘red’); // repaint
$body.css(‘margin’, ‘2px’); // reflow, repaint
// only 1 reflow and repaint will actually happen
但是,如上所述,访问元素属性会触发强制回流。如果我们添加一个额外的行,将元素属性读入上一个块,则会发生这种情况:

var $body = $(‘body’);
$body.css(‘padding’, ‘1px’);
$body.css(‘padding’); // reading a property, a forced reflow
$body.css(‘color’, ‘red’);
$body.css(‘margin’, ‘2px’);

因此,我们得到2个回流而不是一个回流。因此,您应该将读取元素属性组合在一起以优化性能(请参阅 JSBin上的更详细示例)。

有时您必须触发强制回流。示例:我们必须将相同的属性(例如“margin-left”)应用于同一个元素两次。最初,它应该被设置为100px没有动画,然后它必须是动画与transition一个值50px。您现在可以在JSBin上学习这个例子,但是我将在这里进行更详细的描述。

我们首先创建一个具有转换的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;

}
然后继续执行:

// our element that has a “has-transition” class by default
var $targetElem = $(‘#targetElemId’);

// remove the transition class
$targetElem.removeClass(‘has-transition’);

// change the property expecting the transition to be off, as the class is not there
// anymore
$targetElem.css(‘margin-left’, 100);

// put the transition class back
$targetElem.addClass(‘has-transition’);

// change the property
$targetElem.css(‘margin-left’, 50);
然而,这种实现不能像预期的那样工作。这些更改被缓存并应用于代码块的末尾。我们需要的是强制回流,我们可以通过进行以下更改来实现:

// remove the transition class
$(this).removeClass(‘has-transition’);

// change the property
$(this).css(‘margin-left’, 100);

// trigger a forced reflow, so that changes in a class/property get applied immediately
$(this)[0].offsetHeight; // an example, other properties would work, too

// put the transition class back
$(this).addClass(‘has-transition’);

// change the property
$(this).css(‘margin-left’, 50);
现在这样按预期工作。

优化实用建议
总结可用信息,我可以推荐以下内容:

创建有效的HTML和CSS,不要忘记指定文档编码。样式应包含在中,附加到标签末尾的脚本。
尝试简化和优化CSS选择器(这种优化几乎被大多数使用CSS预处理器的开发人员普遍忽略)。保持嵌套水平至少。这是CSS选择器根据其性能(从最快的)开始排名的方式:
识别者: #id
类: .class
标签: div
相邻的兄弟选择器: a + i
家长选择器 ul > li
通用选择器 *
属性选择器 input[type=”text”]
伪类和pseudoelements:a:hover 你应该记住,浏览器从右到左的处理选择,这就是为什么最右边的选择应该是最快的国家之一-要么#id或.class:
div * {…} // bad
.list li {…} // bad
.list-item {…} // good

list .list-item {…} // good

在脚本中,尽量减少DOM操作。缓存所有内容,包括属性和对象(如果要重复使用)。执行复杂操作时,最好使用“离线”元素(“离线”元素是从DOM断开并仅存储在内存中),然后将其附加到DOM。
如果您使用jQuery选择元素,请遵循jQuery选择器最佳做法。
要更改元素的样式,修改“类”属性是最有效的方式之一。您执行此更改的DOM树越深,越好(也是因为这有助于将逻辑与演示分离)。
动画只有绝对/固定的元素,如果可以的话。
在:hover滚动时禁用复杂动画是一个好主意(例如,通过向添加一个额外的“no-hover”类)。阅读有关此主题的文章。
有关更详细的概述,请查看这些文章:

浏览器的工作原理
渲染:重绘,回流/重新传输,修复
我希望你能发现这篇文章有用!

2014年6月30日
[RU] РендерингWEB-страницы:чтообэтомдолжензнать前端разработчик
亚历山大Skutin
现场: http://skutin.ru/
Max Shirshin
GitHub: ingdir
推特: @ingdir
Facebook 推特 Google+
如果您发现有错误,请随时在GitHub上进行 编辑。
评论由Disqus提供支持


推荐阅读
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文探讨了Lua中元表和元方法的使用,通过具体的代码示例展示了如何利用这些特性来实现类似C语言中的运算符重载功能。 ... [详细]
  • 本文详细介绍如何在Spring Boot项目中集成和使用JPA,涵盖JPA的基本概念、Spring Data JPA的功能以及具体的操作步骤,帮助开发者快速掌握这一强大的持久化技术。 ... [详细]
  • 帝国cms各数据表有什么用
    CMS教程|帝国CMS帝国cmsCMS教程-帝国CMS精易编程助手源码,ubuntu桥接设置,500错误是tomcat吗,爬虫c原理,php会话包括什么,营销seo关键词优化一般多 ... [详细]
  • 择要:Fundebug的JavaScript毛病监控插件同步支撑Vue.js异步毛病监控。Vue.js从降生至今已5年,尤大在本年2月份宣布了严重更新,即Vue2.6。更新包含新增 ... [详细]
  • 深入解析链表成环问题:剑指Offer第22天的新视角
    本文将详细介绍链表成环问题的多种解法,包括哈希表法、JSON.stringify特殊解法及双指针法,并提供详尽的代码示例。阅读本文,你不仅能够掌握这一经典算法问题的核心技巧,还能了解到更多编程思维的拓展。 ... [详细]
  • 本项目使用Java语言开发了一个基于B/S架构的指纹识别系统,该系统能够实现指纹的高效采集与精准识别,适用于多种安全认证场景。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 本文详细介绍了在 Ubuntu 16.04 系统上安装和配置 PostgreSQL 数据库的方法,包括如何设置监听地址、启用密码加密、更改默认用户密码以及调整客户端访问控制。 ... [详细]
  • 深入理解:AJAX学习指南
    本文详细探讨了AJAX的基本概念、工作原理及其在现代Web开发中的应用,旨在为初学者提供全面的学习资料。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 本文介绍如何通过Java代码调用阿里云短信服务API来实现短信验证码的发送功能,包括必要的依赖添加和关键代码示例。 ... [详细]
  • 本文探讨了互联网服务提供商(ISP)如何可能篡改或插入用户请求的数据流,并提供了有效的技术手段来防止此类劫持行为,确保网络环境的安全与纯净。 ... [详细]
  • 本文详细介绍了JQuery Mobile框架中特有的事件和方法,帮助开发者更好地理解和应用这些特性,提升移动Web开发的效率。 ... [详细]
  • 理解浏览器历史记录(2)hashchange、pushState
    阅读目录1.hashchange2.pushState本文也是一篇基础文章。继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变 ... [详细]
author-avatar
黄宗翰琼琦莉雯
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有