首页 > 其他分享 >第二十四篇 最佳实践 - 性能

第二十四篇 最佳实践 - 性能

时间:2023-04-05 22:55:12浏览次数:42  
标签:浏览器 JavaScript 实践 最佳 Cookie 二十四篇 页面 CSS 加载

by caix in 深圳

前端性能优化最佳实践

客户端性能、服务器端、网络性能

1、页面内容

减少 HTTP 请求数
减少 DNS 查询
避免重定向
缓存 Ajax 请求
延迟加载
预先加载
减少 DOM 元素数量
划分内容到不同域名
尽量减少 iframe 使用
避免 404 错误

2、服务器

使用 CDN 
添加 Expires 或 Cache-Control 响应头
启用 Gzip
配置 Etag
尽早输出缓冲
Ajax 请求使用 GET 方法
避免图片 src 为空

3、Cookie

减少 Cookie 大小
静态资源使用无 Cookie 域名

4、CSS

把样式表放在 <head> 中
不要使用 CSS 表达式
使用 <link> 替代 @import
不要使用 filter

5、JavaScript

把脚本放在页面底部
使用外部 JavaScript 和 CSS
压缩 JavaScript 和 CSS
移除重复脚本
减少 DOM 操作
使用高效的事件处理

6、图片

优化图片
优化 CSS Sprite
不要在 HTML 中缩放图片
使用体积小、可缓存的 favicon.ico

7、移动端

保持单个文件小于 25 KB
打包内容为分段(multipart)文档
页面内容

1、减少 HTTP 请求数

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

通过简洁的设计减少页面所需资源,进而减少 HTTP 请求,这是最直接的方式,前提是你的 Boss、设计师同事不打死你。所以,还是另辟蹊径吧:

合并 JavaScript、CSS 等文件;

服务器端(CDN)自动合并
基于 Node.js 的文件合并工具一抓一大把

使用CSS Sprite:将背景图片合并成一个文件,通过background-image 和 background-position 控制显示;

Sprite Cow
Spritebox


  逐步被 Icon Font 和 SVG Sprite 取代。

Image Map:合并图片,然后使用坐标映射不同的区域。

  缺点:仅适用于相连的图片;设置坐标过程乏味且易出错;可访性问题。不推荐使用这种过时的技术。

Inline Image:使用 Data URI scheme  将图片嵌入 HTML 或者 CSS 中。

  会增加文件大小,也可能产生浏览器兼容及其他性能问题(有待整理补充)。

未来的趋势是使用内嵌 SVG。

2、减少 DNS 查询

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

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

IE 缓存 30 分钟,可以通过注册表中 DnsCacheTimeout 项设置;
Firefox 混存 1 分钟,通过 network.dnsCacheExpiration 配置;
(TODO:补充其他浏览器缓存信息)

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

3、避免重定向

HTTP 重定向通过 301/302 状态码实现。

HTTP/1.1 301 Moved Permanently  
Location: http://example.com/newuri  
Content-Type: text/html  

客户端收到服务器的重定向响应后,会根据响应头中 Location 的地址再次发送请求。重定向会影响用户体验,尤其是多次重定向时,用户在一段时间内看不到任何内容,只看到浏览器进度条一直在刷新。

有时重定向无法避免,在糟糕也比抛出 404 好。虽然通过 HTML meta refresh 和 JavaScript 也能实现,但首选 HTTP 3xx 跳转,以保证浏览器「后退」功能正常工作(也利于 SEO)。

最浪费的重定向经常发生、而且很容易被忽略:URL 末尾应该添加 / 但未添加。比如,访问 http://astrology.yahoo.com/astrology 将被 301 重定向到 http://astrology.yahoo.com/astrology/(注意末尾的 /)。如果使用 Apache,可以通过  Alias 或 mod_rewrite 或 DirectorySlash 解决这个问题。

网站域名变更:CNAME 结合 Alias 或 mod_rewrite 或者其他服务器类似功能实现跳转。

4、缓存 Ajax 请求

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

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

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

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

5、延迟加载

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

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

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

6、预先加载

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

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

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

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

  TODO: Prefetch 相关细节

Resource Hints Spec

7、减少 DOM 元素数量

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

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

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

浏览器控制台中输入以下代码可以计算出页面中有多少 DOM 元素:

document.getElementsByTagName('*').length;  

对比标记良好的的网站,看看差距是多少。

  为什么不使用表格布局?
  
  更多的标签,增加文件大小;
  不易维护,无法适应响应式设计;
  性能考量,默认的表格布局算法会产生大量重绘(参见表格布局算法)。
  
划分内容到不同域名

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

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

更多信息参考 Maximizing Parallel Downloads in the Carpool Lane

