美文网首页
前端性能优化实践

前端性能优化实践

作者: liutianou | 来源:发表于2019-03-13 16:19 被阅读0次

目录

  • 页面内容
    • 减少HTTP请求数
    • 减少 DNS 查询
    • 缓存 Ajax 请求
    • 延迟加载
    • 预先加载
    • 减少DOM元素数量
    • 划分内容到不同域名
    • 尽量减少 iframe 使用

页面内容


减少 HTTP 请求数

Web 前端 80% 的响应时间花在图片、样式、脚本等资源下载上。浏览器对每个域名的连接数是有限制的,减少请求次数是缩短响应时间的关键。

  • 合并 JavaScript、CSS 等文件;
    • 服务器端(CDN)自动合并
    • 基于 Node.js 的文件合并工具一抓一大把
  • 使用CSS Sprite:将背景图片合并成一个文件,通过background-imagebackground-position 控制显示;
  • 使用内嵌的SVG
  • 内容分片,将请求划分到不同的域名上

减少 DNS 查询

用户输入 URL 以后,浏览器首先要查询域名(hostname)对应服务器的 IP 地址,一般需要耗费 20-120 毫秒 时间。DNS 查询完成之前,浏览器无法从服务器下载任何数据。

基于性能考虑,ISP、局域网、操作系统、浏览器都会有相应的 DNS 缓存机制。

  • IE 缓存 30 分钟,可以通过注册表中 DnsCacheTimeout 项设置;
  • Firefox 混存 1 分钟,通过 network.dnsCacheExpiration 配置;

首次访问、没有相应的 DNS 缓存时,域名越多,查询时间越长。所以应尽量减少域名数量。但基于并行下载考虑,把资源分布到 2 个域名上(最多不超过 4 个)。这是减少 DNS 查询同时保证并行下载的折衷方案。

缓存 Ajax 请求

Ajax 可以提高用户体验。但「异步」不意味着「及时」,优化 Ajax 响应速度提高性能仍是需要关注的主题。

最重要的的优化方式是缓存响应结果,详见 添加 Expires 或 Cache-Control 响应头

以下规则也关乎 Ajax 响应速度:

  • 启用 Gzip
  • 减少 DNS 查询
  • 压缩 JavaScript 和 CSS
  • 避免重定向
  • 配置 Etag

延迟加载

页面初始加载时哪些内容是绝对必需的?不在答案之列的资源都可以延迟加载。比如:

  • 非首屏使用的数据、样式、脚本、图片等;
  • 用户交互时才会显示的内容。

遵循「渐进增强」理念开发的网站:JavaScript 用于增强用用户体验,但没有(不支持) JavaScript 也能正常工作,完全可以延迟加载 JavaScript。

延迟渲染

将首屏以外的 HTML 放在不渲染的元素中,如隐藏的 <textarea>,或者 type 属性为非执行脚本的 <script> 标签中,减少初始渲染的 DOM 元素数量,提高速度。等首屏加载完成或者用户操作时,再去渲染剩余的页面内容。

预先加载

预先加载利用浏览器空闲时间请求将来要使用的资源,以便用户访问下一页面时更快地响应。

  • 无条件预先加载:页面加载完成(load)后,马上获取其他资源。以 google.com 为例,首页加载完成后会立即下载一个 Sprite 图片,此图首页不需要,但是搜索结果页要用到。
  • 有条件预先加载:根据用户行为预判用户去向,预载相关资源。比如 search.yahoo.com 开始输入时会有额外的资源加载。

Chrome 等浏览器的地址栏也有类似的机制。

  • 有「阴谋」的预先加载:页面即将上线新版前预先加载新版内容。网站改版后由于缓存、使用习惯等原因,会有旧版的网站更快更流畅的反馈。为缓解这一问题,在新版上线之前,旧版可以利用空闲提前加载一些新版的资源缓存到客户端,以便新版正式上线后更快的载入。

