I'm using Cherrypy 3.6.0 framework. I have problem with long time loading pages (serving static files takes a lot of time) when I open page in more than one browser. In that case, for example, bootstrap.min.css file which has 120kB can load 5-10 seconds. What is worse, static files are never cached, so every time page is loaded static files are again loaded and again it takes multiple seconds before page will load. When server respond 304 Not modified it also takes the same amount of time before client side receive this answer (there is no difference in response time no matter if static file is loaded or server respond 304). My serving static files configuration:

cherrypy.tree.mount(None, '/static', config={
    '/': {
        'tools.staticdir.on': True,
        'tools.staticdir.dir': static_dir,
        'tools.sessions.on': False,
        'tools.caching.on': True,
        'tools.caching.force' : True,
        'tools.caching.delay' : 0,
        'tools.expires.on' : True,
        'tools.expires.secs' : 60*24*365
        }
    }
)

I can't understand how it is possible that fetching 120kB file can take so much time... Maybe someone can give me advise where can I look for reason of this problem?

EDIT:

Headers:

Remote Address:192.168.100.100:80
Request URL:http://192.168.100.100/static/css/bootstrap.min.css
Request Method:GET
Status Code:304 Not Modified
Request Headersview source
Accept:text/css,*/*;q=0.1
Accept-Encoding:gzip, deflate, sdch
Accept-Language:pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie:session_id=.......................................
Host:192.168.100.100
If-Modified-Since:Mon, 22 Dec 2014 12:30:51 GMT
Referer:http://192.168.100.100/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Response Headersview source
Date:Fri, 14 Jan 2000 23:51:25 GMT
Server:CherryPy/3.6.0
Vary:Accept-Encoding

In timining overlap I have:

Stalled: 9.619ms
Request sent: 0.171ms
Waiting (TTFB): 5.02s
Content download: 1.000ms 

I checked what is TTFB and this is the duration from the virtual user making an HTTP request to the first byte of the page being received by the browser. So something is wrong with server responsiveness...

EDIT2:

I have created minimal app which only loads static files and problem still occurs. This is app code:

server:

import cherrypy

def start():

    import app

    app.application()

    cherrypy.config.update({'server.socket_host': '0.0.0.0', 'server.socket_port': 9061 })

    engine = cherrypy.engine

    engine.autoreload.unsubscribe()

    try:

        engine.start()

    except:

        sys.exit(1)

    else:

        engine.block()


if __name__ == '__main__':    

    start()

app:

import cherrypy

from jinja2 import Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader('/tmp/cherry/'))


static_dir = '/media/vbox_shared/new_web/app/static'

class Test(object):

    @cherrypy.expose

    def index(self):

        template = env.get_template('test.html')

        return template.render()


def application():

    cherrypy.tree.mount(Test(), '/', config = {})

    cherrypy.tree.mount(None, '/static', config={

        '/': {

            'tools.staticdir.on': True,

            'tools.staticdir.dir': static_dir
        }

    })

html:

<html>

<head>

    <meta http-equiv="X-UA-Compatible" content="IE=9"/>

    <link rel="stylesheet" href="/static/css/style.min.css"/>

    <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css"/>

    <link rel="stylesheet" type="text/css" href="/static/css/chosen.min.css"/>

    <link rel="stylesheet" type="text/css" href="/static/css/jquery.jgrowl.min.css"/>

    <link rel="stylesheet" href="/static/css/m-buttons.min.css"/>

    <title>Streams</title>

    <title>test</title>

</head>

<body>

<h1>test</h1>

 <script src="/static/js/jquery-1.11.1.min.js"></script>

    <script src="/static/js/jstree.min.js"></script>

    <script src="/static/js/functions.js"></script>

    <script src="/static/js/stream.js"></script>

    <script src="/static/js/chosen.jquery.min.js"></script>

    <script src="/static/js/chosen.proto.min.js"></script>

    <script src="/static/js/jquery.jgrowl.min.js"></script>

    <script src="/static/js/bootstrap.min.js"></script>

</body>

</html>

links to screenshots:

http://i58.tinypic.com/21m8ar5.png http://i60.tinypic.com/euh6p0.png

EDIT3:

I have reduced my app to:

import cherrypy
class HelloWorld(object):
    def index(self):
        return """
            <html>
            <head>
                <link rel="stylesheet" href="/static/css/style.min.css"/>
                <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css"/>
                <link rel="stylesheet" type="text/css" href="/static/css/chosen.min.css"/>
                <link rel="stylesheet" type="text/css" href="/static/css/jquery.jgrowl.min.css"/>
                <link rel="stylesheet" href="/static/css/m-buttons.min.css"/>
                <title>Streams</title>
                <title>test</title>
            </head>
            <body>
            <h1>test</h1>
                <script src="/static/js/jquery-1.11.1.min.js"></script>
                <script src="/static/js/jstree.min.js"></script>
                <script src="/static/js/chosen.jquery.min.js"></script>
                <script src="/static/js/chosen.proto.min.js"></script>
                <script src="/static/js/jquery.jgrowl.min.js"></script>
                <script src="/static/js/bootstrap.min.js"></script>
            </body>
            </html>"""

    index.exposed = True

conf = {
        '/static':
        {
         'tools.staticdir.on': True,
         'tools.staticdir.dir':'/media/vbox_shared/new_web/app/static'} 

        }

cherrypy.config.update({'server.socket_host': '0.0.0.0', 'server.socket_port': 9066 })
cherrypy.quickstart(HelloWorld(), config=conf)

And problem still occurs. When I open main page in IE, FF, Safari and Chrome - some static files are loading more than 10 seconds ...

1

There are 1 best solutions below

0
On

You must have omitted some headers and some configuration. CherryPy sends Vary: Accept-Encoding only for gzipped responses. Normally it sends Last-Modified, Content-Type, Content-Length and some others. Also note that Cache-Control: max-age=0 means you do a refresh request asking server to validate the resource.

In the answer I linked in the comment I showed that normally 304 Not Modified only costs CherryPy a os.stat call which is instant, unless your disk is broken.

What I suggest you to do is to run a separate CherryPy app on the same static directory with only tools.staticdir on, to avoid possible misconfiguration, session lock issues etc. Then gradually append configuration and measure the response time e.g. with Apache's ab -c 10 -n 1000 http://192.168.100.100/static/css/bootstrap.min.css.