建议购买原文,前端性能优化原理与实践,本文学习总结用。如有侵权,感谢联系,删除。
1、渲染篇
1) 客户端渲染
服务器把静态文件给客户端,客户端进行加载,还有执行js,生成相应的dom。
缺点:根节点下的内容要到js执行完,才知道;对于搜索关键字可能找不到。
2) 服务器渲染
服务器把组件或者页面渲染成html字符串给客户端,客户端不需执行js和生成dom,直接渲染呈现。
服务端渲染解决了一个非常关键的性能问题——首屏加载速度过慢。
缺点:服务器压力大,一般在首屏渲染方案和SEO等低成本方案用完的时候,还是差的时候,考虑
3)浏览器背后的运行机制
①、浏览器的“心”(内核)
浏览器内核决定了浏览器解释网页语法的方式。
浏览器的内核有两部分:渲染引擎和js引擎。
渲染引擎又包括了 HTML 解释器、CSS 解释器、布局、网络、 存储、图形、音视频、图片解码器等等零部件。
渲染简单的过程:html/css/js-->浏览器内核-->图像
内核内部主要有HTML 解释器、CSS 解释器、图层布局计算模块、视图绘制模块与JavaScript 引擎这几大模块:
- HTML 解释器:将 HTML 文档经过词法分析输出 DOM 树。
- CSS 解释器:解析 CSS 文档, 生成样式规则。
- 图层布局计算模块:布局计算每个对象的精确位置和大小。
- 视图绘制模块:进行具体节点的图像绘制,将像素渲染到屏幕上。
- JavaScript 引擎:编译执行 Javascript 代码。
②、基于渲染流程的 CSS 优化建议
CSS 引擎查找样式表:是按照右往左查询的(span在.header)
.header span{}
- 避免使用通配符,只对需要用到的元素进行选择。
- 关注可以通过继承实现的属性,避免重复匹配重复定义。
- 少用标签选择器。如果可以,用类选择器替代
- 不要画蛇添足,id 和 class 选择器不应该被多余的选择器拖后腿(.myList#title--> #title)
- 减少嵌套。后代选择器的开销是最高的,因此我们应该尽量将选择器的深度降到最低(最高不 要超过三层),尽可能使用类来关联每一个标签元素。
③、告别阻塞:CSS 与 JS 的加载顺序优化
HTML、CSS 和 JS,都具有阻塞渲染的特性。 HTML 阻塞,天经地义。
遇到scrpt标签先执行js,把css和html阻塞了(更适合说 JS 引擎抢走了渲染引擎的控制权),执行完在执行下面。
CSS 是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲 染的时间。
④、JS的三种加载方式
-
正常执行 <script src="index.js"></script>
这种情况下 JS 会阻塞浏览器,浏览器必须等待 index.js 加载和执行完毕才能去做其它事情。 -
async 模式:<script async src="index.js"></script>
async 模式下,JS 不会阻塞浏览器做任何其它的事情。它的加载是异步的,当它加载结束,JS 脚本 会立即执行。 -
defer 模式::<script defer src="index.js"></script>
defer 模式下,JS 的加载是异步的,执行是被推迟的。等整个文档解析完成、DOMContentLoaded 事件即将被触发时,被标记了 defer 的 JS 文件才会开始依次执行。
应用场景:
从应用的角度来说,一般当我们的脚本与 DOM 元素和其它脚本之间的依赖关系不强时,我们会选 用 async;当脚本依赖于 DOM 元素和其它脚本的执行结果时,我们会选用 defer。
当 JS 登场时,往往意味着对 DOM 的操作。DOM 操作所导致的性能开销的“昂贵”,大 家可能早就有所耳闻,雅虎军规里很重要的一条就是“尽量减少 DOM 访问”。