网页性能优化

时间:2021-08-20 21:14:04

网页性能优化

页面优化

页面优化可以提升页面的访问速度从而提高用户体验,优化的页面可以更好的提升 SEO 的效果同时也可以提高代码的可读性和维护性。

网页的生成过程,大致可以分成五步。

  1. HTML代码转化成DOM
  2. CSS代码转化成CSSOM(CSS Object Model)
  3. 结合DOM和CSSOM,生成一棵渲染树(包含每个节点的视觉信息)
  4. 生成布局(layout),即将所有渲染树的所有节点进行平面合成
  5. 将布局绘制(paint)在屏幕上

这五步里面,第一步到第三步都非常快,耗时的是第四步和第五步。

"生成布局"(flow)和"绘制"(paint)这两步,合称为"渲染"(render)。

重排和重绘

网页生成的时候,至少会渲染一次。用户访问的过程中,还会不断重新渲染。
以下三种情况,会导致网页重新渲染。

  1. 修改DOM
  2. 修改样式表
  3. 用户事件(比如鼠标悬停、页面滚动、输入框键入文字、改变窗口大小等等)

重新渲染,就需要重新生成布局和重新绘制。前者叫做"重排"(reflow),后者叫做"重绘"(repaint)。

需要注意的是,"重绘"不一定需要"重排",比如改变某个网页元素的颜色,就只会触发"重绘",不会触发"重排",因为布局没有改变。但是,"重排"必然导致"重绘",比如改变一个网页元素的位置,就会同时触发"重排"和"重绘",因为布局改变了。

对于性能的影响

重排和重绘会不断触发,这是不可避免的。但是,它们非常耗费资源,是导致网页性能低下的根本原因。

提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。

前面提到,DOM变动和样式变动,都会触发重新渲染。但是,浏览器已经很智能了,会尽量把所有的变动集中在一起,排成一个队列,然后一次性执行,尽量避免多次重新渲染。

一般的规则是:

  1. 样式表越简单,重排和重绘就越快。
  2. 重排和重绘的DOM元素层级越高,成本就越高。
  3. table元素的重排和重绘成本,要高于div元素

提高性能的九个技巧

有一些技巧,可以降低浏览器重新渲染的频率和成本。

第一条 DOM 的多个读操作(或多个写操作),应该放在一起。不要两个读操作之间,加入一个写操作。

    // bad
    div.style.left = div.offsetLeft + 10 + "px";
    div.style.top = div.offsetTop + 10 + "px";
    
    // good
    var left = div.offsetLeft;
    var top  = div.offsetTop;
    div.style.left = left + 10 + "px";
    div.style.top = top + 10 + "px";

第二条 如果某个样式是通过重排得到的,那么最好缓存结果。避免下一次用到的时候,浏览器又要重排。

    // bad
    var left = 10;
    var top = 10;
    el.style.left = left + "px";
    el.style.top  = top  + "px";
    
    // good 
    el.className += " theclassname";
    
    // good
    el.style.cssText += "; left: " + left + "px; top: " + top + "px;";

第三条 不要一条条地改变样式,而要通过改变class,或者csstext属性,一次性地改变样式。

第四条 尽量使用离线DOM,而不是真实的网面DOM,来改变元素样式。比如,操作Document Fragment对象,完成后再把这个对象加入DOM。再比如,使用 cloneNode() 方法,在克隆的节点上进行操作,然后再用克隆的节点替换原始节点。

第五条 先将元素设为display: none(需要1次重排和重绘),然后对这个节点进行100次操作,最后再恢复显示(需要1次重排和重绘)。这样一来,你就用两次重新渲染,取代了可能高达100次的重新渲染。

第六条 position属性为absolute或fixed的元素,重排的开销会比较小,因为不用考虑它对其他元素的影响。

第七条 只在必要的时候,才将元素的display属性为可见,因为不可见的元素不影响重排和重绘。另外,visibility : hidden的元素只对重绘有影响,不影响重排。

第八条 使用虚拟DOM的脚本库,比如React等。

第九条 使用 window.requestAnimationFrame()、window.requestIdleCallback() 这两个方法调节重新渲染

一些问题

一、 如何对网站的的资源和文件进行优化
  1. 文件的合并(减少http的请求)
  2. 文件的压缩(减少文件的体积)
  3. 使用cdn托管资源
  4. 使用缓存
  5. gizp压缩js和css文件
  6. mete标签的优化。Heading标签的优化和alt优化
  7. 反向链接,网站外链优化
二 、说出三种减少页面加载的方法(加载时间感知的时间或实际加载时间)
  1. CSS Sprites
  2. Js css源码的压缩。图片大小控制合适
  3. 网页gizp
  4. cdn托管
  5. Data缓存
  6. 图片服务器

三 、网页加载速度的优化

  1. 减少请求
  2. 整合资源
  3. 使用浏览器缓存和本地缓存
  4. 首次使用的时候在HTML中嵌入资源
  5. 使用HTML5服务端发送事件
  6. 消除重定向
  7. 减少资源负载
  8. 压缩文本和图像
  9. 代码简化
  10. 使用html5和css3来简化页面
  11. 延迟读取和执行的脚本
  12. 使用ajax来增强进程
  13. 根据网络状况进行适配处理
  14. 对于多线程来说尽量使用html5的web worker特性
  15. 将click事件替换成touch事件
  16. 支持spdy协议

四、为什么利用多个域名来提供网站资源会更有效?

  1. 突破浏览器的并发限制
  2. 节约cookie带宽
  3. cdn缓存更方便
  4. 防止不必要的安全问题(尤其是cookie隔离尤为重要)
  5. 节约主机域名链接数,优化页面响应速度

五、前端性能如何调优

  1. 减少http的请求数
  2. 使用内容分布式网络(cdn)
  3. 给头部添加一个失效期或者cache-control
  4. Gzip压缩组件
  5. 把样式表放在前面
  6. 把脚本放在最后
  7. 不使用css表达式
  8. 使用外部的Javascript和css
  9. 减少dns的查询
  10. 减小javaScript和css

六、怎样解决请求过多问题

  1. 合并js和css文件
  2. 合并图片css sprite
  3. 使用image maps
  4. Data嵌入图片
  5. 使用cdn减少HTTP请求头

七、百度移动端首页秒开是怎样做到的?

  1. 静态文件的放置
  2. 缓存
  3. 外链
  4. 缓存dom
  5. 使用iconfont
  6. 卡片的异步加载与缓存
  7. 不在首屏的就要 异步化
  8. 少量静态文件的域名