关键请求链
说道关键请求链(Critical Request Chain),与之关联的往往是关键渲染路径(Critical Rendering Path)优化。CRP优化策略能够确定资源的优先级及加载顺序,从而让浏览器更快地加载页面。关键请求链就是浏览器在onload之前优先加载的一些资源(html,js,css,font等)的有序集合;
一般,我们使用Chrome devTools时,使用Audit bar进行性能分析与测试时通常可以在performance report中的Diagnostics标题下看到下图,其中第四个优化项是减小关键请求深度,具体优化策略后续讲到。下图所示该页面的关键请求链的长度为4。
关键渲染路径优化
根据参考文献1中的建议,优化关键渲染路径主要可以从以下三个方面入手:
- 关键资源的数量:
- 关键路径的长度
- 关键字节的数量
所谓的关键资源是可能阻塞页面首次渲染的资源,如link标签引入的css,script标签引入的js,font等。由于关键资源可能阻塞页面的首次渲染,因此这些资源的数目越小越好,可以分析代码依赖,移除或者延时加载使其成为非关键资源;关键路径的长度,也就是上图中提到的关键请求的深度,这些资源相互之间存在一定的依赖关系,往往需要前者加载完成后才能加载后续的资源,彼此的加载顺序如同有序的链式结构,这样必然会大大阻塞页面首屏速度;关键字节的数量,个人理解即关键资源的size,资源越小,浏览器加载和处理的速度越快,尤其对js脚本来说,处理相同大小的js比其他类型资源开销大很多。
另外,采用preload、dns-prefetch等技术加快关键资源的加载,避免非关键资源对关键资源的阻塞都是有效的关键资源路径优化策略。
javascript引擎
文献4中提到,其中JIT(Just-in-time)是为了提升javascript引擎的处理效率而引入的,可以将平台无关的字节码或者AST转为本地代码
一个JavaScript引擎不外乎包括以下部分:
第一, 编译器。主要工作是将源代码编译成抽象语法树,然后在某些引擎中还包含将抽象语法树转换成字节码。
第二, 解释器。在某些引擎中,解释器主要是接受字节码,解释执行这个字节码,然后也依赖垃圾回收机制等。
第三, JIT工具。一个能够能够JIT的工具,将字节码或者抽象语法树转换成本地代码,当然它也需要依赖牢记
第四, 垃圾回收器和分析工具(profiler)。它们负责垃圾回收和收集引擎中的信息,帮助改善引擎的性能和功效。
webkit中的javascript引擎主要有JavaScriptCore和V8引擎;前者是webkit默认的js引擎,V8是由Chrome为了提升性能开源的JS引擎。Chrome V8引擎相比JavaScriptCore中间过程不会生成字节码文件,而是使用JIT直接将抽象语法树AST直接转换为本地代码。
1、使用url-loader代替file-loader,从而在打包时将小于limit的静态资源直接以base64形式打包到主程序,减少js请求数;
2、减少script标签数;合并不必要的内嵌script标签,非加载依赖的外部script使用html5的async属性异步加载;
3、精简css;使用chrome-devTools检测https://developers.google.com/web/tools/chrome-devtools/css/reference#coverage;
4、非必要的弹窗等图片使用dataset延迟加载,降低首屏加载负荷;
cms_data拿到时间2.16s -> 1.63s
5、非首屏展示必须的js依赖在client.js中动态加载;
6、减小关键请求链长度;(9 -> 5);
7、swiper图片延时加载;devTools调试发现swiper图片总是优先加载,这导致首屏图片的加载被推迟,从而影响首屏时间;
8、使用合适的图片尺寸,图片resizing性能开销比较大(request->decode->resize->copy to CPU -> display);
9、预加载关键图片资源:; preload预加载的js不会立即执行;
problem 1: JS需要加载、解析/编译、执行、内存消耗;同样大小的图片和js,在浏览器端js的性能开销远远大于图片,并且js的这些过程会阻塞页面的渲染并延误页面可交互的时间(CPU idle大于50ms)
gzip压缩的170kb的js,加载3.4s,编译/解析2s,执行需要1.5s;图像解码和光栅化的过程则不会阻塞主线程及界面交互。
problem 2: 过大的图片资源;据统计,一个网站加载的资源带宽,60%是图片资源;推荐使用渐进式JPEG或者在兼容方案中使用webp;
(Progressive JPEGs rather than baseline JPEGs, better compression ratio, maybe 25%~30% savings and 15% faster loading speed, websites such as twitter/facebook; the drawback of Progressive JPEGs is its slower decode speed.)
problem 3: 未使用CMS和react的情况下,window.onload事件触发时,会加载页面展示所需要的图片资源,而使用react加CMS系统后,页面展示的图片资源是通过异步请求获取的,onload事件触发时通常还未拿到异步请求的回调,也就是onload的时候页面展示所需要的图片资源并未获取,此时屏幕依然是白屏;
Tips: 1. img标签设置了display: none属性仍然会获取src对应的资源;而background-url()设置了display:none属性时不会请求对应的图片资源;
2. 不同位置中脚步的优先级顺序;
参考文献
- https://developers.google.cn/web/fundamentals/performance/critical-rendering-path/optimizing-critical-rendering-path
- https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf
- https://docs.google.com/document/d/1bCDuq9H1ih9iNjgzyAL0gpwNFiEP4TZS-YLRp_RuMlc/edit#
- https://blog.csdn.net/milado_nju/article/details/22101681
- https://csstriggers.com/