【问题标题】:Should I inline all CSS and JS for a static SPA?我应该为静态 SPA 内联所有 CSS 和 JS 吗?
【发布时间】:2014-10-21 07:38:43
【问题描述】:

我正在创建一个仅包含静态 HTML、JS 和 CSS 的单页应用程序。我需要支持 IE9+、现代桌面浏览器和 iOS 6+。

Web 是使用 grunt 构建的,我正在考虑将所有 JS 和 CSS 内联到 HTML 文件中,这样可以稍微简化处理。

由于没有服务器生成的内容,并且 .html 页面也被缓存,您是否发现在内联所有 JS 和 CSS 时有任何缺陷或缺点?据我了解,它甚至可以提高性能,因为浏览器的往返次数更少,但也许有一些很好的理由不内联那些(相当大的)文件?

你有这方面的经验吗?

[编辑] 这似乎很不清楚。我确实想手动将我正在使用的所有 JS 和 CSS 放入生成的 HTML 文件中。我有一个干净的项目结构,并考虑让 grunt 生成一个内联版本作为发布输出。我不会使用内联版本,无论是开发还是调试。我的问题只是关于技术部分:是否会对浏览器产生任何负面影响(除了缓存,整个 html 都被缓存了,我可以忍受它作为一个整体无效)?为什么作为自动构建过程的结果的内联仍然被认为是不好的做法(缓存主题除外)?

【问题讨论】:

  • 是否有多个开发人员在此应用程序上工作?如果是这样,共享一个大文件可能会产生问题。您是否觉得在编辑器中浏览一个大文件很困难?
  • @DaveB 是的,我在一个团队中工作,但这并不重要,因为它是 Grunt 构建过程的结果。我们的配置构建了两个版本,一个版本,另一个没有缩小、压缩(并且不会内联),所以这不是问题

标签: javascript html css gruntjs bundling-and-minification


【解决方案1】:

这实际上是一个非常好的问题。

我能看到的唯一主要缺点是缓存。

你不能整齐地缓存你的 CSS 或 JavaScript,而且你必须以某种方式使所有页面(包括 JS 和 CSS)上的缓存在每次更改时都失效。

我什至可以更进一步,使用 Data URIs 内联您的所有图片,原因是额外的 HTTP 请求比加载额外的约 33% 的数据更昂贵,这要归功于TCP 是如何工作的(它开始缓慢,然后以指数方式提高下载速度,直到数据包开始丢失),在最高速度下额外增加几 KB 可能比一堆新请求要好。

【讨论】:

  • 缓存整个 HTML 页面,并使用 ETag 标头检测更改。不会有太多变化(固定的发布周期和生产系统的检查窗口),最大的部分是 CSS 和 JS,但如果有任何变化,仍然需要更新
  • 那就去吧。这是一种有趣的方法,如果您在发布后进行一些基准测试,然后看看它是否真的更好,我会很感兴趣。我怀疑它会的。还要检查我的编辑是否有变化;)
  • 谢谢,我会试一试,然后发布一些基准测试结果;)
  • 小心在数据 uri 上过度使用,performance on mobile devices is terrible:“对于最近的高端智能手机,例如运行 iOS 6 或 Android 4.2 的智能手机,二进制图像实现速度大约快 6 倍。对于较旧的,较慢的硬件,二值图像物化速度快 10 倍..."
  • @steveax 好点!还没想到手机。你能把这个细节编辑成我的答案吗?
【解决方案2】:

是的。如果 CSS 资源少的话,其实是 Google 推荐的。 (注意:这只适用于 CSS)

现代浏览器在将内容绘制到屏幕之前会阻止外部 CSS。这会导致额外的网络延迟并增加将内容显示到屏幕所需的时间。为了优化渲染时间,如果外部 CSS 资源很小,您可以将它们直接插入 HTML 文档中。以这种方式内联小的 CSS 允许浏览器继续渲染页面。

https://developers.google.com/speed/docs/insights/InlineCSS

显然,您会在开发过程中将这些资源分开,并使用 gulp/grunt 等构建工具。

【讨论】:

    【解决方案3】:

    不,您不应该将 CSS 和 JavaScript 与 HTML 内联。单独的资源将被缓存。考虑关注点分离!您将如何通过 JSLint 之类的工具运行 JavaScript?当 CSS 全部内联时,您将如何验证它?

    【讨论】:

    • 在源代码和调试版本中存在关注点分离。我说的是 grunt 的发布输出('从不看自动生成的代码')
    • @DaveB 将客户视为已编译代码的代码视为已编译代码,而源代码保持良好分离和整洁。这个想法只是通过减少 HTTP 请求的数量来提高加载速度。
    • @SecondRikudo 谢谢,我明白了。当我发布我的答案时,我没有意识到这一点。对客户端调试有影响吗?
    • 我一般有两个“站点”,一个是“生产”,一个是“开发”。开发站点的所有代码都未缩小且完全成熟,您可以在其中轻松进行调试。生产站点从不调试。
    【解决方案4】:

    让你的 CSS 和 JS 分开。如果您的 HTML 有更改但 CSS 没有更改,则您要求您的用户再次下载您的所有 CSS。如果 CSS 是单独的文件,则浏览器将使用本地缓存的版本,无需额外访问服务器。

    如果您正在使用 grunt,请使用类似 grunt-filerev 的任务在缩小和连接 CSS 和 JS 文件名后为其添加哈希。

    【讨论】:

    • 如果更改间隔足够大,则影响很小。
    【解决方案5】:

    如果您在 SPA html 本身中内联 JS 和 CSS,您最终会得到不可维护的代码以及浏览器无法缓存 CSS 和 JS 文件的问题。

    如果你使用 grunt 来准备构建,你为什么不像我们在常规应用中那样创建许多小的 JS 和 CSS 文件,然后使用 grunt-contrib-concat 来连接(也许也将它们缩小)到一个文件中,并在您的 HTML 中作为参考。

    如果您需要一些示例代码,请告诉我。

    【讨论】:

    • 请看我的编辑。该应用程序不(不能)经常更新,我不会手动内联任何代码。这是一个技术问题,只是关于什么可以改善浏览器性能或用户体验。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 2015-05-14
    • 2012-05-09
    相关资源
    最近更新 更多