「双十一」、「黑五」这类促销日来临之前,也可以预先下载一些相关资源到客户端(浏览器、App 等),有效利用浏览器缓存和本地存储,降低活动当日请求压力,提高用户体验。

减少 DOM 元素数量

复杂的页面不仅下载的字节更多,JavaScript DOM 操作也更慢。例如,同是添加一个事件处理器,500 个元素和 5000 个元素的页面速度上会有很大区别。

从以下几个角度考虑移除不必要的标记:

  • 是否还在使用表格布局?
  • 塞进去更多的 <div> 仅为了处理布局问题?也许有更好、更语义化的标记。
  • 能通过伪元素实现的功能,就没必要添加额外元素,如清除浮动。

浏览器控制台中输入以下代码可以计算出页面中有多少 DOM 元素:
document.getElementsByTagName('*').length;

为什么不使用表格布局?

  • 更多的标签,增加文件大小;
  • 不易维护,无法适应响应式设计;
  • 性能考量,默认的表格布局算法会产生大量重绘(参见表格布局算法)。

划分内容到不同域名

浏览器一般会限制每个域的并行线程(一般为 6 个,甚至更少),使用不同的域名可以最大化下载线程,但注意保持在 2-4 个域名内,以避免 DNS 查询损耗。

例如,动态内容放在 csspod.com 上,静态资源放在 static.csspod.com 上。这样还可以禁用静态资源域下的 Cookie,减少数据传输,详见 Cookie 优化

尽量减少 iframe 使用

使用 iframe 可以在页面中嵌入 HTML 文档,但有利有弊。

<iframe> 优点

  • 可以用来加载速度较慢的第三方资源,如广告、徽章;
  • 可用作安全沙箱
  • 可以并行下载脚本。

<iframe> 缺点

  • 加载代价昂贵,即使是空的页面;
  • 阻塞页面 load 事件触发;

Iframe 完全加载以后,父页面才会触发 load 事件。 Safari、Chrome 中通过 JavaScript 动态设置 iframe src 可以避免这个问题。

  • 缺乏语义。

避免 404 错误

HTTP 请求很昂贵,返回无效的响应(如 404 未找到)完全没必要,降低用户体验而且毫无益处。

一些网站设计很酷炫、有提示信息的 404 页面,有助于提高用户体验,但还是浪费服务器资源。尤其糟糕的是外部脚本返回 404,不仅阻塞其他资源下载,浏览器还会尝试把 404 页面内容当作 JavaScript 解析,消耗更多资源。

补充规则:

  • 定义字符集,并放在 <head> 顶部。大多数浏览器会暂停页面渲染,直到找到字符集定义。

CSS


把样式表放在 <head> 中

把样式表放在 <head> 中可以让页面渐进渲染,尽早呈现视觉反馈,给用户加载速度很快的感觉。

这对内容比较多的页面尤为重要,用户可以先查看已经下载渲染的内容,而不是盯着白屏等待。

如果把样式表放在页面底部,一些浏览器为减少重绘,会在 CSS 加载完成以后才渲染页面,用户只能对着白屏干瞪眼,用户体验极差。

不要使用 CSS 表达式

CSS 表达式可以在 CSS 里执行 JavaScript,仅 IE5-IE7 支持,IE8 标准模式已经废弃。

CSS 表达式超出预期的频繁执行,页面滚动、鼠标移动时都会不断执行,带来很大的性能损耗。

IE7 及更低版本的浏览器已经逐渐成为历史,忘记它吧。

使用 <link> 替代 @import

对于 IE 某些版本,@import 的行为和 <link> 放在页面底部一样。所以,不要用它。

不要使用 filter

AlphaImageLoader 为 IE5.5-IE8 专有的技术,和 CSS 表达式一样,放进博物馆吧。

JavaScript


把脚本放在页面底部

浏览器下载脚本时,会阻塞其他资源并行下载,即使是来自不同域名的资源。因此,最好将脚本放在底部,以提高页面加载速度。

一些特殊场景无法将脚本放到页面底部的,可以考虑 <script> 的以下属性:

