提高代码运行速度,或许我们从来没有优化这些页面来提高速度

想要开发优秀的网站,你必须了解你的用户,知道他们想要达到什么目的,同时还要明白浏览器的工作原理,从而能够打造快速良好的体验,我最近在PageSpeed Insights 中运行了我的网页,得分最低,该工具给出了一些建议,但是我不太明白,例如如何移除渲染屏蔽的JavaScript,什么是异步脚本。这些问题都与关键呈现路径相关,关键呈现路径是指浏览器呈现网页要经历的一系列步骤,我觉得很多人都认为浏览器负责所有工作,但是你一旦理解了浏览器是如何构建DOM CSSOM对象模型布局和Paint你就可以构建能在一秒内呈现的网页

当你请求某个URL并按下Enter,浏览器就会想服务器发送一个请求,例如我们可以在命令行里模拟下浏览器收到响应后即我们在这里看到的HTML浏览器必须将所有的标记都转化为我们在屏幕上看到的这些内容,有没有想过这一切是怎么发生的?

浏览器会遵守定义完善的步骤并从处理HTML和构建DOM开始,HTML规范包含了一组规则,规定了我们应该如何处理接收的数据,例如在HTML中尖括号里包含的文本具有特殊含义,表示的是标记,因此每当我们遇到标记,浏览器都会发出一个令牌,这里是个以标签HTML开始的令牌,然后是head,这整个流程都由令牌生成器来完成,当令牌生成器在执行这些工作时,另一个流程正在消耗这些

令牌并将它们转换为节点对象,例如我们转换了第一个HTML令牌,并创建了HTML节点,然后消耗下一个令牌并创建head节点,节点之间有关系吗?是的,令牌生成器发出了起始和结束令牌,表明了节点之间的关系。

最终当我们消耗了所有这些令牌后,就形成了文档对象模型,简称DOM,它是一个树结构,表示了HTML的内容和属性以及各个节点之间的所有关系。

实际上,浏览器会逐步构建DOM,你可以利用这一点来提高网页的呈现速度,实际上google在这方面做的很棒,我来演示下

每当你向google发送一个搜索请求,服务器都会做出非常巧妙的响应,甚至在服务器知道搜索结果前,就会立即返回网页标题,就是在这里看到的,这一标题对所有用户来说都是相同的,这样浏览器能够开始处理响应并逐步构建DOM,甚至有可能呈现该标题

一旦搜索结果准备好后,剩余的HTML浏览器会解析并展示相关内容

可以看出,浏览器不用等待,所有的HTML都好了后再处理,你的服务器也不应该这样,实际上,返回解析的HTML是个很好的性能优化。逐步交付HTML太机智了。很好奇Google的工程师是怎么衡量和优化他们的网页性能的。

解析功能开始按步处理每个部分和我们之前描述的一样即生成令牌,将令牌转换为节点,并构建出DOM树。时间轴向我们详细展示了浏览器加载页面时执行的操作。

首先可以看到发送出去的css请求,它发生在收到第一部分HTML之后,这里解析器发现了链接标记并发起了css请求,然后我们等待获取css字节内容,然后我们看到Recalculate Style事件,这里我将css响应转换为css对象模型,我们的css非常小,所以只需要几毫秒就完成了转换。

但是对于更大型的样式表来说,肯定时间更长。

DOM包含了页面的所有内容,CSSOM包含了页面的所有样式,我如何将内容和样式转换成像素显示到屏幕上呢?觉得少了中间一步,你的想法不错,现在我们需要将DOM和CSSOM树组成渲染树,并捕获你刚刚提到的内容,渲染树的最重要特性是仅捕获可见内容,要了解具体的操作流程,我们来看看屏幕上的这个简单示例,顶部是DOM树,底部是CSS对象模型,要构建渲染树,我们从DOM树的根部开始,

这里是p节点,看看有没有任何相符的CSS规则,这里的确有一个相符的规则,让所有的字体大小都设置为16px并且为粗体,我们将p节点复制到渲染树里,处理完p节点后,我们向下浏览该树,然后我们看到“hello”是个文本节点,并将其复制到渲染树上,然后是span节点有一个相符的CSS规则,有一个span是段落节点的子节点,但是注意到这个规则的某个属性标记为display:none,表示这个span的内容不应呈现,因为我们提到渲染树仅捕获可见内容,

所以我们可以跳过它和它的所有子节点并转到下一节点,这里的话是另一个文本节点,我们将其复制到渲染树里

所以渲染树会同时捕获内容和样式。

这是Hello World页面的DOM和CSS树,要构建渲染树我们从DOM树的HTML节点开始,HTML和head部分不包含任何可见信息,多以我们快速地从渲染树里修剪它们,接着是body节点我们将其复制过来,树的左侧应该看起来比较熟悉,这是我们刚刚构建的部分,我们将其也复制过来,最终我们达到了div和img节点,这两个都包含可见内容,所以也复制到渲染树里,包括它们的样式,完成后将这个渲染树与屏幕的内容对比下,渲染树是个很好的展示结果,没有不必要的文本。

现在已经接近尾声了,我们还需要弄明白最后一个问题就是所有元素应该放在页面的哪个位置撒花姑娘,改如何放置,这就是布局步骤,我们来看看,

