文档章节

写在前端性能优化之前你应该知道的 - 浏览器的加载和渲染

顽Shi
 顽Shi
发布于 2014/03/23 18:33
字数 1701
阅读 888
收藏 65

  前言

    一直想写点关于前端性能的东西,后来感觉所谓的性能优化最基本的前提是你要知道浏览器是如何针对web页面工作的.后来由于过年以及换工作等原因耽搁下来,只好利用这个休息的周末写一下.    

    本来打算好好研究一下关于前端性能优化的一些内容,看了一些发现有的地方不是很明了.所以觉得先把浏览器加载渲染这个过程摸清楚,本文是多方总结和我自己的一点研究,如果有不对的地方,还请指出,谢谢.

 

    首先我们要有一个概念,浏览器显示出一个页面,即使只拿前端抛开服务器和数据库,也是一个很复杂的过程.尽管它很复杂,但还是有一的步骤和流程的,了解这些步骤你才会清除的知道哪里耗费了过多的资源,从而进行人为的优化.

    在一个页面上我们通常会看到种内容,HTML-CSS-Javascript.在一个文件中它们会通过各种方式引入,然后会被浏览器分别解析.当我们通过一个URL地址进入页面时,工作就开始了.首先浏览器将HTML解析为一个DOM-Tree,然后将CSS规则解析为一个CSS-Tree,最后则是Javascript的下载和执行.


    在这个过程中,浏览器是按照一定顺序进行的,其中的任何一个步骤出现问题都可能导致页面无法显示.

  解析

    当完成了上面的解析过程后,浏览器引擎会根据这些解析的结果构建出Rendering-Tree,它会生成的规则将CSS样式应用到对应的element上,并且计算每个element的位置,这就是Reflow的过程.

    在这一过程中,DOM-Tree 的生成相对容易,比较耗费性能的是CSS匹配HTML这一过程,所以对着CSS解析很多地方都有提出:DOM的结构要尽量简单,要小,不要过度嵌套,CSS尽量用class和id.

  渲染

    在没说之前我就要先告诉大家,渲染是一个很消耗性能的过程.这就意味着如果你要优化你的前端性能,可以在这一部分针对每一个动作进行检查和优化.

    黄色部位就是渲染过程的几个动作,先进行样式的计算,然后够将Rendering-Tree,然后定位坐标以及大小等各种样式属性,最后画出来.上面有些线没有连贯是因为Javascript修改了DOM或者CSS导致必须重新Layout,又或者CSS规则没有匹配到.

    如果你早先对前端性能有概念,那么Repaint和Reflow这两个词你一定不会陌生.  

    Repaint - 表示页面上一部分的内容要重新画,可能是颜色什么的,但是元素的大小和位置不需要改变,也就是不影响其相邻的内容.

    Reflow - 表示页面上一部分内容的大小或者位置变化了,这会引起周围元素的连锁反应,导致整个Rendering-Tree重构.

    通过描述我们可以看到Reflow的动作成本要比Repaint高得多,所以在平时的工作中我们要尽量避免浏览器的Reflow.对于CSS浏览器是可以并行下载的,但是要注意这其中可能会发生的Reflow.

  JS的加载和执行

    Javascript在整个浏览器渲染的进程中始终是个不安份的因素,更多的时候它充当着规则的破坏者这种角色.因为它可以操作DOM的特性,使得之前生成好的DOM-Tree很有可能发生改变.

    浏览器对于Javascript奉行了两个原则,首先加载即执行,其次在其执行的期间阻塞其他内容(包括DOM的解析和其他资源的下载等).这是因为无法确定Javascript的执行会给DOM-Tree或者CSS带来怎样的变化,所以在JS执行的情况下,整个浏览器处于单核状态.看到这你就不难理解为什么很多地方都推荐将CSS写在页面最前面,而将Javascript写在页面最后的原因了.

    IE从6开始支持一个defer属性,它加在<script>标签中,作用是使Javascript脚本并行下载,并且等到都下载完在顺序执行,但仅支持IE.

    HTML5也不甘示弱,加入了类似的async属性,不过它坚定遵守Javascript加载后立即执行的原则,所以存在弊端,容易使有顺序的JS代码失控,并且不是所有版本的浏览器都支持,所以不常使用.

  标准解决方案-动态DOM

    为了解决Javascript脚本载入的问题,人们又找出通过创建script节点的方式.

function loadjs(script_filename) {
    var script = document.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.setAttribute('src', script_filename);
    script.setAttribute('id', 'coolshell_script_id');
 
    script_id = document.getElementById('coolshell_script_id');
    if(script_id){
        document.getElementsByTagName('head')[0].removeChild(script_id);
    }
    document.getElementsByTagName('head')[0].appendChild(script);
}
 