使用外部 JavaScript 和 CSS

外部 JavaScript 和 CSS 文件可以被浏览器缓存,在不同页面间重用,也能降低页面大小。

当然,实际中也需要考虑代码的重用程度。如果仅仅是某个页面使用到的代码,可以考虑内嵌在页面中,减少 HTTP 请求数。另外,可以在首页加载完成以后,预先加载子页面的资源。

压缩 JavaScript 和 CSS

压缩代码可以移除非功能性的字符(注释、空格、空行等),减少文件大小,提高载入速度。

移除重复脚本

重复的脚本不仅产生不必要的 HTTP 请求,而且重复解析执行浪费时间和计算资源。

减少 DOM 操作

JavaScript 操作 DOM 很慢,尤其是 DOM 节点很多时。

使用时应该注意:

  • 缓存已经访问过的元素;
  • 使用 DocumentFragment 暂存 DOM,整理好以后再插入 DOM 树;
  • 操作 className,而不是多次读写 style
  • 避免使用 JavaScript 修复布局。

使用高效的事件处理

  • 减少绑定事件监听的节点,如通过事件委托;
  • 尽早处理事件,在 DOMContentLoaded 即可进行,不用等到 load 以后。

图片


优化图片

建议参考以下工具。

PNG 终极优化:

优化 CSS Sprite

水平排列 Sprite 中的图片,垂直排列会增加图片大小;

Spirite 中把颜色较近的组合在一起可以降低颜色数,理想状况是低于 256 色以适用 PNG8 格式;

不要在 Spirite 的图像中间留有较大空隙。减少空隙虽然不太影响文件大小,但可以降低用户代理把图片解压为像素图的内存消耗,对移动设备更友好。

不要在 HTML 中缩放图片

不要使用 <img> 的 width、height 缩放图片,如果用到小图片,就使用相应大小的图片。

使用体积小、可缓存的 favicon.ico

Favicon.ico 一般存放在网站根目录下,无论是否在页面中设置,浏览器都会尝试请求这个文件。

所以确保这个图标:

  • 存在(避免 404);
  • 尽量小,最好小于 1K;
  • 设置较长的过期时间。

对于较新的浏览器,可以使用 PNG 格式的 favicon。

参考链接:

图片相关补充

设置图片的宽和高,以免浏览器按照「猜」的宽高给图片保留的区域和实际宽高差异,产生重绘。

相关文章

  • 前端面试必问及加分点---性能优化篇

    如何进行网站性能优化 你有用过哪些前端性能优化的方法? 谈谈性能优化问题 代码层面的优化 前端性能优化最佳实践

  • 前端性能优化(中)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(上)...

  • 前端性能优化(下)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(中)...

  • 前端性能优化(上)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 为什么要进行前端性能...

  • 文摘-20170226

    前端 释义前端指南 性能优化腾讯HTTPS性能优化实践 vuevue早期源码学习系列之一:如何监听一个对象的变化 ...

  • 前端性能优化原理集合篇

    之前购买了一本掘金小册《前端性能优化原理与实践》,文章短小精悍,至少对前端的性能优化与原理实践让我在读后有一个大体...

  • 前端性能优化清单

    本文参考前端性能优化最佳实践2018前端性能优化清单 以下是针对目前公司项目(我参与的项目)的具体情况,整理出来的...

  • 前端性能优化原理与实践(二)

    摘自前端性能优化原理与实践 从 Cookie 到 Web Storage、IndexDB Cookie Cooki...

  • 前端性能优化实践

    目录 页面内容减少HTTP请求数减少 DNS 查询缓存 Ajax 请求延迟加载预先加载减少DOM元素数量划分内容到...

  • 前端性能优化原理与实践(三)

    摘自前端性能优化原理与实践 DOM 优化原理与基本实践 JS是很快的,在 JS中修改DOM对象也是很快的。在JS的...

网友评论

      本文标题:前端性能优化实践

      本文链接:https://www.haomeiwen.com/subject/qqhtmqtx.html