现在只剩下绘制像素了。

当我们开始接收这个HTML时,我们就开始解析它,所以解释DOM是第一步,DOM可以逐步构建并非一次性完成所有响应,所以我们可能不会立即构建完毕,在head中我们将发现CSS和JavaScript的链接,然后我们就发出这些请求,但是有个陷阱,脚本是同步的,在获得CSSOM之前,我们无法执行它,所以我们需要需要尽快创建CSSOM,完成CSSOM将取消屏蔽JavaScritp引擎,所以我们将在收到JavaScript后立即执行它。JavaScript完成后我们就可以继续并完成DOM的构建,获得DOM和CSSOM后,我们将合并二者并构建渲染树,然后运行布局并绘制网页。

我们完成了关键呈现路径的各个部分,我们来从头到尾地看看时间轴是怎么汇总这些部分的。

网站性能优化(website performance optimization)的更多相关文章

  1. 网站性能优化(Yahoo 35条)

    Yahoo 网站性能优化 35条 一.内容部分 尽量减少 HTTP请求 减少 DNS查找 避免跳转 缓存 Ajxa 推迟加载 提前加载 减少 DOM元素数量 用域名划分页面内容 使 frame数量最少 ...

  2. Yahoo团队经验:网站性能优化的34条黄金法则

    Yahoo团队总结的关于网站性能优化的经验,非常有参考价值.英文原文:http://developer.yahoo.com/performance/rules.html 1.尽量减少HTTP请求次数 ...

  3. 网站性能优化实战——从12.67s到1.06s的故事

    文章摘自https://juejin.im/post/5b0b7d74518825158e173a0c 作为互联网项目,最重要的便是用户体验.在举国“互联网+”的热潮中,用户至上也已经被大多数企业所接 ...

  4. Yahoo网站性能优化的34条规则

    摘自:http://blog.chinaunix.net/uid/20714478/cid-74195-list-1.html Yahoo网站性能优化的34条规则 1.尽量减少HTTP请求次数 终端用 ...

  5. Yahoo!团队实践分享:网站性能优化的34条黄金守则

    (一)内容 Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客并在各种会议上参与探讨.最佳实 ...

  6. input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has

    input屏蔽历史记录   设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处   ;(function($){$.ex ...

  7. Yahoo! 35条网站性能优化建议

    Yahoo! 35条网站性能优化建议 Yahoo!的 Exceptional Performance团队为改善 Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客 ...

  8. Yslow网站性能优化工具

    Yslow是一款网站性能优化的插件:

  9. asp.net网站性能优化2则

    摘要:Web服务器的性能优化有很多资料介绍了,多台主机负载均衡,查询结果的多级缓 存,数据库索引优化等都是常见的优化手段.随着后端优化空间越来越小,现在越来越多 的网站更注重前端性能的优化,就是浏览器 ...

  10. 网站性能优化小结和spring整合redis

    现在越来越多的地方需要非关系型数据库了,最近网站优化,当然从页面到服务器做了相应的优化后,通过在线网站测试工具与之前没优化对比,发现有显著提升. 服务器优化目前主要优化tomcat,在tomcat目录 ...

随机推荐

  1. C# List分组

    //分组 8个为一组 List<List<string>> ArrayList = sArray.Select((x, i) => new { Index = i, Va ...

  2. Object.keys 返回由一个给定对象的自身可枚举属性组成的数组

    在实际开发中,我们有时需要知道对象的所有属性, 原生js给我们提供了一个很好的方法:Object.keys(),该方法返回一个数组 http://blog.csdn.net/u014035151/ar ...

  3. CDOJ 1264 人民币的构造 区间问题+数论

    人民币的构造 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Status ...

  4. zookeeper系列(二)zookeeper的使用--javaAPI

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败: 出处:http://www.cnblogs.com/leesf456/ (尊重原创,感谢作者整理的这么好,作者的部分内容添加了我的理解 ...

  5. scrapy_redis的使用

    配置Scrapy-Redis 配置Scrapy-Redis非常简单,只需要修改一下settings.py配置文件即可. 1. 核心配置 首先最主要的是,需要将调度器的类和去重的类替换为Scrapy-R ...

  6. 去掉input type=file的默认样式

    原样式: 解决: 加style="opacity: 0;"变成透明的 然后可以外面套个div,在div上自定义样式.

  7. ZOJ - 1586 QS Network (Prim)

    ZOJ - 1586 QS Network (Prim) #include<iostream> #include<cstring> using namespace std; + ...

  8. leetcode探索中级算法

    leetcode探索中级答案汇总: https://leetcode-cn.com/explore/interview/card/top-interview-questions-medium/ 1)数 ...

  9. 如何选择K-Means中K的值

    K-Means需要设定一个簇心个数的参数,现实中,最常用于确定K数的方法, 其实还是人手工设定.例如,当我们决定将衣服做成几个码的时候,其实就是在以 人的衣服的长和宽为为特征进行聚类.所以,弄清楚我们 ...

  10. Redis ==> 集群的三种模式

    一.主从同步/复制 通过持久化功能,Redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,因为持久化会把内存中数据保存到硬盘上,重启会从硬盘上加载数据. 但是由于数据是存储在一台服务器 ...