iPhone Web 应用程序中的缓存控制 - ajax 加载的页面
我正在寻找缓存和 ajax 加载页面方面的专家:-)
我已经阅读了很多有关该主题的内容,但仍然不确定缓存 ajax 页面的最佳方法是什么。我想确保我正在尽我所能让我的 iPhone Web 应用程序尽可能快地加载和导航。
这就是我所做的和拥有的: 我正在使用 jqtouch 和 PhoneGap 开发 iPhone Web 应用程序。 当从 App Store 下载应用程序时,我包括应用程序中的所有 js 文件、css 文件、索引页、菜单图标。 js 和 css 文件被缩小。
我的所有子页面都从我的专用服务器加载了 ajax。 所有子页面都是 .asp 页面,每次加载页面时都会从 mysql 数据库获取其内容。
由于 iPhone 缓存页面,当我访问它们时,我必须删除所有 ajax 页面,否则更新将不可见。这不是最好的做事方式。
相反,我不想删除 ajax 页面并使用缓存控制。
我认为它应该是这样工作的: 在服务器上打开缓存控制(这是如何完成的?) 在应用程序中,检查上次修改日期,如果没有更改 - 从缓存中读取。 如果它发生了变化 - 从服务器获取文件。
这是最好的做事方式吗?电子标签代替?
我想知道如何使用正确的缓存控制设置带有 IIS 7 的 Windows 2008 服务器。如何在索引文件中写入正确的标头,以及是否需要在我的 asp ajax 页面中写入一些 asp 读取标头?
我希望有人现在该怎么做? 任何意见,谢谢!
Im looking for a guru on caching and ajax loaded pages :-)
I have read a lot of input about the subject but are still unsure what the best way is to cache ajax pages. I would like to be sure that Im doing all I can to make my iPhone web app as fast as possible to load and navigate on.
This is what I do and have:
Im developing a iPhone web app with jqtouch and phonegap.
Im including all js files,css files, index page, menu icons in the app when it is downloaded from the App Store. The js and css files are minified.
All my subpages is loaded with ajax from my dedicated server.
All subpages are .asp pages that gets its content from a mysql database every time a page is loaded.
Since the iPhone cache pages I have to delete all ajax pages when I have visited them, otherwise an update wouldnt be visible. This is not the best way of doing things.
Instead i would like to not delete the ajax pages and use the cache-controll.
This is how I think it should work:
Turn on cache-controll on the server(how is this done?)
In the app, check the Last-Modified date and if it is not changes - read from the cache.
If its changed - get the files from the server.
Is this the best way of doing things? E-tag instead?
I would like to know, how to set the windows 2008 server with IIS 7 with the right cache controll. How to write the correct header in the index files, and if I need to write som asp-read headers in my asp ajax pages?
I hope somebody now how to do this?
Any input appriciated, thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
iPhone 在本地缓存页面,并且您必须清理缓存才能获取新内容,这对我来说听起来很奇怪。
事实上,必须有一些 HTTP 缓存标头告诉 iPhone 浏览器执行此操作。
无论浏览器是 iOS 上的 Safari、Android 上的 Opera 还是 Windows 上的 Firefox,都没有关系,因为所有现代浏览器“应该”符合 HTTP 1.1 RFC,甚至是移动 RFC。
当然,它们可能在节省带宽、手机电池和手机 CPU 周期方面存在一些差异,但它们绝对应该允许用户从网站获取新鲜内容。所以我同意你的观点,清理访问过的页面并不是正确的做法。
我绝对认为某个地方有问题。尝试通过计算机浏览器调用API,并通过firebug或chrome的本机调试工具检查请求,检查服务器响应标头,看看行为是否相同。
通常我混合使用 max-age 和 if-modified-since 缓存验证器。
我将一些图像的 max-age 设置为较高的值(在我的例子中为 365 天,很可能不适合您),将其他一些图像的 max-age 设置为一周,以及一天的 css 和 javascript。
此外,我使用 if-modified-since,因此我在内容的新鲜度、服务器负载和带宽使用之间取得了良好的平衡。 ETAG 基本上与 if-modified-since 相同,不同之处在于您可以将其设置为弱缓存验证器,如果服务器的时钟不可靠,它确实很有用。 (有关更多信息和文档参考,请参阅下面的扩展答案)
要启用缓存,IIS7 使用输出缓存 IIS 模块使您变得非常容易。 这里有一个关于它的好文档,关于如何启用它,以及内核和用户模式缓存之间的区别。
除非您需要做非常特殊的事情,否则我认为您不需要为其创建代码,IIS 会处理所有事情。如果情况并非如此,那么这里是另一个很好的指南 这会对你有所帮助。
如果您确实想要一个快速的网站,那么我建议您启用压缩,并在应用程序和数据库之间添加缓存层。因此,您不会对每个请求都执行对数据库的查询。
以下是针对任何 Web 开发人员的一些更好的性能指南。
扩展答案(甚至可能太扩展了:) )
通过 HTTP 1.1 在客户端缓存内容有不同的方法。
最常见的,或者至少是我最常用的有:
1) max-age 标头是从服务器发送到 HTTP 响应标头的,基本上告诉客户端的浏览器存储其缓存上的内容,持续以秒为单位的指定时间段。
例如,假设服务器返回 max-age=60 以响应 logo.jpg 的 GET 客户端 http 请求。然后,客户端的浏览器存储 logo.jpg,并在接下来的 60 秒内从自己的缓存中提供该图像。
换句话说,在接下来的 60 秒内不会有对此特定图像的 HTTP 请求。
因此,使用最大期限,内容将缓存在客户端,并且在 max-age 标头中指定的秒数内不会向服务器请求或重新验证。
然而,通常可以通过在 Windows 浏览器上按 CTRL-F5 和在 Mac 浏览器上按 CMD-R 来强制重新验证/刷新。在移动设备上,该功能通常位于浏览器菜单上,称为刷新。这是 RFC 的相应部分。
优点
缺点
2) 最后修改的服务器端 http 响应标头与客户端 http 请求标头 if-modified-since 一起,是另一个加快网站速度并节省资金的好机制。它基本上是这样工作的。
浏览器首次通过 GET 请求向服务器请求内容。
服务器以 200 响应并返回内容以及最后修改的标头。
Last-Modified header 的值就是上次修改内容时的实际日期和时间。 (由于时区的原因,日期时间必须采用 UTC)
此时,来自客户端的对相同内容的所有以下 HTTP 请求都将具有一个名为:if-modified-since 的附加标头,其中包含从服务器接收到的日期和时间作为值。
服务器在收到以下请求时将检查 if-modified-since 标头值,并将其与内容的最后修改日期进行比较。
如果数据相同,因此内容没有改变,服务器将响应 304,并且基本上没有内容。 (最重要的部分!)
然后浏览器知道它必须将内容保留在缓存中并从中加载它,因为它在服务器端没有改变。
该过程将继续,直到服务器上的内容发生更改,因此服务器将提供新的上次修改日期和新内容。
正如您所看到的,这可以节省大量带宽,尤其是在图像、JS 或 css 的情况下,而又不会放弃内容的新鲜度。 规范第 14.25 节 比我解释得更好做过。 :)
优点
缺点
3)ETAG是一个类似于if-modified-since的过程,不同之处在于标头的值通常是服务器端内容的散列,并且http请求上的客户端发送一个名为:if-none的标头-匹配。
优点和缺点与第 2 点相同。
您现在可能想知道第 2 点和第 3 点之间的主要区别是什么。
第2点的问题实际上是服务器时钟。事实上,如果服务器有时钟问题,那么从服务器返回上次修改日期可能会出现问题。
这个主题相当深入,因为最佳实践是发送弱验证器和强验证器。有关详细信息,请参阅第 13.3.4 节。
It sounds strange to me that iPhone caches the pages locally and that you have to clean up the cache to get fresh content.
In fact there must be some HTTP cache headers which tell iPhone browser to do that.
It should not matter if the browser is Safari on iOS, or opera on Android, or Firefox on a windows, because all modern browser "should" conform to the HTTP 1.1 RFC, even the mobile ones.
Surely they might have some differences to save bandwidth, phone battery and phone cpu cycles, but definitely they should allow users to get fresh content from a website. So I agree with you, cleaning the visited pages is not the right way of doing things.
I definitely think that there is a problem somewhere. Try to call the API via a computer browser and inspect the requests via firebug, or the native debugging tool of chrome, to check the server response headers, and to see if the behavior is the same.
Normally I use a mix of max-age and if-modified-since cache validators.
I set the max-age of some of the images to an high value (in my case 365 days, most probably not suitable for you), for some others to a week, and a day of css and javascript.
Additionally I use the if-modified-since so I have a good balance between freshness of the content, server load and bandwidth usage. The ETAG is basically the same thing as if-modified-since, with the difference you can set it to a weak cache validator, and it is really useful if the clock of the server is not reliable. (see below on the extended answer for more info and references to docs)
To enable the cache, IIS7 makes it really easy for you with the output caching IIS module. Here is a good doc about it, on how to enable it, and the difference between kernel and user mode cache.
Unless you will need to do really particular stuff, I think you will not need to create code for it, and IIS will take care of everything. If that's not the case, then here is another good guide which will help you out.
If you really want a fast website then I would recommend you to enable compression, and to add a cache layer between the application and the database. So you will not execute queries to the DB on every requests.
Here are some more good performance guidelines for any web developer.
Extended Answer (maybe even too extended :) )
There are different ways of caching the content on the client side via HTTP 1.1.
The most commons, or at least the ones I used the most are:
1) The max-age header is sent from the server, on the HTTP response headers, and basically tells the client's browser to store the content on its cache, for a period of time specified in seconds.
For instance, let's assume a server gives back a max-age=60 in response to a GET client http request of logo.jpg. The client's browser then stores the logo.jpg and for the next 60 seconds it will serve the image from its own cache.
In other words there will be no HTTP requests for this specific image for the next 60 seconds.
So with the max age the content is cached on the client side, and will not be requested or revalidated with the server for the amount of seconds specified in the max-age header.
There is however normally the possibility to force this revalidation/refresh by pressing CTRL-F5 on windows browser and CMD-R on mac browsers. On the mobile devices, normally the functionality is on the browser menu, and it is called refresh. This is the appropriate section of the RFC.
PROS
CONS
2) The last-modified server side http response header together with the client side http request header if-modified-since, is another good mechanism for speeding up the sites and to save some money. It basically works in this way.
A browser requests content for the first time to a server via a GET request.
The server responds with a 200 and gives back the content together with a last-modified header.
The last-modified header's value is nothing else than the actual date and time when the content has been modified last time. (date time must be in UTC because of the timezones)
At this point all the following HTTP requests for the same content coming from the client will have an additional header called: if-modified-since with the date and time received from the server as value.
The server when receives the following requests will check the if-modified-since header value and it will compare it with the last-modified date of the content.
If the data is the same, and therefore the content has not changed, the server will respond with a 304 and basically with no content. (most important part !)
The browser then knows it has to keep still the content on the cache and load it from it because it has not changed on the server side.
The process will continue till the content on the server changed and therefore the server will provide a new last-modified date and fresh content.
This as you can see, can save a lot of bandwidth, especially in the case of images, or JS or css, without giving up content freshness. Section 14.25 of the spec explains things much better than I did. :)
PROS
CONS
3) The ETAG is a similar process like the if-modified-since, with a difference that the value of the header is normally an hash of the server side content, and the client on the http requests sends an header called: if-none-match.
The pros and cons are the same as the point 2.
You might now wonder than what is the main difference between point 2 and point 3.
The problem with point 2 is actually the server clock. In fact there could be problems serving back the last-modified date from the server if it has clock problems
The subject is quite deeper, cause the best practice is to send a weak and a strong validator. See section 13.3.4 for more information.
我刚刚发现有关 Safari 缓存与网络应用程序交互的更多信息。
这里的 link
看来你要缓存的内容需要在manifest文件中指定。
此外,该链接还解释了如何通过 JavaScript 触发缓存失效和内容刷新。
I have just found out additional info about safari cache interaction with the web app.
Here the link
It seems that the content you want to cache needs to be specified in the manifest file.
Additionally the link explains how to trigger cache invalidation and content refresh via javascript.