8、尽量减少 iframe 使用

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

 优点:

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

 缺点:

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

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

缺乏语义。

9、避免 404 错误

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

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

补充规则:

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

服务器相关优化设置可参考 H5BP 相关项目:

Nginx HTTP server boilerplate configs
Apache HTTP server boilerplate configs
IIS Web.Config Boilerplates

1、使用 CDN

网站 80-90% 响应时间消耗在资源下载上,减少资源下载时间是性能优化的黄金发则。

相比分布式架构的复杂和巨大投入,静态内容分发网络(CDN)可以以较低的投入,获得加载速度有效提升。

添加 Expires 或 Cache-Control 响应头

静态内容:将 Expires 响应头设置为将来很远的时间,实现「永不过期」策略;

动态内容:设置合适的 Cache-Control 响应头,让浏览器有条件地发起请求。

2、启用 Gzip

Gzip 压缩通常可以减少 70% 的响应大小,对某些文件更可能高达 90%,比 Deflate 更高效。主流 Web 服务器都有相应模块,而且绝大多数浏览器支持 gzip 解码。所以,应该对 HTML、CSS、JS、XML、JSON 等文本类型的内容启用压缩。

注意,图片和 PDF 文件不要使用 gzip。它们本身已经压缩过,再使用 gzip 压缩不仅浪费 CPU 资源,而且还可能增加文件体积。

对于不支持的 Gzip 的用户代理,通过设置 Vary 响应头,返回为压缩的数据:

Vary: *  

3、配置 Etag

Etag 通过文件版本标识,方便服务器判断请求的内容是否有更新,如果没有就响应 304,避免重新下载。

当然,启用 Etag 可能会导致其他问题,还需要根据具体情况做判断。(TODO:补充相关内容)

4、尽早输出(flush)缓冲

用户请求页面时,服务器通常需要花费 200 ~ 500 毫秒来组合 HTML 页面。在此期间,浏览器处于空闲、等待数据状态。使用PHP 中的 flush() 函数,可以发送部分已经准备好的 HTML 到浏览器,以便服务器还在忙于处理剩余页面时,浏览器可以提前开始获取资源。

可以考虑在  之后输出一次缓冲,HTML head 一般比较容易生成,先发送以便浏览器开始获取  里引用的 CSS 等资源。

5、Ajax 请求使用 GET 方法

浏览器执行 XMLHttpRequest POST 请求时分成两步,先发送 Header,再发送数据。而 GET 只使用一个 TCP 数据包发送数据,所以首选 GET 方法。

根据 HTTP 规范,GET 用于获取数据,POST 则用于向服务器发送数据,所以 Ajax 请求数据时使用 GET 更符合规范(GET 和 POST 对比)。

IE 中最大 URL 长度为 2K,如果超出 2K,则需要考虑使用 POST 方法。

6、避免图片 src 为空

图片 src 属性值为空字符串可能以下面两种形式出现:

HTML:

JavaScript:

var img = new Image();  
img.src = "";  

虽然 src 属性为空字符串,但浏览器仍然会向服务器发起一个 HTTP 请求:

IE 向页面所在的目录发送请求;
Safari、Chrome、Firefox 向页面本身发送请求;
Opera 不执行任何操作。

  以上数据较老,当下主流版本可能会有改变。

空 src 产生请求的后果不容小憩:

给服务器造成意外的流量负担,尤其时日 PV 较大时;
浪费服务器计算资源;
可能产生报错。


当然,浏览器如此实现也是根据 RFC 3986 - Uniform Resource Identifiers,当空字符串作为 URI 出现时,被当成相对 URI,具体算法参见规范 5.2 节。

空的 href 属性也存在类似问题。用户点击空链接时,浏览器也会向服务器发送 HTTP 请求,可以通过 JavaScript 阻止空链接的默认的行为。
Cookie

1、减少 Cookie 大小

Cookie 被用于身份认证、个性化设置等诸多用途。Cookie 通过 HTTP 头在服务器和浏览器间来回传送,减少 Cookie 大小可以降低其对响应速度的影响。

去除不必要的 Cookie;
尽量压缩 Cookie 大小;
注意设置 Cookie 的 domain 级别,如无必要,不要影响到 sub-domain;
设置合适的过期时间。

2、静态资源使用无 Cookie 域名

静态资源一般无需使用 Cookie,可以把它们放在使用二级域名或者专门域名的无 Cookie 服务器上,降低 Cookie 传送的造成的流量浪费,提高响应速度。

CSS

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

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

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

1、不要使用 CSS 表达式

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

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

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

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

