从案例分析如何优化前端性能

作者:信息技术

从案例分析如何优化前端性能

2016/08/30 · 基础技术 · 性能

原文出处: css-tricks   译文出处:王下邀月熊   

在 De Voorhoede工作的日子里,我们一直在追寻为用户构建高性能的前端解决方案。不过并不是每个客户会乐于遵循我们的性能指南,以至于我们必须一遍又一遍地跟他们解释那些保证他们能够战胜竞争对手的性能策略的重要性。最近我们也重构了自己的官方主页,使其能够拥有更快地响应速度与更好地性能表现。
图片 1

如何运用最新的技术提升网页速度和性能

2016/08/29 · 基础技术 · 性能

原文出处: Declan   译文出处:众成翻译   

最近更新了我们的网站,它是经过了设计上的全面验收的。但实际上,作为软件开发者,我们会注重很多技术相关的零碎的东西。我们的目标是控制性能,注重性能,未来可伸展,为网站增添内容是一种乐趣。接着就来告诉你,为什么我们的网站速度比你们的快吧(抱歉,确实是这样的)。

前言
本文是@旭日云中竹带来的翻译与投稿。文章中提到的图片格式webp,自定义网页字体,懒加载等技术的运用,这些在大家的项目中现在运用的如何了呢?

性能调优始于设计

在前端项目中,我们常常与产品经理以及UI设计讨论如何在美感与性能之间达到平衡,我们坚信更快地内容呈现是好的用户体验的不可分割的一部分。在我们自己的网站中,我们是以性能优于美感。好的内容、布局、图片与交互都是构成你网站吸引力的不可或缺的部分,不过这些复杂的元素的使用往往也意味着页面加载速度的增加。设计的核心即在于决定我们网站需要呈现哪些内容,往往这里的内容会指图片、字体这样的偏静态的部分,我们首先也从对于静态内容的优化开始。

性能设计

在我们的项目中,我们每天都会和设计师和产品负责人讨论关于平衡美观和性能的问题。对于我们自己的网站,这样做是很简单的。简言之,我们认为好的用户体验从快速的内容传输开始,也就意味着 性能 > 美观

好的内容、布局、图片和交互是吸引用户的重要因素。这每个因素都会影响页面的加载时间和终端用户体验。每一步我们都在探讨如何在获得好的用户体验和保证设计美感的同时,最小化对性能的影响。

正文
最近也更新了我自己的网站,它是经过了设计上的全面验收的。但实际上,作为软件开发者,我们回注重很多技术相关的零碎的东西。我们的目标是控制性能,注重性能,未来可伸展,为网站增添内容是一种乐趣。接着就来告诉你,为什么我们的网站速度比你们的快吧。

Static Site Generator

为了演示与测试方便,我们基于NodeJS搭建了一个混合使用MarkDown与JSON作为配置的静态网站生成器,其中一个简单的博客类型的网站的配置信息如下:

JavaScript

{ "keywords": ["performance", "critical rendering path", "static site", "..."], "publishDate": "2016-08-12", "authors": ["Declan"] }

1
2
3
4
5
{
  "keywords": ["performance", "critical rendering path", "static site", "..."],
  "publishDate": "2016-08-12",
  "authors": ["Declan"]
}

而其内容为:

JavaScript

# A case study on boosting front-end performance At [De Voorhoede]() we try to boost front-end performance... ## Design for performance In our projects we have daily discussions...

