网络服务器缓存问题

时间:2017-02-09 13:23:04

标签: php caching php-builtin-server

当我试图改善缩略图的加载时间时,一切都开始了。所有图像的路径都来自JSON文件/字符串/响应以及有关它们的若干细节,以便构建UI。

我的第一个想法是用JavaScript本身缓存它们:

for( let i = 0; i < data.length; i++ ) {

    let thumbnail = new Image();
    thumbnail.src = data[ i ].thumbnail;
}
  

使用BabelJS的ES2015

我知道这不是最好的方法,因为我应该按需加载它们(即在JSON中访问它们的偏移量时)或甚至与AJAX异步加载它们。实际上我也尝试了两种方式,但是在填充UI之前,我没有设法让其他数据等待图像完全加载。

但这是后来的问题^ _ ^

因此,我检查了Chrome Inspector,在网络标签下,所有JPG都按预期加载,但在实际使用图片时,修改为预览设计的容器的src属性(见下文),每张图片都被重新加载。

$( 'figure img' ).attr( 'src', data[ current ].thumbnail );
  

这只是一个片段。 'current'是浏览JSON

的图库计数器

在耗尽我的测试技能后,我最终认为问题是我的服务器。

我目前正在使用PHP Internal Webserver进行开发,因为至少到现在为止,我并不需要完整的服务器解决方案。打开几个命令行窗口是不好的,但无论如何......

为了记录,网络服务器就像这样启动:

php.exe -c "path\to\php.ini" -S "0.0.0.0:8080" -t "." "routing.php"
  

在Windows环境下运行&gt;。&lt;

我以前的路由文件非常生硬,如果请求图片,js,css,font就返回false ...所以,在阅读了几个主题之后,我改变了它,尝试包含一些缓存:< / p>

<?php

if( preg_match( '/\.(js|ico|gif|jpg|png|css|eot|svg|ttf|woff|php)$/', $_SERVER["REQUEST_URI"] ) ) {

    date_default_timezone_set( 'America/Sao_Paulo' );

    $file = sprintf( '.%s', $_SERVER['REQUEST_URI'] );

    if( ! file_exists( $file ) ) {
        header( 'HTTP/1.1 404 Not Found' );
    }

    $eTag = md5_file( $file );

    if( $eTag !== FALSE ) {
        header( 'Etag: ' . $eTag );
    }

    header( 'Cache-Control: public, max-age=2592000' );

    $mTime = filemtime( $file );

    if( $mTime !== FALSE ) {

        $GMD = gmdate('D, d M Y H:i:s', $mTime );

        header( sprintf( 'Last-Modified: %s GMT', $GMD ) );

        if( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {

            $mSince = strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );

            if( $mSince !== FALSE && $mSince == $GMD ) {

                header( 'HTTP/1.1 304 Not Modified' ); return false;
            }
        }

        if( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ) {

            $noneMatch = str_replace( '"', '', stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) );

            if( $noneMatch == md5( $file . $mTime ) ) {
                header( 'HTTP/1.1 304 Not Modified' ); return false;
            }

            if( $noneMatch == $eTag ) {
                header( 'HTTP/1.1 304 Not Modified' ); return false;
            }
        }
    }

    // Resource not cached yet

    header( 'Content-Type: '   . mime_content_type( $file ) );
    header( 'Content-Length: ' . filesize( $file ) );

    return false;
}

include __DIR__ . '/index.php';

性能相当好,但是,直接测试单个文件,第一次加载需要〜300ms,第二次加载需要5ms,第三次加载需要300ms,第四次加载需要大约5ms,依此类推。 o.O

然后我在整个Application中测试了它并且缓存问题仍然存在,尽管理论上,图像已经加载了JavaScript并存储在Image Object中,当它们通过JSON访问它们各自的偏移量时它们再次加载导航。

此外,当多次刷新页面时,我没有与直接访问相同的“跳跃”响应时间。所有不是来自CDN(jQuery,Bootstrap ......)的东西都被一次又一次地加载。 &GT;:(

经过更多研究,我发现的两个罪魁祸首是Cache-control未设置和整体状态代码。

我找不到使用PHP Internal WebServer发送304 Header的方法,不是因为我不知道如何,事后代码是相同的,但因为我看到的所有实现都依赖于据我所知,一些$_SERVER条目由Apache(以及其他专用服务器应用程序)提供。

此外,出于某种原因,在Chrome Inspector中,打开资源的标题部分,我在那里看不到响应标题下的Cache-control指令即使我确实设置了它,如你所见,约30天到期。

我怎么能解决这些问题,我想了解为什么会这样。

0 个答案:

没有答案