当我们进行性能优化，我们在优化什么（LightHouse优化实操）
Tags: javascript, webdev, programming
Published: 2022-06-02 13:15:57

原文转载自「刘悦的技术博客」[https://v3u.cn/a_id_214](https://v3u.cn/a_id_214)

好的互联网产品不仅仅在功能上要高人一筹，在性能层面也需要出类拔萃，否则金玉其外败絮其中，页面是美轮美奂了，结果首屏半天加载不出来，难免让用户乘兴而来，败兴而归。

幸运的是，前端的性能优化有诸多有迹可循的理论和方法，其中相对权威的，无疑是LightHouse。

LightHouse 是一个开源的自动化工具，它作为 Chrome 浏览器的扩展程序运行，提供一套完整的站点评分标准，我们可以依据此标准对站点进行基准测试，从而达到优化的效果。

怎么打开LightHouse？可以在Chrome浏览器开发人员工具中找到LightHouse。

要打开“开发人员工具”，请选择：  
“顶部菜单→查看→开发人员→开发人员工具”  
或者使用快捷键：

Mac系统上的“⌥+⌘+I”  
Win系统上的“F12+Ctrl+Shift+I”。  

随后点击生成报告按钮即可：

![](https://v3u.cn/v3u/Public/js/editor/attached/20220602190650_38711.png)

LightHouse评分大体上有四大指标，分别为：性能、无障碍、最佳做法以及SEO。

性能指标（Performance）
-----------------

性能指标里又分为六个小指标：

Largest Contentful Paint 【简称LCP: 最大内容渲染】  
FCP最大内容渲染时间标记了渲染出最大文本或图片的时间。  
Total Blocking Time 【简称TBT: 总阻塞时间】  
TBT测量了FCP（首次内容渲染）和TTI（可交互时间）之间的总耗时。TTI可能会被主线程阻塞以至于无法及时响应用户。大于50ms的任务称为长任务，当任意长任务出现时，主线程则称为被阻塞状态。由于浏览器不会打断正在进行中的长任务，所以，如果用户在执行长任务时和页面有交互事件时，浏览器必须等到该长任务完成才能响应。TBT计算的是在FCP到TTI之间所有长任务时间内总和。  
First Contentful Paint 【简称FCP: 首次内容渲染】

FCP测量了从页面开始加载到页面任意部分的内容渲染到屏幕上。

Speed Index 【简称SI: 速度指数】  
SI速度指数表明了网页内容的可见填充速度。lighthouse首先捕获页面加载的视屏，然后对比帧与帧之间视觉效果变化（通过计算结构相似指数SSMI来比较)。  
Time to Interactive 【简称TTI: 可交互时间】  
可交互时间是指网页需要多长时间才能提供完整交互功能。TTI测量了从页面开始加载到页面的主要附属资源加载完毕，并且可以足够快速回应用户输入的所用时间。  
Cumulative Layout Shift 【简称CLS: 累积布局偏移】  
CLS累积布局偏移旨在测量可见元素在视口内的移动情况。CLS值越小越好。

性能优化手段
------

有哪些手段可以提高这些性能指标？

首先需要优化的是页面“资源”，这里的资源指的是页面中加载的一切元素，包含但不限于：js文件、css文件、图片、视频等。

对于js文件来说，首先要做的是业务分拆，不同页面只加载对应需要的文件，并且做到单页面只加载一个js文件，减少Http请求数，多余的文件要做合并压缩操作，但其实这里有一个基础问题，就是如果js文件本身就很庞大，压缩比例再高，也是杯水车薪，举个例子，一般情况下Jquery官方的压缩版就已经高达80kb左右了，这样的体积很难有再次压缩的优化空间，所以还不如直接摒弃Jquery，换成别的功能上可以替换的库，比如zepto，后者的体积只有26kb，是前者的四分之一。随后进行压缩合并操作，首先安装：

```
npm install uglify-js -g
```

以本站为例，业务上用到的js库分别为zepto.min.js、my.js、lazyload.min.js、wordcloud2.min.js iconfont.js，将这五个js文件进行合并压缩：

```
uglifyjs zepto.min.js my.js lazyload.min.js wordcloud2.min.js iconfont.js -o ./1-min.js
```

如此，最后得到一个体积为59kb的1-min.js文件，当然这是业务层面的压缩，还可以通过修改服务器进行gzip压缩：

```
location ~ .*.(jpg|gif|png|bmp|js|css)$ {  
                gzip on;  
                gzip_http_version 1.1;  
                gzip_comp_level 3;  
                gzip_types text/plain application/json application/x-javascript application/css application/xml application/xml+rss text/javascript application/x-httpd-php image/jpeg image/gif image/png image/x-ms-bmp;  
                }
```

加载方式上，尽量使用预加载：

```
<link rel="preload" as="script" href="1-min.js" />
```

同时，对于一些站外js比如广告，或者一些js特效，我们可以对其进行延时加载的操作，即首屏加载好之后，再加载这些逻辑：

```
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">  
(function() {  
var done = false;  
var script = document.createElement('script');  
script.async = true;  
script.type = 'text/javascript';  
script.src = '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';  
  
var createScript = setTimeout(  
function(){  
document.getElementsByTagName('HEAD').item(0).appendChild(script);  
WordCloud(canvas, options);  
}, 7000  
);  
  
script.onreadystatechange = script.onload = function(e) {  
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {  
(adsbygoogle = window.adsbygoogle || []).push({});  
}  
};  
})();  
</script>
```

上面的逻辑就是首屏完成7秒后再加载Google广告和标签云特效。

对于css文件的处理，原理和js文件差不多，宗旨也是分拆，缩小体积，并且压缩：

```
cssMinifier(['./bootstrap.min.css', '../js/kindeditor/plugins/code/prettify_dark.css', './style.css'], './tidy_min.css');
```

优化后，得到体积为17kb的tidy\_min.css文件。

对于图片文件，不仅是首图，所有图片最好都采用新的图片格式Webp，用以减少其体积，具体操作方法请移步：[石火电光追风逐日|前端优化之次时代图片压缩格式WebP的项目级躬身实践(Python3 PIL+Nginx)](https://v3u.cn/a_id_190)。对于特定的图片，比如Logo，使用svg格式图片，请移步：[Logo小变动，心境大不同，SVG矢量动画格式网站Logo图片制作与实践教程(Python3)](https://v3u.cn/a_id_207)

同时，对于图片一律声明宽高属性，并且使用支持lazyload.js组件推迟对屏幕外图片的加载。

使用viewport标签加快移动端的载入速度：

```
<meta name="viewport" content="width=device-width, initial-scale=1">  
    <meta name="applicable-device" content="pc,mobile"/>
```

无障碍（Accessibility）
------------------

访问无障碍检测所有用户是否都能有效地访问内容并浏览网站，无障碍性的每个指标项测试结果为pass或者fail，与性能指标项的计算方式不同，当页面只是部分通过某项指标时，页面的这项指标将不会得分。例如，如果页面中的一些元素有屏幕阅读器友好的命名，而其他的元素没有，那么这个页面的 screenreader-friendly-names 指标项得分为0。

一般情况下，优化无障碍其实是对于站点标签的优化，比如页面元素是否具备title标签、title元素是否按降序排列、是否声明了页面语言类型、元素是否具备alt标签等等，值得一提的是，页面对比度也是无障碍评分重要的一环，假如背景色是white，那么前景色最好选择高对比度的颜色，比如black。

最佳做法（Best Practice）
-------------------

最佳做法检测可以改善网页的代码健康状况的一些最佳做法，评分的分值由相关指标的加权平均值计算而来。

最佳做法指标我们可以理解为就是站点安全性的指标，多数情况下，需要保证协议为HTTPS，同时要开启CSP网页安全政策防止XSS攻击。

CSP 的实质就是白名单制度，开发者明确告诉客户端，哪些外部资源可以加载和执行，等同于提供白名单。它的实现和执行全部由浏览器完成，开发者只需提供配置。CSP 大大增强了网页的安全性。攻击者即使发现了漏洞，也没法注入脚本，除非还控制了一台列入了白名单的可信主机。

开启方法：

```
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
```

搜索引擎优化（SEO）
-----------

搜索引擎优化检测搜索引擎对网页内容的理解程度是怎样的，评分的分值由相关指标的加权平均值计算而来。

说白了，就是站点页面是否适合搜素引擎蜘蛛的抓取以及收录，以本站为例，搜索引擎需要的标签如下：

```
<head>  
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">  
    <meta name="viewport" content="width=device-width, initial-scale=1">  
    <meta name="applicable-device" content="pc,mobile"/>  
    <title>当我们进行性能优化，我们在优化什么（LightHouse优化实操）-刘悦</title>  
    <meta name="description" content="好的互联网产品不仅仅在功能上要高人一筹，在性能层面也需要出类拔萃，否则金玉其外败絮其中，页面是美轮美奂了，结果首屏半天加载不出来，难免让用户乘兴而来，败兴而归。幸运的是，前端的性能优化有诸多有迹可循的理论和方法，其中相对权威的，无疑是LightHouse。LightHouse是一个开源的自动化工具，它作为Chrome浏览器的扩展程序运行，提供一套完整的站点评分标准，我们可以依">  
    <meta content="刘悦" name="Author">  
    <link rel="canonical" href="https://v3u.cn/a_id_214"/>  
    <link rel="miphtml" href="https://v3u.cn/mipa_id_214">  
    <link rel="stylesheet" href="/v3u/Public/css/tidy_min.css?v=11"/>  
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>  
    <link rel="icon" href="favicon.ico" type="image/x-icon"/>  
    <link rel="stylesheet" href="/v3u/Public/css/share.min.css?v=1">  
</head>
```

包括页面标题、描述、作者、页面唯一标识等等元素。

当我们完成上面这些指标的优化之后，就可以，坐下来，欣赏这紫禁烟花一万重了：

![](https://v3u.cn/v3u/Public/js/editor/attached/20220602200644_24294.gif)

正是：东风夜放花千树，更吹落，星如雨。

结语
--

前端的性能分析和优化方式，无论是传统性能还是感官性能完全可以根据LightHouse按图索骥。过程中可以针对某些指标进行一定的取舍，虽然本站在LightHouse的优化实践中取得了一定的效果，但路漫漫其修远兮，吾将上下而求索。

原文转载自「刘悦的技术博客」 [https://v3u.cn/a_id_214](https://v3u.cn/a_id_214)