1
2
3
4
# A case study on boosting front-end performance
At [De Voorhoede](https://www.voorhoede.nl/en/) we try to boost front-end performance...
## Design for performance
In our projects we have daily discussions...

下面,我们就这个静态网站,进行一些讨论。

内容优先

我们想要把核心内容尽快地呈现给用户,意味着我们要处理好基本的 HTML 和 CSS。每个页面都应该达到基本的目的:传递信息。JS、CSS、网页字体、图片、网站分析等优化都是位居于核心内容之下的。

性能设计

在我们的项目中,我们每天都会与设计师和产品负责任讨论关于平衡美观与性能的问题。对于我们自己的网站,这样做是很简单的。简言之,我们认为好的用户体验从快速的内容传输开始,也就意味着 性能 > 美观。

好的内容、布局、图片和交互式吸引用户的重要因素。这没个因素都会影响页面的加载时间和终端用户体验,每一步我们都在探讨如何在获得好的用户体验和保证设计美感的同时,最小化对性能的影响。

Image Delivery

图片是网站的不可或缺的部分,其能够大大提升网站的表现力与视觉效果,而目前平均大小为2406KB的网页中就有1535KB是图片资源,可见图片占据了静态资源多么大的一个比重,这也是我们需要重点优化的部分。
图片 2

可控性

给理想网站定义了标准后,我们总结出:要想达到预期效果,就要能对网站各方面的控制都游刃有余。我们选择构建自己的静态站点生成器,包括资源传输,并且由我们自己操控。

内容优先

我们想要把核心内容尽快地呈现给用户,意味着我们要处理好基本的 html 和 css。每个页面都应该达到基本的目的:传递信息。js、css、网页字体、图片、网站分析等优化都是位居于核心内容之下的。

WebP

WebP 是面向现代网页的高压缩低损失的图片格式,通常会比JPEG小25%左右。然后WebP目前被很多人忽视,也不常使用。截止到本文撰写的时候,WebP目前只能够在Chrome, Opera and Android (大概占用户数的 50%)这些浏览器中使用,不过我们还是有办法以JPG/PNG来弥补部分浏览器中不支持WebP的缺憾。

静态站点生成器

我们用 Node.js 实现了静态站点生成器。它是采用带有简短 JSON 页面描述标签的Markdown 文件来生成整个网站结构和它所有的资源。为了包括特殊的页面脚本,也可以附带一个 HTML 文件。以下是一个简单化的描述标签和 markdown 文件,用于博客的发布,用它来生成真正的 HTML

JSON 描述标签:

JavaScript

{ "keywords": ["performance", "critical rendering path", "static site", "..."], "publishDate": "2016-07-13", "authors": ["Declan"] }

1
2
3
4
5
{
  "keywords": ["performance", "critical rendering path", "static site", "..."],
  "publishDate": "2016-07-13",
  "authors": ["Declan"]
}

markdown 文件:

# Why our website is faster than yours We've recently updated our site. Yes, it has a complete... ## Design for performance In our projects we have daily discussions...

1
2
3
4
5
# Why our website is faster than yours
We've recently updated our site. Yes, it has a complete...
 
## Design for performance
In our projects we have daily discussions...
可控性

给理想网站定义了标准后,我们总结出:要想达到预期的效果,就要能对网站各方面的控制都游刃有余。我们选择构建自己的静态站点生成器,包括资源传输,并且由我们自己操控。

picture标签

使用picture标签可以方便的对于WebP格式不支持的情况下完成替换:

XHTML

<picture> <source type="image/webp" srcset="image-l.webp" media="(min-width: 640px)"> <source type="image/webp" srcset="image-m.webp" media="(min-width: 320px)"> <source type="image/webp" srcset="image-s.webp"> <source srcset="image-l.jpg" media="(min-width: 640px)"> <source srcset="image-m.jpg" media="(min-width: 320px)"> <source srcset="image-s.jpg"> <img alt="Description of the image" src="image-l.jpg"> </picture>

1
2
3
4
5
6
7
8
9
<picture>
  <source type="image/webp" srcset="image-l.webp" media="(min-width: 640px)">
  <source type="image/webp" srcset="image-m.webp" media="(min-width: 320px)">
  <source type="image/webp" srcset="image-s.webp">
  <source srcset="image-l.jpg" media="(min-width: 640px)">
  <source srcset="image-m.jpg" media="(min-width: 320px)">
  <source srcset="image-s.jpg">
  <img alt="Description of the image" src="image-l.jpg">
</picture>

这里我们使用了 picturefill by Scott Jehl作为Polyfill库来保证低版本的浏览器中能够支持picture标签,并且保证跨浏览器的功能一致性。并且我们还使用了img标签来保证那些不支持picture的浏览器能够正常工作。

图片传输

平均一个 2406kb 的网页中 1535kb 是图片。就因为图片在网站中占据了这么大的一个比例,所以它也是性能优化的重点之一。

图片 3

静态站点生成器

我们用 Node.js 实现了静态站点生成器。它是采用带有简短 JSON 页面描述标签的 Markdown 文件来省城整个网站结构和它所有的资源。为了包括特殊的页面脚本,也可以附带一个 HTML 文件。以下是一个简单化的描述标签和 markdown 文件,用于博客的发布,用它来生成真正的 HTML。

JSON 描述标签:

{
  "keywords": ["performance", "critical rendering path", "static site", "..."],
  "publishDate": "2016-08-29",
  "authors": ["Simon"]
}

markdown 文件:

# Why our website is faster than yours 
We've recently updated site. Yes, it has a complete...

## Design for performance
In our projects we have daily discussions...

图片多格式生成

现在我们已经可以通过设置不同的图片尺寸、格式来保证图片的分发优化,不过我们总不希望每次要用一张图片的时候就去生成6个不同的尺寸/实例。我们希望有一种抽象的方法可以帮我们自动完成这一步,为我们自动生成不同的格式/尺寸,然后自动插入合适的picture元素,在我们的静态网站生成器中是这么做的:

  • 首先是要gulp responsive来生成不同尺寸的图片,该插件同样会输出WebP格式的图片
  • 压缩生成好的图片
  • 用户只需要在MarkDown中编写![Description of the image](image.jpg)即可
  • 我们自定义的MarkDown渲染引擎会在处理过程中自动使用picture元素替换这些img标签

WebP格式

WebP是一种现代图片格式,为网页图片提供了出色的低损耗、有损压缩。WebP格式的图片实质上比其它格式的小,有时可以比同样的 JPEG 图片小 25%。 WebP被大多数人所忽略,也没被经常使用。截止到写这篇文章的时候,WebP 仅支持Chrome, Opera 和 Android (仍超过了我们50%的用户),但我们可以优雅降级为 JPG/PNG。

使用 <picture> 元素我们可以把图片从 WebP 优雅地降级到其它被广泛支持的图片格式,如JPEG:

XHTML

<picture> <source type="image/webp" srcset="image-l.webp" media="(min-width: 640px)"> <source type="image/webp" srcset="image-m.webp" media="(min-width: 320px)"> <source type="image/webp" srcset="image-s.webp"> <source srcset="image-l.jpg" media="(min-width: 640px)"> <source srcset="image-m.jpg" media="(min-width: 320px)"> <source srcset="image-s.jpg"> <img alt="Description of the image" src="image-l.jpg"> </picture>

1
2
3
4
5
6
7
8
9
<picture>
  <source type="image/webp" srcset="image-l.webp" media="(min-width: 640px)">
  <source type="image/webp" srcset="image-m.webp" media="(min-width: 320px)">
  <source type="image/webp" srcset="image-s.webp">
  <source srcset="image-l.jpg" media="(min-width: 640px)">
  <source srcset="image-m.jpg" media="(min-width: 320px)">
  <source srcset="image-s.jpg">
  <img alt="Description of the image" src="image-l.jpg">
</picture>

我们使用Scott Jehl 的 picturefill 来使那些不支持 <picture> 元素的浏览器获得支持,在各个浏览器中达到一致的效果

我们使用 <img> 作为那些不支持 <picture> 或者 JS 的浏览器的后备元素。使用图片的最大实例确保了它在后备方案中的可行性。

图片传输

平均一个2406kb的网页中1535kb是图片。就因为图片在网站中占据了这么大的一个比例,所以它也是性能优化的重点之一。

图片 4

QQ20160829-0@2x.png

SVG Animation

我们的网站中也存在着很多的Icon以及动画性质图片,这里我们是选择SVG作为Icon与Animation的格式,主要考虑有下:

  • SVG是矢量表示,往往比位图文件更小
  • SVG自带响应式功效,能够根据容器大小进行自动缩放,因此我们不需要再为了picture元素生成不同尺寸的图片
  • 最重要的一点是我们可以使用CSS去改变其样式或者添加动画效果,关于这一点可以参考CodePen上的这个演示 点击预览 。
    图片 5

生成

尽管图片传输方式已经确定了,我们仍需要思考该怎样有效地执行。我喜欢 <picture>元素的功能,但不喜欢写上面那些代码段,尤其是写内容时必须把它加进去。我们不想做这么费力的事情:每张图片都要写 6 个实例,所以优化这些图片并且把它们写在markdown文件的 <picture> 里面。所以:

WebP格式

WebP 是一种现代图片格式,为网页图片提供了出色的低损耗、有损压缩。WebP 格式的图片实质上比其它格式的小,有时可以比同样的 JPEG 图片小25%。WebP 被大多数人所忽略,也没被经常使用。截止到目前,WebP 仅支持chrome,opera 和 android,但我们可以优雅降级为 JPG/PNG。

使用 <picture> 元素我们可以把图片从 WebP 优雅地降级到其它被广泛支持的图片格式,如JPEG:

<picture>
    <source type="image/webp" srcset="image-l.webp" media="(min-width: 640px)">
    <source type="image/webp" srcset="image-m.webp" media="(min-width: 320px)">
    <source type="image/webp" srcset="image-s.webp">
    <source srcset="image-l.jpg" media="(min-width: 640px)">
    <source srcset="image-m.jpg" media="(min-width: 320px)">
    <source srcset="image-s.jpg" >
    <img alt="Description of the image" src="image-l.jpg">
</picture>

我们使用Scott Jehl 的 picturefill 来使那些不支持 <picture> 元素的浏览器获得支持,在各个浏览器中达到一致的效果.

我们使用<img/>作为那些不支持 <picture> 或者 JS 的浏览器的后备元素。使用图片的最大实例确保了它在后备方案中的可行性。

Custom Web Fonts

我们首先回顾下浏览器是如何使用自定义字体的,当浏览器识别到用户在CSS中基于@font-size定义的字体时,会尝试下载该字体文件。而在下载的过程中,浏览器是不会展示该字体所属的文本内容,最终导致了所谓的Flash of Invisible Text现象。现在很多的网站都存在这个问题,这也是导致用户体验差的一个重要原因,即会影响用户最主要的内容浏览这一操作。而我们的优化点即在于首先将字体设置为默认字体,而后在自定义的Web Font下载完毕之后对标准字体再进行替换操作,并且重新渲染整个文本块。而如果自定义的字体下载失败,整个内容还是能保证基本的可读性,不会对用户体验造成毁灭性的打击。
图片 6

首先,我们会为需要使用到的Web Fonts创建最小子集,即只将那些需要使用的字体提取出来,而并不需要让用户下载整个字体集,这里推荐使用Font squirrel webfont generator。另外,我们还需要为字体的下载设置监视器,即保证能够在字体下载完毕之后自动回调,这里我们使用的是fontfaceobserver,它会为页面自动创建一个监视器,在侦测到所有的自定义Web Fonts下载完毕后,会为整个页面添加默认的类名:

CSS

html {font-family: Georgia, serif;} html.fonts-loaded {font-family: Noto, Georgia, serif;}

1
2
html {font-family: Georgia, serif;}
html.fonts-loaded {font-family: Noto, Georgia, serif;}

不过现在CSS的font-display属性也原生提供了我们这种替换功能,更多详情可见font-display属性。

生成图片

在构建过程中,原图片的多个实例,包括JPG, PNG和WebP格式,我们使用 gulp responsive 来生成。

生成

尽管图片传输方式已经确定了,我们仍需要思考该怎样有效地执行。我喜欢 <picture> 元素的功能,但不喜欢写上面那些代码段,尤其是写内容时必须把它加进去。我们不想做这么费力的事情:每张图片都要写 6 个实例,所以优化这些图片并且把它们写在markdown文件的 <picture> 里面。所以:

JS 与 CSS 的懒加载

总的来说我们希望所有的资源能够尽可能快地加载完毕,不过往往为了保证首页加载的速度,我们会考虑将部分非首屏需要的JS/CSS文件进行延迟加载,或者对于重复的视图使用浏览器本地缓存。

最小化图片

生成图片

在构建过程中,原图片的多个实例,包括 jpg、png 和 webp 格式,我们使用 gulp responsive 来生成。

本文由杏彩发布,转载请注明来源

关键词: