9

我的主要目标是尽可能快地加载多个页面。为此,我想同时利用缓存和一种“特殊技术”,作为后备,它依赖于标准缓存。

结构

在后端,我有以下结构。public_html 中有一个主页面和几个子页面,每个子页面都有各自不同的特定 css 规则。所有最小化文件的创建都是由脚本完成的,因此没有额外的复杂性。为简单起见,我们假设这是结构,尽管它更复杂:

/public_html
  /index.php
  /style.css    ~50kb
  /min.css      ~100kb
  /subjects
    /index.php
    /style.css      ~20kb
    /min.css        ~10kb
  /books
    /index.php  
    /style.css      ~20kb
    /min.css        ~10kb
  ...

第一个请求

所以当用户第一次进入子页面时,他们会收到这个 html 代码:

<!DOCTYPE html>
<html>
  <head>
    <link href="/subjects/min.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    All the body here
    <link href="/min.css" rel="stylesheet" type="text/css">
  </body>

如您所见,用户在一个小文件中的页眉中加载了该页面所需的所有 css 代码。请注意,这比使第一个请求加载更快的要/subjects/min.css小得多。/min.css然后,在正确加载完整的 html 和 css 后,/min.css将开始加载。该文件包含所有子页面样式。

请注意,将放在tag中是合适的<link><body>,即使它不起作用,也没有问题,因为已经加载了特定于页面的样式。为什么我在这里加载这个?继续阅读:

以下请求

对于该会话的第二个和后续请求,用户将收到以下 html 代码:

<!DOCTYPE html>
<html>
  <head>
    <link href="/min.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    All the body here
  </body>

/min.css应该已经从第一个请求缓存。但是,如果由于某种原因它不是,它现在将加载完整的最小化样式,就像在任何普通网站中一样。这将是后备情况。

这是一个有效的方案吗?为什么我以前没有见过这样的事情?它是否包含任何逻辑错误?

这些是我可以看到的主要问题,与好处相比还不够强大:

  • 它给代码增加了一些额外的复杂性。
  • 在一切都已经加载之后,需要提出一个额外的请求。这会在服务器上增加一点开销,但它是一个静态文件。

关于评论的注释:

  1. 浏览器会发出更少的请求。确实如此,这样浏览器会执行一个额外的请求。但是,它是在加载 html 和 css 之后,所以这不会对 html 产生很大影响。

  2. 缓存。是的,我正在尽我所能去抓文件。<link>但是,如果它在内部,可以针对缓存提出一点<body>,因为我不知道缓存的行为是否不同,我只在问题中假设是。

4

4 回答 4

6

更新:

请注意,不能推荐提问者标记为已接受的答案 -
永远不要这样做!

任何类型的 CSS 文件“预加载”都没有任何意义,因为您永远不应该将 CSS 拆分为多个文件!

我原来的答案:

那么你真正的问题到底是什么?

在我看来,你做错了 - 对不起!

通常作者打算

  • 为网站提供一致的外观/外观
  • 保持可维护性尽可能简单
  • 避免FOUC(无样式内容的闪现)
  • 最小化 (HTTP) 请求的数量
  • 支持缓存机制以减少带宽/数据量

仅提及一些最重要的方面。

所有这些都被您的方法所忽视。

当您在元素中使用link元素body时,我假设您使用的是 HTML5。因为在其他 HTML 版本中这是无效的。

但在 HTML5 中我也不会依赖这个。看看2个版本:

  1. http://www.w3.org/html/wg/drafts/html/master/document-metadata.html#the-link-element
  2. http://www.w3.org/html/wg/drafts/html/CR/document-metadata.html#the-link-element

比较部分(顶部)“可以使用此元素的上下文:”。

由于浏览器最需要来自 CSS 的信息来呈现页面,因此它应该是最先加载的内容之一。

查看文章:“浏览器的工作原理:现代 Web 浏览器的幕后”,尤其是“渲染引擎”部分。

因此加载另一个样式表将迫使浏览器重做所有工作,除了额外的 HTTP 请求,特别是在 GSM 连接上,由于更大的延迟可能会导致“麻烦”。

如果你网站的每个页面真的有这么多的个人风格规则,那么我会说这是一个“设计缺陷”。

“设计原则”之一是:尽可能多 - 尽可能少!

仅使用一个样式表的另一个(大)优点是它在第一次加载后被浏览器缓存。而且由于网站的 CSS 通常不会经常更改,这是一个很大的优势,远远超过了在第一页访问时加载更多 KB 的劣势(顺便说一句,独立于入口/登陆页面)!

结论
我真的不推荐使用你的方法!

将所有样式(规范化、基本、媒体查询、打印)放在一个文件中,您可以通过<link>该文件加载到<head>文档中。

这是你能做的最好的。

于 2014-02-15T15:44:57.667 回答
5

是的,你正在做的事情是完全有效和普遍的

CSS 可能是一个不好的例子,但原理相同(通过 ajax btw 加载最后一个)

比如说,图像。

我们在网站的第 1 页,我们知道 99.999% 的访问者会点击第 2 页,并且我们知道在第 2 页上我们有一些大图像要提供,是的,然后我们可以在之后静默加载它们第 1 页已加载 - 准备就绪,然后网站在导航时“感觉”很快。移动 Web 应用程序/网站中的一个常见技巧/

