목차
浏览器是如何渲染网页的?
重现绘制(Repaint)
Reflow
怎么让浏览器充分利用渲染机制
过程代码:
达到预期效果的代码
性能优化的建议
希望这边译文对您有用
웹 프론트엔드 HTML 튜토리얼 关于网页渲染,前端们应该知道的一些事情_html/css_WEB-ITnose

关于网页渲染,前端们应该知道的一些事情_html/css_WEB-ITnose

Jun 21, 2016 am 08:46 AM

浏览器是如何渲染网页的?

我们从浏览器渲染一个页面的行为说起:

  • 从服务器端获取的HTML文档中构建出DOM树(文档对象模型);

  • 样式被加载和分析,构建CSSOM(CSS对象模型);

  • 以DOM和CSSOM为基础,文档树被构建,一系列对象被渲染(Webkit称每一个为‘renderer’或’render 对象(render object)‘,Gecko中称为‘frame’).渲染树反应了除不可见元素(

    , display:none)之外的DOM结构中一切可见元素,每一段字符串在渲染树中都被当做独立的渲染对象,每一个渲染对象都是其对应的DOM结构和计算所得样式的混合体,换句话说渲染树是DOM树的视觉表现;
  • 对于每一个渲染树元素,它的坐标都是通过计算获得的,这被称作排版(布局layout),浏览器通过文档流的方式(也就是一次就能完成所有元素的布局)(tables需要多于一次的布局);

  • 最终渲染树出现在浏览器窗口上,这个过程称为绘制(painting)。

当用户与一个页面交互或者脚本修改时,由于文档结构的变化,以上的一些操作步骤会重新执行。

重现绘制(Repaint)

当元素样式变化并不影响该元素在一个网页上的位置时( background-color, border-color, visibility),浏览器只会把新样式应用到该元素。

Reflow

当改变影响了 文档内容或结构或者元素的位置时,reflow发生(重新布局),这一般由以下因素触发:

  • DOM操作(添加,删除,更改,或者变更元素顺序);

  • 内容改变(包括表格区域内文本的变化)(所占位置大小变了);

  • 计算或者改变CSS属性(位置改变);

  • 添加或者删除样式表;

  • 改变类属性(class)(可能会改变位置);

  • 浏览器窗口操作(改变大小,滚动);

  • 伪类激活(可能改变位置)

怎么让浏览器充分利用渲染机制

浏览器会尽可能的限制被改变元素所在区域的重排重绘,比如说 display:fixed/absolute元素改变时只会影响它本身和它的子元素,而 display:static元素改变时会使其随后的元素都被重绘;(影响尽量少的元素)

另一个最大化性能的机制在于,当运行一系列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(由于缓存,只会重绘一次)
로그인 후 복사

然而,就像上面已经提到的,调用一个元素的属性会触发强制性的reflow,当我们加上一行读元素属性的代码时就会发生;

var $body = $('body');$body.css('padding', '1px');$body.css('padding'); // reading a property, a forced reflow(强制发生)$body.css('color', 'red');$body.css('margin', '2px');//另外一次reflow
로그인 후 복사

因此,会有两次reflow,因此应该组合来读元素属性已最大化性能 一个详细的例子;

