在同一页面中组合特定页面样式和全局样式时的性能

Fra*_*cia 9 html css php performance load-time

我的主要目标是允许尽可能快地加载几个页面.为此,我想利用缓存和一种"特殊技术",作为后备,依赖于标准缓存.

结构体

在后端我有以下结构.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
  ...
Run Code Online (Sandbox Code Playgroud)

第一个请求

因此,当用户第一次在子页面上输入时,他们将收到此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>
Run Code Online (Sandbox Code Playgroud)

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

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

以下要求

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

<!DOCTYPE html>
<html>
  <head>
    <link href="/min.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    All the body here
  </body>
Run Code Online (Sandbox Code Playgroud)

/min.css应该从第一请求已经被缓存.但是,如果由于任何原因不是,它将立即加载完全最小化的样式,就像在任何普通网站中一样.这将是后备案件.

这是一个有效的计划吗?为什么我以前没见过这样的东西?它是否包含任何逻辑错误?

这些是我能看到的主要问题,与收益相比还不够强大:

  • 它为代码增加了一些额外的复杂性.
  • 在已经加载所有内容之后,需要进行额外请求.这会在服务器上增加一些开销,但它是一个静态文件.

关于评论的说明:

  1. 浏览器将减少请求.这是事实,通过这种方式,浏览器会执行一个额外的请求.但是,它是在加载html和css之后,所以这不会对html产生很大的影响.

  2. 缓存.是的,我正在尽力抓住文件.但是,<link>如果它在内部的缓存中可以有一个点<body>,因为我不知道它对缓存的行为是否不同,我在问题中只假设是.

Net*_*fer 6

更新:

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

任何类型的"预加载"CSS文件都没有任何意义,因为你永远不应该将你的CSS分成几个文件!

我的原始答案:

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

以我的拙见,你做错了 - 抱歉!

通常作者打算

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

仅举几个最重要的方面.

所有这些都被你的方法所忽视.

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

但是在HTML5中我也不会依赖于此.看看这两个版本:

  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>你的文档.

这是你能做的最好的事情.


Rob*_*ick 5

是的,你所做的是完全有效和普遍的

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

比如说,图像.

我们在我们网站的第1页上,我们知道访问者将有99.999%的时间点击到第2页,我们知道在第2页我们有一些大图像可供服务,是的,然后我们可以默默地加载它们第1页已经加载 - 准备就绪,然后网站在导航时"感觉"很快.移动Web应用程序/站点中的常见技巧/

是的:是的

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

  • 加载页面
  • 当访问者"读取"加载的页面时,预先获取您希望接下来可能请求的文件/数据.(图像,结果数据,javascript和css的第2页).这些是通过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>
Run Code Online (Sandbox Code Playgroud)

这里我们通过javascript /某些情况加载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>
Run Code Online (Sandbox Code Playgroud)

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