所以是的:

对于您可能希望为后续请求“预缓存”的任何类型的文件,这都是相同的原则。

  • 加载页面
  • 当访问者“阅读”加载的页面时,预取您希望他们接下来可能请求的文件/数据。(图像、结果数据的第 2 页、javascript 和 css)。这些是通过 ajax 加载的,以不阻止页面“onload”事件触发 - 与您的示例的关键区别

但是,为了回答您的目标 - 尽可能快地加载页面

如果我们不是从静态服务器、无 cookie 域以及最终的内容交付网络提供静态文件,那么这样做或任何类型的“抢先加载”技术对“交付速度”的影响最小。


实现尽可能快地加载页面的目标是静态文件的服务与您的动态内容不同(php 渲染等) 。

1)为这些资源(css、js、images/media)创建一个子域 - static.yourdomain.com

2)关闭 cookie、标头并专门为此子域调整缓存标头。

3)考虑使用http://cdnify.com/或 www.akamai.com 之类的服务。

这些是提供静态内容的性能和速度步骤。(希望不要吸鸡蛋,只是直接相关的问题,如果有人不熟悉这个)

抢先加载”技术仍然很棒,但它们现在更多地与预加载数据的可用性相关,而不是速度。


编辑/更新:

澄清“速度”和“可用性速度”。

  • 速度通常由软件在页面“onload”事件触发时进行判断(这就是为什么通过 ajax 加载这些“抢先资源”很重要的原因。

  • 感知速度(可用性)是用户可以看到内容并与内容交互的速度(即使页面加载事件可能尚未触发)。


编辑/更新

在帖子的一些区域和评论中提到了通过 javascript/ajax 加载这些额外的“抢先式”资源。

原因是不要延迟页面“onload”事件的触发。

许多网站测试速度工具(yslow、google ..)使用这个'onload'事件来判断页面速度。

这里我们延迟页面的“onload”事件。

<body>

... page content 

<link rel="stylesheet" href="/nextpage.css"  />
</body>

在这里,我们通过 javascript / some case Ajax 加载(页面数据)并且不阻止页面加载事件

<body>
.. page content

  <script>

    window.onload = function () {

       var style   = document.createElement( 'link' );
       style.rel   = 'stylesheet';
       style.type  = 'text/css';
       style.href  = '/nextpage.css';
       document.getElementsByTagName( 'head' )[0].appendChild( style );

   };

   </script>

(作为奖励,这也解决了在您的其他线程中讨论的带有<link>标签的兼容性问题)<body>

于 2014-02-16T10:48:30.790 回答
3

由于min.css包含正确最小化的所有样式,只需使用它


为什么 ?

1.浏览器会发出更少的请求

2.文件被浏览器抓取2到3次后会被缓存。页面加载时间大幅减少!

3.浏览器不必遍历特定页面的css,从而减少了页面渲染所需的时间

4.代码的易维护性。如果要更新 css,只需为一些查询变量添加前缀,以便浏览器获取更新后的 css


我认为,以上理由足以让你使用min.css

另外,如果您愿意按照我的建议进行操作,请不要忘记设置一个非常长的缓存到期日期

编辑:由于 OP 不理解第 2 点,我要让自己和重点清楚。

浏览器不会在第一次遇到 css 文件时缓存它,因为它认为:'嘿,我们不要立即缓存它。万一变了怎么办?我会看到,相同的 css 至少被重新加载 2 次,以便获得缓存的好处'

首次加载时缓存 css 是没有意义的。因为如果浏览器这样做,那么用户系统上就会有大量的cahce。所以浏览器足够聪明,可以缓存频繁加载且未更改的文件。

于 2014-02-15T16:07:12.340 回答
2

您所描述的是一种预取/延迟加载模式,其中加载的资源预计将来会变得相关 - 例如,具有最小样式的基本登录页面开始在后台加载站点 css。

除其他外,这在PageSpeed模块中已经完成。事实上,它更具侵略性,但需要更少的开发工作!仅使用一小部分样式的普通登录页面(如登录屏幕)可以利用将prioritize_critical_css相关规则内联到 html 并在页面底部加载 css 的优势!与必须执行两个连续请求的原始场景不同,头部中没有样式表的渲染阻塞效果正在被抵消。首次使用移动设备的访问者对这种改进有很好的看法,他们会受到更高的网络延迟和更少的同时 http 请求数量的限制。

一个自然的进展是延迟加载精灵、网络字体和其他静态可缓存内容。但是,我倾向于推测拥有结构良好的单独 css 的好处可能是肤浅的,通常将样式缩小到一个文件中会做得很好。5 KB 和 50 KB 文件之间的加载时间差异不是十倍,可以忽略不计,因为网站性能不再取决于带宽。附带说明一下,您永远不必担心依赖管理(即记住在页面上包含与特定元素相关的规则),这对于 html+css 来说不容易自动化,并且对于大型项目来说会变得相当麻烦。

如果您专注于静态资源的基本规则 -积极缓存- 并记住对您的资产进行指纹识别,以便部署不会变得混乱,那么您做得很好!如果你在这里和那里用一个位置优越的悸动者来解决感知的表现......

于 2014-02-19T00:33:39.867 回答