影响网站加载速度的因素有很多,我希望能通过自己对于网站速度加载优化的一系列总结来加深自己对网站性能优化的思考,同时分享出来希望能对你有一些收获。
当我们在讨论加载的时候,我们讨论的更多的时候加载网站上的资源。那一个普通的网站有哪些所谓的“资源”呢?
关于 JS/CSS 的加载和解析
如我们所知,最先加载的是 HTML 文件,然后根据你在 HTML <head>
标签中所定义的一系列 <link>
或是 <script src>
浏览器会开始加载并解析 JS 文件或是 CSS 文件。当然你的 CSS/JS 文件有可能在 <head>
加载并解析,也有可能会在 <body>
中加载并解析。
在这个过程中我们已经遇到了一些常见的问题,当浏览器加载 JS 文件时浏览器的主线程会被阻塞吗?我们应该在 <head>
标签中加载 JS 还是在 <body>
最底部加载 JS?你是否应该使用 <script async>
或是 <script defer>
来对你的 JS 资源加载做出调整?我没有一个标准答案,随着项目的不同策略也应该是不同的。但如果你还不清楚这些问题那关于浏览器加载优化的第一步则是搞清楚这几个问题:
- JS Script 加载和执行是否阻塞,阻塞了浏览器做什么?
<script>
标签的 async/await 如何使用?- CSS 的加载和解析是否阻塞?阻塞了浏览器做什么?
- 其他资源例如图片、视频的加载是否阻塞浏览器?
你真的需要加载全部吗?
想象一下你有一个图片分享网站,很不幸50%的用户只是点进来看一下首屏的内容然后就关掉了网页,剩下30%的用户会滑动屏幕到第二屏,最后20%的用户会滑动到页尾。此时你是否有必要给 100% 的用户都加载所有的图片呢?
带宽就像一根水管,如果你有大量的内容想要给用户,此时你所需要考虑的是哪些内容是用户迫切需要的,哪些内容是用户可能不需要的。举例来说:
- 用户可能不需要非常迫切的看到首屏之外的图片和视频,所以你可以使用浏览器提供的
<img/iframe loading="lazy">
来对不需要的资源进行懒加载。把水管留给更重要的资源。 - 用户也不需要你下次跳转才能用到的 CSS 和 JS,这也是为什么 webpack 有
code splitting
以及 React 会有React.lazy
以及Suspense
。对于 CSS 你可以考虑 Critical CSS 优化,相信你可以通过关键字找到更优质的相关文章。 - 不同的资源有不同的优先级,当前页面所能使用到的 HTML 和 CSS 的优先级可能比 JS 更高。而 JS 又比图片、视频的优先级更高。于此同时也要考虑不同在资源加载执行的成本也是不同的,加载解析图片的成本显然要比同等大小的 JS 要低很多。所以在不同文件类型之间对比大小是没有意义的。
水管固定的情况下如何流更多的水?
你可以加大水管的水压,上一台更好的发动机引擎,而这台引擎就是 CDN。
如果你已经有 CDN 了那还能做什么?如之前所说你需要把不用的资源推迟加载,把重要的资源提前加载。其实这也正是你要做的事情 —— 对资源进行优先级划分。
划分优先级的时候可以遵循如下规则:
- 提前加载最重要的资源(可能是 HTML/CSS)
Push
(orpreload
) the most important resources. - 尽可能快的渲染首屏内容,如果是 SPA 则是尽快渲染第一个路由的内容。
Render
the initial route as soon as possible. - 缓存其他资源。(当浏览器再次加载相同的内容时完全没有必要重复从服务器上下载)
Pre-cache
remaining assets. - 懒加载其他页面的内容或是不重要的内容(比如图片视频 iframe 或是网站的评论框)
Lazy load
other routes and non-critical assets.
上面的这四个原则被 Google 称之为 PRPL(Push/Render/PreCache/Lazyload) 原则,如果你英文过关的话 Google 的文章 可能讲的更好。
我如何知道我所做是事情是有用的?
当你设置了图片的 lazyload 在浏览器上之后你一定想知道对你的网站产生了怎样的影响,下一篇文章会继续讲述你如何量化你的网站性能?满分100分的话你能得几分?有哪些重要的指标是我们应该关注的。希望我能坚持写下去,
如果你很耐心地看完了这篇文章并且觉得有收获的话,欢迎留言和分享。期待下次再见。