【问题标题】:What does Blink in-memory cache store?Blink 内存缓存存储什么?
【发布时间】:2018-10-23 13:15:20
【问题描述】:

除了浏览器缓存之外,还有其他几种浏览器缓存数据的方式。对于 Chrome,在渲染引擎 Blink 中还有另一个缓存,用于在内存中存储图像、样式、脚本和字体(可能更多)。

此缓存用于网站上的连续导航。从 Blink 缓存传递的资源在网络选项卡中标记为 (from memory cache)。从浏览器缓存提供的资源标有(from disk cache)

我现在的问题是,哪些资源存储在这个非常快的缓存中并从该缓存中交付?根据我的测试,它变化很大:

  • 它非常适合直接在 HTML 中的图像和脚本标签。
  • 它有时适用于直接在 HTML 中的样式(链接)标签。有时它不起作用(在具有相同会话的同一浏览器中)。
  • 对于以编程方式插入 HTML 的脚本标签,它几乎从不工作。但有时它会起作用。

磁盘缓存命中和内存缓存命中之间的一个巨大差异在与 Service Worker 结合使用时变得显而易见。在 Service Worker 中无法观察到由内存缓存服务的请求(因为缓存位于 Service Worker 之前)。由磁盘缓存处理的请求通过 Service Worker(因为 Browser Cache 位于 Service Worker 之后)。

为了显示解释的行为,我构建了一个包含所有资源类型的测试页面:https://dm-clone-optimized.app.baqend.com/

您可以使用顶部的链接浏览站点,并观察请求在网络选项卡和控制台中的行为方式。每个页面加载相同的资源。

经过一些导航(Chrome 70.0.3538.67),我大部分时间都会遇到这种情况:

  • HTML 是从网络获取的
  • 脚本标签scripts.jsscripts2.js 来自内存缓存
  • 图片标签logo.png也来自内存
  • 样式链接标签styles.css来自磁盘缓存 :(
  • 以编程方式添加的脚本标签scripts2.js?id=1 也来自磁盘缓存 :(

但有时,我真的很幸运,一切都从内存缓存中提供:

我很想了解 Blink 内存缓存的工作原理,以及如何调整我的网站以将其用于具有适当 cache control 标头的所有资源。

----编辑----

我最担心的是:为什么动态添加的脚本根本不缓存?这对像require.js这样的框架有明显的影响,因为它们将所有依赖项都插入为动态添加的脚本标签。

【问题讨论】:

  • 据我了解,缓存控制并没有真正提供可能影响渲染引擎实现的缓存策略的粒度级别。除非您正在寻找 Blink 如何解释 max-age 属性?作为 Web 内容开发人员,您不需要真正关心 Blink 如何管理其缓存(内存中与磁盘)。我不确定你对 Blink 文档的研究有多深,但这个演示文稿很有趣:docs.google.com/presentation/d/…
  • @user3474985 实际上,Blink 缓存似乎遵循 max-age 等缓存控制指令。至少 max-age=0 no-cache no-store 的资源似乎没有被缓存。我想知道的是为什么动态添加的脚本根本不被缓存(除了一些罕见的时刻)。 Yoav Weiss 和 Jake Archibald 似乎也认为这很奇怪,see Twitter conversation
  • 我担心这种行为的原因是它对像 require.js 这样的框架有明显的影响,因为它们将所有依赖项作为动态脚本标签插入。例如,如果 JavaScript 是商店前端的性能瓶颈,这尤其成问题。

标签: google-chrome caching rendering


【解决方案1】:

闪烁内存缓存工作

Blink 有四个内存分配器 PartitionAllocOilpantcmallocsystem allocator

因此,开发 Chrome Blink 的团队已从 Blink 中删除了 tcmallocsystem allocators

Blink (PartitionAlloc+Oilpan) 是渲染器内存的第二大消耗者,典型情况下消耗 10 - 20%,并在 Discardable、CC 和 V8 中保留了部分内存

在 Blink 中,主要的内存使用者是:

  • 大型 StringImpls(由 JavaScript 源代码使用)
  • 共享缓冲区(资源使用)
  • 向量和哈希表

建议是:“识别对 Blink 总内存有影响的缓存,并仅对它们实施purgeMemory()

  • 减小(DOM 对象)的大小不会产生影响
  • 在大多数情况下,丢弃缓存不会影响

他们正在努力摆脱“DiscardableMemory”项目,这将有助于执行诸如强制分离所有布局对象之类的事情,这反过来又会释放布局树保留的内存。

【讨论】:

    【解决方案2】:

    我相信这是 chrome 优化的结果,它们让你觉得它很冗长。

    文件总是进入磁盘缓存。而且它们也会进入内存,很快就会被刷新。

    Chrome 足够聪明,可以在磁盘上查找之前询问正在运行的进程是否还在内存中加载了它们的副本。 该步骤的命中率很高,因为这些图像/js 正在积极地用于某些事情。

    您将无法控制 chrome 如何管理它们的 TTL/内存容量可用于保持 blob 热。 Chrome 开发团队在基于实际硬件容量和系统负载的动态调优方面做了很多工作。

    附:如果您要求将您的应用程序保存在内存中。你失败了 Sun/Adobe 的邪恶方式:让他们的应用程序 DLL 在内存中变热(通过托盘图标/服务)并减慢其他人的速度。

    附言如果是最终用户可能想要使用的应用程序,请使用 electron 并按照 Whatsapp/Slack/etc 构建一个始终运行的应用程序。

    【讨论】:

    • 嘿@DennisC 感谢您的回答。为了消除误解,我的问题不是关于 Blink 如何驱逐条目来管理其内存,而是为什么动态添加的脚本根本不被缓存(除了一些罕见的情况)。这对像 require.js 这样的框架有显着影响,因为它们将所有依赖项都插入为动态脚本标签。
    猜你喜欢
    • 1970-01-01
    • 2017-07-15
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多