Web 性能优化:理解及使用 JavaScript 缓存

您所在的位置:网站首页 web性能优化方法 Web 性能优化:理解及使用 JavaScript 缓存

Web 性能优化:理解及使用 JavaScript 缓存

2023-08-28 19:33| 来源: 网络整理| 查看: 265

阿里云最近在做活动,低至2折,有兴趣可以看看:https://promotion.aliyun.com/...

为了保证的可读性,本文采用意译而非直译。

这是 Web 性能优化的第 5 篇,上一篇在下面看点击查看:

Web 性能优化:使用 Webpack 分离数据的正确方法 Web 性能优化:图片优化让网站大小减少 62% Web 性能优化:缓存 React 事件来提高性能 Web 性能优化:21种优化CSS和加快网站速度的方法

随着我们的应用程序的不断增长并开始进行复杂的计算时,对速度的需求越来越高(🏎️),所以流程的优化变得必不可少。 当我们忽略这个问题时,我们最终的程序需要花费大量时间并在执行期间消耗大量的系统资源。

缓存是一种优化技术,通过存储开销大的函数执行的结果,并在相同的输入再次出现时返回已缓存的结果,从而加快应用程序的速度。

如果这对你没有多大意义,那没关系。 本文深入解释了为什么需要进行缓存,缓存是什么,如何实现以及何时应该使用缓存。

什么是缓存 缓存是一种优化技术,通过存储开销大的函数执行的结果,并在相同的输入再次出现时返回已缓存的结果,从而加快应用程序的速度。

在这一点上,我们很清楚,缓存的目的是减少执行“昂贵的函数调用”所花费的时间和资源。

什么是昂贵的函数调用?别搞混了,我们不是在这里花钱。在计算机程序的上下文中,我们拥有的两种主要资源是时间和内存。因此,一个昂贵的函数调用是指一个函数调用中,由于计算量大,在执行过程中大量占用了计算机的资源和时间。

然而,就像对待金钱一样,我们需要节约。为此,使用缓存来存储函数调用的结果,以便在将来的时间内快速方便地访问。

缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能够更快地得到处理。

因此,当一个昂贵的函数被调用一次时,结果被存储在缓存中,这样,每当在应用程序中再次调用该函数时,结果就会从缓存中非常快速地取出,而不需要重新进行任何计算。

为什么缓存很重要?

下面是一个实例,说明了缓存的重要性:

想象一下,你正在公园里读一本封面很吸引人的新小说。每次一个人经过,他们都会被封面吸引,所以他们会问书名和作者。第一次被问到这个问题的时候,你翻开书,读出书名和作者的名字。现在越来越多的人来这里问同样的问题。你是一个很好的人🙂,所以你回答所有问题。

你会翻开封面,把书名和作者的名字一一告诉他,还是开始凭记忆回答?哪个能节省你更多的时间?

发现其中的相似之处了吗?使用记忆法,当函数提供输入时,它执行所需的计算并在返回值之前将结果存储到缓存中。如果将来接收到相同的输入,它就不必一遍又一遍地重复,它只需要从缓存(内存)中提供答案。

缓存是怎么工作的

JavaScript 中的缓存的概念主要建立在两个概念之上,它们分别是:

闭包 高阶函数(返回函数的函数) 闭包 闭包是函数和声明该函数的词法环境的组合。

不是很清楚? 我也这么认为。

为了更好的理解,让我们快速研究一下 JavaScript 中词法作用域的概念,词法作用域只是指程序员在编写代码时指定的变量和块的物理位置。如下代码:

function foo(a) { var b = a + 2; function bar(c) { console.log(a, b, c); } bar(b * 2); } foo(3); // 3, 5, 10

从这段代码中,我们可以确定三个作用域:

全局作用域(包含 foo 作为唯一标识符) foo 作用域,它有标识符 a、b 和 bar bar 作用域,包含 c 标识符

仔细查看上面的代码,我们注意到函数 foo 可以访问变量 a 和 b,因为它嵌套在 foo 中。注意,我们成功地存储了函数 bar 及其运行环境。因此,我们说 bar 在 foo 的作用域上有一个闭包。

你可以在遗传的背景下理解这一点,即个体有机会获得并表现出遗传特征,即使是在他们当前的环境之外,这个逻辑突出了闭包的另一个因素,引出了我们的第二个主要概念。

从函数返回函数 通过接受其他函数作为参数或返回其他函数的函数称为高阶函数。

闭包允许我们在封闭函数的外部调用内部函数,同时保持对封闭函数的词法作用域的访问

让我们对前面的示例中的代码进行一些调整,以解释这一点。

function foo(){ var a = 2; function bar() { console.log(a); } return bar; } var baz = foo(); baz();//2

注意函数 foo 如何返回另一个函数 bar。这里我们执行函数 foo 并将返回值赋给baz。但是在本例中,我们有一个返回函数,因此,baz 现在持有对 foo 中定义的bar 函数的引用。

最有趣的是,当我们在 foo 的词法作用域之外执行函数 baz 时,仍然会得到 a 的值,这怎么可能呢?😕

请记住,由于闭包的存在,bar 总是可以访问 foo 中的变量(继承的特性),即使它是在 foo 的作用域之外执行的。

案例研究:斐波那契数列

斐波那契数列是什么?

斐波那契数列是一组数字,以1 或 0 开头,后面跟着1,然后根据每个数字等于前两个数字之和规则进行。如

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …

或者

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …

挑战:编写一个函数返回斐波那契数列中的 n 元素,其中的序列是:

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …]

知道每个值都是前两个值的和,这个问题的递归解是:

function fibonacci(n) { if (n


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3