awesome-interview/book1/browser-repain-reflow.html

22 lines
21 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper docs-doc-page docs-version-current plugin-docs plugin-id-default docs-doc-id-book1/browser-repain-reflow">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v2.3.1">
<title data-rh="true">浏览器的重排重绘 | HZFE - 剑指前端 Offer</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://febook.hzfe.org/awesome-interview/book1/browser-repain-reflow"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="浏览器的重排重绘 | HZFE - 剑指前端 Offer"><meta data-rh="true" name="description" content="相关问题"><meta data-rh="true" property="og:description" content="相关问题"><link data-rh="true" rel="icon" href="/awesome-interview/img/favicon.ico"><link data-rh="true" rel="canonical" href="https://febook.hzfe.org/awesome-interview/book1/browser-repain-reflow"><link data-rh="true" rel="alternate" href="https://febook.hzfe.org/awesome-interview/book1/browser-repain-reflow" hreflang="en"><link data-rh="true" rel="alternate" href="https://febook.hzfe.org/awesome-interview/book1/browser-repain-reflow" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://PED5MQGL7T-dsn.algolia.net" crossorigin="anonymous"><link rel="search" type="application/opensearchdescription+xml" title="HZFE - 剑指前端 Offer" href="/awesome-interview/opensearch.xml">
<link rel="apple-touch-icon" href="/awesome-interview/img/badge.png">
<link rel="manifest" href="/awesome-interview/manifest.json">
<link rel="preconnect" href="https://hm.baidu.com">
<script>var _hmt=_hmt||[];!function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?c7cd0fd77ac518cc6ef46461cdc9524b";var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(e,c)}()</script>
<script src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" async data-ad-client="ca-pub-9889934432771967"></script>
<script src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9889934432771967" async crossorigin="anonymous"></script><link rel="stylesheet" href="/awesome-interview/assets/css/styles.0f62048e.css">
<link rel="preload" href="/awesome-interview/assets/js/runtime~main.a75952d5.js" as="script">
<link rel="preload" href="/awesome-interview/assets/js/main.a5e14537.js" as="script">
</head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
<div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_m1mJ"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/awesome-interview/"><div class="navbar__logo"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_ToTc themedImage--light_HNdA"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_ToTc themedImage--dark_i4oU"></div><b class="navbar__title text--truncate">剑指前端 Offer</b></a></div><div class="navbar__items navbar__items--right"><a href="https://github.com/hzfe/awesome-interview" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a><div class="searchBox_ZlJk"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><aside class="theme-doc-sidebar-container docSidebarContainer_b6E3"><div class="sidebarViewport_Xe31"><div class="sidebar_njMd sidebarWithHideableNavbar_wUlq"><a tabindex="-1" class="sidebarLogo_isFc" href="/awesome-interview/"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_ToTc themedImage--light_HNdA"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_ToTc themedImage--dark_i4oU"><b>剑指前端 Offer</b></a><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/awesome-interview/about">关于我们</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/awesome-interview/">前言</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" aria-expanded="true" href="/awesome-interview/book1/browser-cross-origin">模拟题一</a></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/browser-cross-origin">浏览器:浏览器跨域</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/awesome-interview/book1/browser-repain-reflow">浏览器:浏览器的重排重绘</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/engineer-webpack-workflow">工程化webpack 工作流程</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/frame-vue-data-binding">框架Vue 的数据绑定机制</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/frame-vue-computed-watch">框架Vue 的 computed 和 watch 的区别</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/js-closures">基础:闭包的作用和原理</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/js-module-specs">基础:前端模块化规范</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/css-bfc">样式BFC 的形成和作用</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/network-security">网络:前端安全</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/coding-promise">编码:实现一个符合 Promises/A+ 规范的 Promise</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/algorithm-balanced-binary-trees">算法:平衡二叉树</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book1/topic-enter-url-display-xx">综合:浏览器从输入网址到页面展现的过程</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/awesome-interview/book2/browser-render-mechanism">模拟题二</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/awesome-interview/book3/browser-event-loop">模拟题三</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/awesome-interview/book4/browser-router">模拟题四</a></div></li></ul></nav><button type="button" title="Collapse sidebar" aria-label="Collapse sidebar" class="button button--secondary button--outline collapseSidebarButton_PEFL"><svg width="20" height="20" aria-hidden="true" class="collapseSidebarButtonIcon_kv0_"><g fill="#7a7a7a"><path d="M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"></path><path d="M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"></path></g></svg></button></div></div></aside><main class="docMainContainer_gTbr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/awesome-interview/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><span class="breadcrumbs__link">模拟题一</span><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="name">浏览器:浏览器的重排重绘</span><meta itemprop="position" content="2"></li></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><h1>浏览器的重排重绘</h1><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="相关问题">相关问题<a href="#相关问题" class="hash-link" aria-label="Direct link to 相关问题" title="Direct link to 相关问题"></a></h2><ul><li>如何提升页面渲染性能</li><li>如何减少页面重排重绘</li><li>哪些行为会引起重排/重绘</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="回答关键点">回答关键点<a href="#回答关键点" class="hash-link" aria-label="Direct link to 回答关键点" title="Direct link to 回答关键点"></a></h2><p><code>渲染性能</code> <code>Layout</code> <code>Paint</code></p><p>浏览器渲染大致分为四个阶段,其中在解析 HTML 后,会依次进入 Layout 和 Paint 阶段。<strong>样式或节点的更改,以及对布局信息的访问等</strong>,都有可能导致重排和重绘。而重排和重绘的过程在<strong>主线程</strong>中进行,这意味着不合理的重排重绘会导致<strong>渲染卡顿,用户交互滞后</strong>等性能问题。</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="知识点深入">知识点深入<a href="#知识点深入" class="hash-link" aria-label="Direct link to 知识点深入" title="Direct link to 知识点深入"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-什么是重排重绘">1. 什么是重排重绘<a href="#1-什么是重排重绘" class="hash-link" aria-label="Direct link to 1. 什么是重排重绘" title="Direct link to 1. 什么是重排重绘"></a></h3><p><img loading="lazy" src="https://user-images.githubusercontent.com/17002181/126033732-d5002255-1c88-4dee-9371-da166aacdca9.png" alt="image" class="img_ev3q"></p><ol><li>Parse HTML相关引擎分别解析文档和样式表以及脚本生成 DOM 和 CSSOM ,最终合成为 Render 树。</li><li>Layout浏览器通过 Render 树中的信息,以递归的形式计算出每个节点的尺寸大小和在页面中的具体位置。</li><li>Paint浏览器将 Render 树中的节点转换成在屏幕上绘制实际像素的指令,这个过程发生在多个图层上。</li><li>Composite浏览器将所有层按照一定顺序合并为一个图层并绘制在屏幕上。</li></ol><p>图中所示步骤为浏览器渲染的关键路径。浏览器从获取文档、样式、脚本等内容,到最终渲染结果到屏幕上,通常需要经过如图所示的步骤。而 DOM 或 CSSOM 被修改,会导致浏览器重复执行图中的步骤。重排和重绘,本质上指的就是触发 Layout 和 Paint 的过程,且重排必定导致重绘。</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="引起重排重绘的常见操作">引起重排/重绘的常见操作<a href="#引起重排重绘的常见操作" class="hash-link" aria-label="Direct link to 引起重排/重绘的常见操作" title="Direct link to 引起重排/重绘的常见操作"></a></h4><ol><li>外观有变化时,会导致<strong>重绘</strong>。相关的样式属性如 <code>color</code> <code>opacity</code> 等。</li><li>布局结构或节点内容变化时,会导致<strong>重排</strong>。相关的样式属性如 <code>height</code> <code>float</code> <code>position</code> 等。<ul><li>盒子尺寸和类型。</li><li>定位方案(正常流、浮动和绝对定位)。</li><li>文档树中元素之间的关系。</li><li>外部信息(如视口大小等)。</li></ul></li><li>获取布局信息时,会导致<strong>重排</strong>。相关的方法属性如 <code>offsetTop</code> <code>getComputedStyle</code> 等。</li></ol><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-如何减少重排重绘">2. 如何减少重排重绘<a href="#2-如何减少重排重绘" class="hash-link" aria-label="Direct link to 2. 如何减少重排重绘" title="Direct link to 2. 如何减少重排重绘"></a></h3><p><img loading="lazy" src="https://user-images.githubusercontent.com/17002181/126033739-3e689aab-fcd8-4928-9e6d-6a047ab2a8c9.png" alt="image" class="img_ev3q"></p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="意义">意义<a href="#意义" class="hash-link" aria-label="Direct link to 意义" title="Direct link to 意义"></a></h4><p>大多数显示器的刷新率是 60FPSframes per second。理想情况下浏览器需要在 1/60 秒内完成渲染阶段并交付一帧。这样用户就会看到一个交互流畅的页面。</p><p>在交互阶段,页面更新(一般是通过执行 JavaScript 来触发)通常会触发重排和重绘。为了提升浏览器渲染效率,应当尽可能减少重绘重排(跳过 Layout/Paint 步骤),从而降低浏览器渲染耗费的时间,将内容尽快渲染到屏幕上。</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="解决方案">解决方案<a href="#解决方案" class="hash-link" aria-label="Direct link to 解决方案" title="Direct link to 解决方案"></a></h4><ol><li>对 DOM 进行批量写入和读取(通过虚拟 DOM 或者 DocumentFragment 实现)。</li><li>避免对样式频繁操作,了解常用样式属性触发 Layout / Paint / Composite 的<a href="https://csstriggers.com/" target="_blank" rel="noopener noreferrer">机制</a>,合理使用样式。</li><li>合理利用特殊样式属性(如 transform: translateZ(0) 或者 will-change将渲染层提升为合成层开启 GPU 加速,提高页面性能。</li><li>使用变量对布局信息(如 clientTop进行缓存避免因频繁读取布局信息而触发重排和重绘。</li></ol><p>另外,可以借助 DevTools Performance 面板来查看产生重排重绘任务占用主线程的情况和调用代码。</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="参考资料">参考资料<a href="#参考资料" class="hash-link" aria-label="Direct link to 参考资料" title="Direct link to 参考资料"></a></h2><ol><li><a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hl=zh-cn" target="_blank" rel="noopener noreferrer">渲染树构建、布局及绘制</a></li><li><a href="https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing" target="_blank" rel="noopener noreferrer">避免大型、复杂的布局和布局抖动</a></li><li><a href="https://csstriggers.com/" target="_blank" rel="noopener noreferrer">CSS 属性触发布局、绘制及合成的数据</a></li><li><a href="https://gist.github.com/paulirish/5d52fb081b3570c81e3a" target="_blank" rel="noopener noreferrer">What forces layout / reflow</a></li></ol></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages navigation"><a class="pagination-nav__link pagination-nav__link--prev" href="/awesome-interview/book1/browser-cross-origin"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">浏览器:浏览器跨域</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/awesome-interview/book1/engineer-webpack-workflow"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">工程化webpack 工作流程</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#相关问题" class="table-of-contents__link toc-highlight">相关问题</a></li><li><a href="#回答关键点" class="table-of-contents__link toc-highlight">回答关键点</a></li><li><a href="#知识点深入" class="table-of-contents__link toc-highlight">知识点深入</a><ul><li><a href="#1-什么是重排重绘" class="table-of-contents__link toc-highlight">1. 什么是重排重绘</a><ul><li><a href="#引起重排重绘的常见操作" class="table-of-contents__link toc-highlight">引起重排/重绘的常见操作</a></li></ul></li><li><a href="#2-如何减少重排重绘" class="table-of-contents__link toc-highlight">2. 如何减少重排重绘</a><ul><li><a href="#意义" class="table-of-contents__link toc-highlight">意义</a></li><li><a href="#解决方案" class="table-of-contents__link toc-highlight">解决方案</a></li></ul></li></ul></li><li><a href="#参考资料" class="table-of-contents__link toc-highlight">参考资料</a></li></ul></div></div></div><div class="row"><div class="col"><div class="react-utterences"><div>Loading script...</div></div></div><div class="col col--3"></div></div></div></main></div></div></div>
<script src="/awesome-interview/assets/js/runtime~main.a75952d5.js"></script>
<script src="/awesome-interview/assets/js/main.a5e14537.js"></script>
</body>
</html>