var script = 'a.js';
loadjs(script);
    看一下代码,传递一个url参数,然后用创建element的方式创建一个script节点.这一过程就将脚本载入并且执行了.当然其实还有一种Ajax的方式,不过原理差不多,有兴趣的可以自行百度.

  结尾

    其实浏览器整个的处理比这写的要复杂的多,上面的过程只是简化了.了解整个浏览器的渲染进程那么我们对什么影响了网页的加载?这个问题应该有了一点认识,比较重要的一个Repaint和Reflow,另一个就是JS操作DOM.

    一些建议:

  •     如果能提前定义好一个class去赋值给DOM,就别一个个DOM节点的遍历然后逐个添加style了,在楼下大喊一句远比挨个单元去敲门省力.
  •     创建的DOM结构尽可能简洁,层次少,另外不要再DOM节点中运算.
  •     table这种布局省事是省事,不过典型的牵一发而动全身,改一个地方其他都要变,所以尽量不要用.
  •     JS的性能浪费的不是在代码本身的执行,而是对DOM和CSS的操作.

    受能力所限,写的可能有不对的地方还请谅解,欢迎大家留言讨论.

© 著作权归作者所有

顽Shi
粉丝 275
博文 81
码字总数 92387
作品 0
普陀
程序员
私信 提问
React + Koa 实现服务端渲染(SSR)

⚛️React是目前前端社区最流行的UI库之一,它的基于组件化的开发方式极大地提升了前端开发体验,React通过拆分一个大的应用至一个个小的组件,来使得我们的代码更加的可被重用,以及获得更好...

jasonboy7
2018/05/21
0
0
CSS 是如何工作的:关键渲染路径中的 CSS 解析和渲染

CSS 是如何工作的:关键渲染路径中的 CSS 解析和渲染 发布于 2018-07-27

阅文集团前端团队
2018/07/30
0
0
移动H5前端性能优化指南

移动H5前端性能优化指南 概述 1. PC优化手段在Mobile侧同样适用 2. 在Mobile侧我们提出三秒种渲染完成首屏指标 3. 基于第二点,首屏加载3秒完成或使用Loading 4. 基于联通3G网络平均338KB/s...

32氪
2017/07/31
0
0
[译] 2019 前端性能优化年度总结 — 第五部分

原文地址:Front-End Performance Checklist 2019 — 5 原文作者:Vitaly Friedman 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m… 译者:wznonstop 校对者:TUARAN, xilih...

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

今天我要将关注点放到页面渲染以及其重要性上。虽然已经有很多文章提到过这个主题了,但大部分信息都是零碎的片段。为了思考这件事情,我需要研究很多信息的来源。这也就是为什么我觉得我应该...

oschina
2014/07/04
9K
16

没有更多内容

加载失败,请刷新页面

加载更多

PostgreSQL参数search_path影响及作用

search_path稍微熟悉PG就会用到,用法这里就不必讲,本篇主要讲它在程序里怎样处理。 1、GUC参数定义 这是个 config_string 参数 {{"search_path", PGC_USERSET, CLIENT_CONN_STATEMENT,...

有理想的猪
57分钟前
8
0
Qt程序各个平台打包发布及安装程序大全

本文链接:https://blog.csdn.net/zhengtianzuo06/article/details/78468111 通用: 1.准备图标 图标可以直接使用一般格式的图片制作, 比如jpg, png等 推荐使用Photoshop制作原始图 推荐使用I...

shzwork
今天
4
0
springboot2.0 maven打包分离lib,resources

springboot将工程打包成jar包后,会出现获取classpath下的文件出现测试环境正常而生产环境文件找不到的问题,这是因为 1、在调试过程中,文件是真实存在于磁盘的某个目录。此时通过获取文件路...

陈俊凯
今天
22
0
BootStrap

一、BootStrap 简洁、直观、强悍的前端开发框架,让web开发更加迅速、简单 中文镜像网站:http://www.bootcss.com 用于开发响应式布局、移动设备优先的WEB项目 1、使用boot 创建文件夹,在文...

wytao1995
今天
10
0
小知识:讲述Linux命令别名与资源文件的区别

别名 别名是命令的快捷方式。为那些需要经常执行,但需要很长时间输入的长命令创建快捷方式很有用。语法是: alias ppp='ping www.baidu.com' 它们并不总是用来缩短长命令。重要的是,你将它...

老孟的Linux私房菜
今天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部