【问题标题】:Using a PHP script to minify javascript causes slow server response使用 PHP 脚本缩小 javascript 会导致服务器响应缓慢
【发布时间】:2013-07-22 16:21:26
【问题描述】:

我正在使用 PHP 脚本来最小化 javascript。问题是脚本在服务器响应之前经常需要一秒钟左右的时间,这几乎完全违背了目的。即使只是发送一个 304,它仍然有时需要一秒钟左右的时间来发送响应,在此期间浏览器处于挂起状态。

加载时,脚本功能如下:

  1. 根据查询字符串 var 确定要加载的文件(或者如果查询字符串 var 为 null,则使用默认值)
  2. 检查文件的缓存副本是否可用并且是最新的(这是存储在服务器上的 .txt 文件)
  3. 如果是这样,什么也不做。如果没有,则创建或重新创建缓存文件(我使用 JShrink 0.5.1 进行缩小)
  4. 最后,检查缓存文件的 etags 和 last-modified 是否与用户的匹配
  5. --如果是这样,只需发送 304
  6. --如果没有,对缓存文件做一个readfile

它不会始终如一地这样做 - 一次刷新可能需要一秒钟,下一次大约需要 100 毫秒,两者都返回 304。由于不一致,我最好的猜测是延迟是在访问在硬盘驱动器上缓存文件(即使发送 304 它仍然需要对缓存文件和 $fileList 中的任何文件执行 filemtime(),然后对缓存文件执行 md5_file() 以生成当前 etag) .

关于如何解决这个问题的任何想法?以下是一些相关的代码块:

<script type="text/javascript" src="/loadJS.php"></script>
// steps 2 and 3 (check cache, update if necessary, fileList is an array of paths to .js files):

if ( file_exists( $cacheFile ) ) {
    $cacheLastModified = filemtime( $cacheFile );
    for( $i = 0; $i < sizeof( $fileList ); $i++ ) {
        /* check if any files in the list are newer than the cache's last modification date
        * if so, cache must be updated
        */
        if ( $cacheLastModified < filemtime( $fileList[$i] ) ) {
            $outdated = true;
        }
    }
}

if ( isset( $outdated ) || !file_exists($cacheFile) ) {
    // update the cache file now
    ob_start();
    foreach( $fileList as $file ) {
        readfile( $file );
    }
    $output = ob_get_clean();
    include( "includes/JShrink-0.5.1.class.php" );
    $output = Minifier::minify($output, array('flaggedComments' => false));

    if ( $cacheFileFP = fopen( $cacheFile, "w" ) ) {
        if ( fwrite( $cacheFileFP, $output ) ) {
            fclose( $cacheFileFP );
        } else {
            // handle fwrite errors
        }
    } else {
        // handle fopen errors
    }
}



// step 4 (function checks etags and modification date):

function fileNotModified ( $file ) {
    /* returns false if file NOT modified
    * -- or an array of headers if file has been modified
    * use two criteria to determine if file has been modified
    * a) if-modified-since header vs the file's last-modified time
    * b) etag match
    * if if-modified-since is the same as file mod time, or etags match
    * --- return array of headers to send
    * else return false
    *
    * see http://stackoverflow.com/questions/2000715/answering-http-if-modified-since-and-http-if-none-match-in-php/2015665#2015665
    */

    $gmtModifiedTime = gmdate('r', filemtime($file) );
    $eTag = md5_file( $file );
    $result = false;

    if( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) || isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ) {        
        if ( $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmtModifiedTime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == $eTag ) {
            $result["ETag"] = $eTag;
            $result["Last-Modified"] = $gmtModifiedTime;
        }
    }

    return $result;
}

// steps 5 and 6 (304 header or send readfile output):

if ( $headers = fileNotModified( $cacheFile ) ) {
    // send the headers and 304 not modified
    foreach( $headers as $name=>$value ) {
        header( $name . ": " . $value );
    }
    header('HTTP/1.1 304 Not Modified');
    /*exit();*/
} else {
    // read and output the cache
    header("Last-Modified: " . gmdate("r", filemtime( $cacheFile )) );
    header("Etag: " . md5_file( $cacheFile ) );
    readfile( $cacheFile );
}

【问题讨论】:

  • 你不需要在每次页面加载时都缩小你应该只缩小一次 js 源文件然后将缩小的脚本上传到你的网络服务器。
  • 我也可以反映@Dave 所说的,这不是PHP 的工作。让您的网络服务器处理它。
  • @Dave 这种情况:if ( isset( $outdated ) || !file_exists($cacheFile) ) 表示它没有在“每次页面加载时”被缩小。
  • @brewal 很明显,这就是为什么有时需要 1 秒 + 才能加载,而有时需要 ms,代码中存在逻辑错误,但总体而言,主要逻辑错误是 WTF 你是在做这样的缓存还是缩小它完全违背了整个观点。
  • 你的if ( $cacheFileFP = fopen( $cacheFile, "w" ) )应该在if ( isset( $outdated ) || !file_exists($cacheFile) )里面

标签: php


【解决方案1】:

我没有测试下面的代码,但这是你应该做的:

if(!file_exists($js_path_cache) || filemtime($js_path_cache) < filemtime($js_path) {
  // MINIFY YOUR JS HERE
}

【讨论】:

    猜你喜欢
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    相关资源
    最近更新 更多