2、不要使用 filter

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

  注意:
  
  这里所说的不是 CSS3 Filter,参考文章 Understanding CSS Filter Effects
JavaScript

把脚本放在页面底部

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

一些特殊场景无法将脚本放到页面底部的,可以考虑

标签:浏览器,JavaScript,实践,最佳,Cookie,二十四篇,页面,CSS,加载
From: https://www.cnblogs.com/caix-1987/p/17291227.html

相关文章

  • Redis实践操作之—— keyspace notification(键空间通知)
    源码地址:https://github.com/Tinywan/PHP_Experience一、需求分析:设置了生存时间的Key,在过期时能不能有所提示?如果能对过期Key有个监听,如何对过期Key进行一个回调处理?如何使用Redis来实现定时任务?二、序言:    本文所说的定时任务或者说计划任务并不是很多人想象中的那样,比......
  • 7·1HTTP协议的瓶颈|7·2双工通信的WebScoket|7·3探索式的实践-SPDY|7·4期盼已久的H
    HTTP协议的瓶颈影响Http网络请求的原因带宽延迟HTTP协议的瓶颈一条连接上只可发送一个请求请求只能从客户端开始。客户端不可以接受除响应意外的指令请求/响应头部不经压缩就发送每次互相发送相同的头部造成的浪......
  • 一个Web报表项目的性能分析和优化实践(六):设置MySQL的最大连接数(max_connections)
    在上一篇文章中"一个Web报表项目的性能分析和优化实践(二):MySQL数据库连接不够用(TooManyConnections)问题的一次分析和解决案例"提到,项目中新增几个数据库后,数据库最大连接数达到了默认的最大值100。此时,如果再创建连接,就会报错(TooManyConnections)。因此,需要手动设置MySQL的最......
  • 一个Web报表项目的性能分析和优化实践(四):MySQL建立索引,唯一索引和组合索引
    先大致介绍下项目的数据库信息。数据库A:主要存放的通用的表,如User、Project、Report等。数据库B、C、D:一个项目对应一个数据库,而且这几个项目的表是完全一样的。数据库表的特点A中的表:数据量几乎都比较小,比如User表中用户数,顶多也就几百上千。B中的表:X/Y/Z3张表几乎是确定的,Data表......
  • 旅游APP大数据分析:带你找到最佳旅游路线
    如今,旅游App已经成为了现代旅游的必备工具,而在这个数字化的时代,大数据的应用已经成为了旅游App的重要手段。本文将介绍旅游App大数据分析的应用,带你找到最佳旅游路线。一、大数据在旅游App中的应用随着互联网的发展和普及,旅游App已经成为了一个全球性的行业。而在这个行业中,大......
  • 性能测试入门实践路线图
    我转行做软件测试工作已有八年多了,从功能到自动化测试,然后负责性能测试团队和质量团队的技术专项治理,再到测试专家角色,负责整个技术项目的产品/运营和质量保障工作。其中性能测试和线上稳定性保障,算是我最擅长的技术领域。很多同学咨询过我,性能测试如何入门,如何快速提升压测和......
  • 第三十八篇 vue - 最佳实践 - 性能优化
    概述Vue在大多数常见场景下性能都是很优秀的,通常不需要手动优化。然而,总会有一些具有挑战性的场景需要进行针对性的微调。在本节中,我们将讨论用Vue开发的应用在性能方面该注意些什么首先,让我们区分一下web应用性能的两个主要方面1、页面加载性能首次访问时,应......
  • 第三十九篇 vue - 最佳实践 - 安全
    报告漏洞虽然很少发现新的漏洞,但我们仍建议始终使用最新版本的Vue及其官方配套库,以确保你的应用尽可能地安全。首要规则:不要使用无法信赖的模板使用Vue时最基本的安全规则就是不要将无法信赖的内容作为你的组件模板。使用无法信赖的模板相当于允许任意的JavaScript在你......
  • vivo 全球商城:优惠券系统架构设计与实践
    一、业务背景优惠券是电商常见的营销手段,具有灵活的特点,既可以作为促销活动的载体,也是重要的引流入口。优惠券系统是vivo商城营销模块中一个重要组成部分,早在15年vivo商城还是单体应用时,优惠券就是其中核心模块之一。随着商城的发展及用户量的提升,优惠券做了服务拆分,成立了独立的优......
  • 聊聊微前端的原理和实践
    作者:TanXin本文对微前端的概念和场景进行科普,介绍一些主流的微前端的实现库及其用法,并讲解部分这些库的原理和实践知识。一、微前端在项目迭代中,随着业务的发展壮大,项目的功能模块通常也会越来越多。可能原来所有的代码模块都在一个仓库里,由一个团队负责。但随着功能模块越来越多,......