1

当我试图改善我拥有的画廊中缩略图的加载时间时,一切都开始了。所有图像的路径都来自 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 并在Network选项卡下按预期加载了所有 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环境下运行>.<

我以前的路由文件很生硬,false如果请求图像,js,css,字体就返回......所以,在阅读了这里的几个主题之后,我改变了它,试图包含一些缓存:

<?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';

性能要好得多,但是,直接用一个文件进行测试,第一次加载大约需要 300 毫秒,第二次大约需要 5 毫秒,第三次大约需要 300 毫秒,第四次大约需要 5 毫秒,依此类推。oO

然后我在整个应用程序中对其进行了测试,缓存问题仍然存在,尽管理论上,图像已经用 JavaScript 加载并存储在图像对象中,当它们在 JSON 中的相应偏移量通过导航访问时再次加载。

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

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

我找不到304 Header使用 PHP Internal WebServer 发送的方法,不是因为我不知道怎么做,毕竟代码是一样的,而是因为我看到的所有实现都依赖于一些$_SERVER条目,就我而言知道,是由 Apache(可能还有其他专用服务器应用程序)提供的。

此外,由于某种原因,在 Chrome Inspector 中,打开资源的Headers部分,我看不到Response HeadersCache-control下的指令,即使我确实设置了它,如您所见,到期时间约为 30 天。

除了如何解决这些问题之外,我还想了解为什么会发生这种情况。

4

0 回答 0