• 技术文章 >web前端 >html教程

    为什么每个前端开发者都要理解页面的渲染?

    2016-06-06 09:32:39原创564
    渲染应该从最开始当页面布局被定义时就进行优化,样式和脚本在页面渲染中扮演着非常重要的角色。专业人员知道一些技巧以避免一些性能问题。
    这篇文章不会深入研究浏览器的技术细节,而是提供一些通用的原则。不同浏览器引擎工作原理不同,这就使特定浏览器的学习更加复杂。

    浏览器是怎样渲染一个页面的?

    我们从浏览器渲染页面的大概过程开始说起:

    重绘

    当在页面上修改了一些不需要改变定位的样式的时候(比如background-color,border-color,visibility),浏览器只会将新的样式重新绘制给元素(这就叫一次“重绘”或者“重新定义样式”)。

    重排

    当页面上的改变影响了文档内容、结构或者元素定位时,就会发生重排(或称“重新布局”)。重排通常由以下改变触发:

    浏览器如何优化渲染?

    浏览器尽最大努力限制重排的过程仅覆盖已更改的元素的区域。举个例子,一个 position 为 absolue 或 fixed 的元素的大小变化只影响它自身和子孙元素,而对一个 position 为 static 的元素做同样的操作就会引起所有它后面元素的重排。
    另一个优化就是当运行一段Jjavascript 代码的时候,浏览器会将一些修改缓存起来,然后当代码执行的时候,一次性的将这些修改执行。举例来说,这段代码会触发一次重绘和一次重排:
    1. var $body = $('body');
    2. $body.css('padding', '1px'); // 重排, 重绘
    3. $body.css('color', 'red'); // 重绘
    4. $body.css('margin', '2px'); // 重排, 重绘
    5. // 实际上只有一次重排和重绘被执行。

    如上面所说,访问一个元素的属性会进行一次强制重排。如果我们给上面的代码加上一行读取元素属性的代码,这个情况就会出现:
    1. var $body = $('body');
    2. $body.css('padding', '1px');
    3. $body.css('padding'); // 这里读取了一次元素的属性,一次强制重排就会发生。
    4. $body.css('color', 'red');
    5. $body.css('margin', '2px');
    上面这段代码的结果就是,进行了两次重排。因此,为了提高性能,你应该讲读取元素属性的代码组织在一起(细节的例子可以看JSBin上的代码)。
    有一种情况是必须触发一次强制重排的。例如:给元素改变同一个属性两次(比如margin-left),一开始设置100px,没有动画,然后通过动画的形式将值改为50px。具体可以看例子,当然,我在这里会讲更多的细节。
    我们从一个有transition的CSS class开始:
    1. .has-transition {
    2. -webkit-transition: margin-left 1s ease-out;
    3. -moz-transition: margin-left 1s ease-out;
    4. -o-transition: margin-left 1s ease-out;
    5. transition: margin-left 1s ease-out;
    6. }

    然后进行实现:
    1. //我们的元素默认有"has-transition"属性
    2. var $targetElem = $('#targetElemId');
    3. //删除包含transition的class
    4. $targetElem.removeClass('has-transition');
    5. // 当包含transition的class已经没了的时候,改变元素属性
    6. $targetElem.css('margin-left', 100);
    7. // 再将包含transition的class添加回来
    8. $targetElem.addClass('has-transition');
    9. // 改变元素属性
    10. $targetElem.css('margin-left', 50);
    上面的实现没有按照期望的运行。所有的修改都被浏览器缓存了,只在上面这段代码的最后才会执行。我们需要的是一次强制重排,我们可以通过进行以下修改来实现:
    1. //删除包含transition的class
    2. $(this).removeClass('has-transition');
    3. // 改变元素属性
    4. $(this).css('margin-left', 100);
    5. //触发一次强制重排,从而使变化了的class或属性能够立即执行。
    6. $(this)[0].offsetHeight; // offsetHeight仅仅是个例子,其他的属性也可以奏效。
    7. // 再将包含transition的class添加回来
    8. $(this).addClass('has-transition');
    9. // 改变元素属性
    10. $(this).css('margin-left', 50);

    现在这段代码如我们所期望的运行了。

    实际的优化建议

    汇总了一些有用的信息,我建议以下几点:
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:为什么每个前端开发者都要理解页面的渲染?
    上一篇:jsp页面在IE8下文本模式自动为“杂项(Quirks)”导致页面显示错位 下一篇:【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 登录界面前端样式和特效
    Web大前端开发直播班

    相关文章推荐

    • html5元素的分类有哪些• web前端笔试题库之HTML篇• Div+CSS网站设计的优点_html/css_WEB-ITnose• ExtJs教程14• HTML中meta标签作用及属性总结_html/css_WEB-ITnose

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网