$(function() {  var $body = $('body');  $body  .on('click', '.block-1', function(e) {    // 1 reflow        $body.css('padding', '1px');    $body.css('color', 'red');    $body.css('margin', '2px');  })  .on('click', '.block-2', function(e) {    // 2 reflows        $body.css('padding', '1px');    $body.css('padding');    $body.css('color', 'red');    $body.css('margin', '2px');  })  .on('click', '.block-3', function(e) {    // 3 repaints        $body.css('color', 'red');    $body.css('color');    $body.css('color', 'yellow');    $body.css('background');    $body.css('color', 'blue');    $body.css('outline');  })  .on('click', '.block-4', function(e) {    // 1 repaint        $body.css('color', 'red');    $body.css('color', 'yellow');    $body.css('color', 'blue');    $body.css('color');    $body.css('background');    $body.css('outline');  })  .on('click', '.block-5', function(e) {    // 3 reflows        $body.css('padding', '1px');    $body[0].offsetHeight;    $body.css('padding', '2px');    $body[0].offsetTop;    $body.css('padding', '3px');    $body[0].offsetWidth;  })  .on('click', '.block-6', function(e) {    // 1 reflow        $body.css('padding', '1px');    $body.css('padding', '2px');    $body.css('padding', '3px');    $body[0].offsetHeight;    $body[0].offsetTop;    $body[0].offsetWidth;  });});
로그인 후 복사

有些时候,可能你会需要一次强制性的reflow,例如:我们需要运用两次 margin-left到同一个对象,第一次无动画的设置到100px,然后通过动画过渡到50px, 实例;

过渡动画:

.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 defaultvar $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预处理器的开发者忽略),维护最少的层状结构,以下是各选择器的效率排行

    #id.classdiva+iul>li*input[type='text']a:hover
    로그인 후 복사
  • 应该引起注意的是,浏览器是从右向左读取选择器的,所以最右边的应该选择效率比较高的选择器 #id,.class;

div * {...} // bad.list li {...} // bad.list-item {...} // good#list .list-item {...} // good
로그인 후 복사
  • 在脚本中,应该尽可能的减少DOM操作,如果对象和属性会被重用,就缓存它们。在最好离线元素(未被插入文档树)(offline)上进行操作,然后把它插入DOM结构中;

  • 如果使用jQuery,遵循[jQuery选择器基本原则( http://learn.jquery.com/performance/optimize-selectors/);

  • 修改元素的样式时,修改class属性是做好的方法,其位置越深,越好(also because this helps decouple logic from presentation);

  • 只使 display:fixed/absolute的元素具有动画;

  • 不适用复杂的 :hover动画也是一个好的实践(给

    添加 no-hover属性), 延展阅读;

延展阅读已获得更多信息:

  1. How browsers works;

  2. Rendering: repaint, reflow/relayout, restyle;

希望这边译文对您有用

原文链接

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

& lt; Progress & Gt의 목적은 무엇입니까? 요소? & lt; Progress & Gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:34 PM

이 기사는 HTML & lt; Progress & Gt에 대해 설명합니다. 요소, 그 목적, 스타일 및 & lt; meter & gt의 차이; 요소. 주요 초점은 & lt; progress & gt; 작업 완료 및 & lt; meter & gt; Stati의 경우

& lt; datalist & gt의 목적은 무엇입니까? 요소? & lt; datalist & gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:33 PM

이 기사는 HTML & LT; Datalist & GT에 대해 논의합니다. 자동 완성 제안을 제공하고, 사용자 경험을 향상시키고, 오류를 줄임으로써 양식을 향상시키는 요소. 문자 수 : 159

HTML5의 크로스 브라우저 호환성에 대한 모범 사례는 무엇입니까? HTML5의 크로스 브라우저 호환성에 대한 모범 사례는 무엇입니까? Mar 17, 2025 pm 12:20 PM

기사는 HTML5 크로스 브라우저 호환성을 보장하기위한 모범 사례에 대해 논의하고 기능 감지, 점진적 향상 및 테스트 방법에 중점을 둡니다.

& lt; meter & gt의 목적은 무엇입니까? 요소? & lt; meter & gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:35 PM

이 기사는 HTML & lt; meter & gt에 대해 설명합니다. 범위 내에 스칼라 또는 분수 값을 표시하는 데 사용되는 요소 및 웹 개발의 일반적인 응용 프로그램. & lt; meter & gt; & lt; Progress & Gt; 그리고 Ex

HTML5 양식 유효성 검사 속성을 사용하여 사용자 입력을 유효성있게하려면 어떻게합니까? HTML5 양식 유효성 검사 속성을 사용하여 사용자 입력을 유효성있게하려면 어떻게합니까? Mar 17, 2025 pm 12:27 PM

이 기사에서는 브라우저에서 직접 사용자 입력을 검증하기 위해 필요한, Pattern, Min, Max 및 Length 한계와 같은 HTML5 양식 검증 속성을 사용하는 것에 대해 설명합니다.

html5 & lt; time & gt; 의미 적으로 날짜와 시간을 나타내는 요소? html5 & lt; time & gt; 의미 적으로 날짜와 시간을 나타내는 요소? Mar 12, 2025 pm 04:05 PM

이 기사는 html5 & lt; time & gt; 시맨틱 날짜/시간 표현 요소. 인간이 읽을 수있는 텍스트와 함께 기계 가독성 (ISO 8601 형식)에 대한 DateTime 속성의 중요성을 강조하여 Accessibilit를 향상시킵니다.

뷰포트 메타 태그는 무엇입니까? 반응 형 디자인에 중요한 이유는 무엇입니까? 뷰포트 메타 태그는 무엇입니까? 반응 형 디자인에 중요한 이유는 무엇입니까? Mar 20, 2025 pm 05:56 PM

이 기사는 모바일 장치의 반응 형 웹 디자인에 필수적인 Viewport Meta Tag에 대해 설명합니다. 적절한 사용이 최적의 컨텐츠 스케일링 및 사용자 상호 작용을 보장하는 방법을 설명하는 반면, 오용은 설계 및 접근성 문제로 이어질 수 있습니다.

& lt; iframe & gt; 꼬리표? 보안을 사용할 때 보안 고려 사항은 무엇입니까? & lt; iframe & gt; 꼬리표? 보안을 사용할 때 보안 고려 사항은 무엇입니까? Mar 20, 2025 pm 06:05 PM

이 기사는 & lt; iframe & gt; 외부 컨텐츠를 웹 페이지, 공통 용도, 보안 위험 및 객체 태그 및 API와 같은 대안을 포함시키는 태그의 목적.

See all articles