How to cache specific parts of page in PHP intelligently? - php

Problem:
I've a website which has 50k+ pages and most of them are only updated once on the creation time, I am building a caching for these pages as they do not need any frequent changes on the content. But I'm confuse about few things.
If I cache whole page, how do i preserve User Login/Logout status in sidebar
How do I cache the meta tags for the page as main caching is done in the middle of page as this is most expensive part as far processing is concerned.

Take a look at the Cache_Lite PEAR module.

For your first point - you can make the login status sidebar load via AJAX, if you want to cache the rest of the page. Since the result of the AJAX request is separate (and presumably, not cached), it will update properly.
Assuming you're actually sending the meta tags as part of the page content, you might want to wait to actually write anything to the output stream until after all of your processing is done, so that you're free to compute things in any order, even if they come earlier or later in the actual page HTML content.

Obviously I don't have specific information regarding your setup, but a common tactic is to simply cache the database result/page specific content in Memcached. If Memcached isn't an option for you, you could create a writable directory on your server and just cache the page specific content there. So, you would still be generating the user specific content on each request, but without the overhead of querying the database unnecessarily.

Apply content filters before output.
You could simply use parts in your template that are reference ids of content that should be dynamic, and replace them with a the result of a function call, on the fly.
Example:
<p>some cached content</p>
<div id="user_box"> {{USER_BOX}} </div>
<p>other cached content</p>
First, fetch your cached content, then in your code, replace {{USER_BOX}} with a function call result, and finally output the modified result.
This way, you won't need to code and perform extra AJAX requests (the more server calls the less performance).
Of course you could treat your cached content with some template engine like Twig (part of Symfony) if you're using php. That would add some extra features like conditions, etc.

Related

Dynamic content in PHP WordPress page

I have a ecommerce store website running with WordPress. I'd like to include a section with a -random custormer's product review, so that every time someone access the page, there will be a different comment there.
I'm not used to PHP, but I managed to create a shortcode which takes a random comment and returns the proper HTML. It is working fine (in eddition mode, every time I insert the shortcode a different comment appears).
My issue is that when I leave the page and return, the previous one is still there. I believe that it is being caused by cache, but I wouldn't like to disable the cache for the whole page.
How you I force the shortcode run again (I don't know if it is the right way to explain) and make sure that at every access, a different comment appears?
One solution I thought is to have JS code which would do preaty much the same thing my PHP code does, using Woocommerce API to get the data. But I'm wondering if there is a simpler solution to do that, like forcing the specific section not being cached or re-run the shortcode.
Thanks!
JS can't do what PHP does here: at most it can create an AJAX-call to the backend that then runs a query for a random comment and returns it. You need to render it thereafter. It's fairly standard, but overkill for your case.
Instead, you're going to want to check whether your caching mechanism supports ESI or something else that excluded parts of your code from being cached.

How to make the 1st part of the site loads first? (Like in Google PageSpeed)

I have a very large site and it takes pretty long time to load. It takes around 120 seconds. What I'm trying to do is loads 1st half of the site loads 1st. Then user can surf while others parts are being loaded.
What I'm trying to do is below.
1st of all is this possible ?
According to my knowledge Yes since Google PageSpeed does that. But the problem is if I use PageSpeed I would have to change my DNS server settings and etc. I would like to do this myself.
How can I get it done ?
What type of technology should I use ?
Given that pages have the .php extension and written in PHP language.
You can use the concept of lazy loading.
You can load only content that is necessary during the load then using jquery and ajax you can load the remaining content.
In this way user can surf and interact easily with the the part already loaded while the other part will be loading asynchronously.
jQuery ajax or post method can help you on this.
A simple example could be,
If There are 5 parts of contents in your page, 2 needs to be loaded immediately
The page will be loaded with 2 parts loaded, so it will take quite less time than 5 parts loading
After document is loaded you will use ajax to load the remaining 3 parts.
Ajax will send request to the specific page of your website(can be possibly named AjaxRequestHandler.php) with some parameters, and this page will process your request and generate html for this and will send it back to your main page which will just show this returned html and this all be happening asynchronously, so the user will be able to communicate with the initially loaded 2 parts
And even if you are new to web technologies, I suppose you have to have the knowledge of atleast ajax and asynchronous calls etc. to achieve lazy loading.
Edit :
For your this question
Except AJAX Is there way around for this?
I think you can try iframes if they can help.
Loading the main content in the page load without iframe while loading other contents in the iframes after pages is loaded.
This jsFiddle
jsfiddle.net/cGDuV/
can help you understand lazy loading with iframe, mentioned in this post of stackoverflow.
You can use javascript for the same if you want to avoid jquery.
You can manipulate the output buffer such that it flushes early thus achieving what your after in the screenshot you posted in your question.
http://www.stevesouders.com/blog/2013/01/31/http-archive-adding-flush/
You can lazyload all your images. Here's a jquery plugin that does it easily
http://www.appelsiini.net/projects/lazyload
You can combine all your js in one file. Same with your css files. This will help the speed.
You can incorporate caching, expires headers and gzip/deflate compression
https://github.com/h5bp/html5-boilerplate/blob/master/dist/.htaccess
I would suggest you load your 3rd party javascript widget garbage (Google+ buttons, fabebook like buttons, social, twitter stuff) in a non blocking asynchronous way so it does not slow down the page in the beginning.
http://css-tricks.com/thinking-async/
Optimize your images as much as possible.
http://kraken.io/
Use a CDN
http://www.maxcdn.com/
Finally test your site and see where is the big bottleneck and where you can improve the site for speed optimization. Use the waterfall chart feature
http://www.webpagetest.org/
One of the things you can do is to load all the essential (top half) of the page normally, then use javascript/ajax to load the second half of the page. This is a very common technique (and is often used to load images).
Here is an excellent tutorial from jQuery for Designers, walking through how to use jQuery to load images asynchronously after the page loads. http://jqueryfordesigners.com/image-loading/
Having said that, a two minute load time seems very excessive. Maybe you should check if there is anything that could be slowing down your server.
You need to determine why the site is loading slow. What is the size of the data you are sending? Google and Firefox have web developer tools to help you determine which elements are taking the longest too load. Once you've determined the culprit, try to load the worst offenders asynchronously.
Check out this article on aync requests: https://segment.io/blog/how-to-make-async-requests-in-php/
in my opinion you need an endless scrolling solution. That is, have a fixed amount of content per "page" (could be an estimated 1500px worth of height). Use jQuery to load another "page" when user scrolls down by a set amount.
If you really want to unconditionally load all the content, just use the same approach, and on document ready trigger the next page to load. The loop the page loader until the whole thing is loaded. That way, you load the first "page", and defer the content "below the fold" to subsequent requests.
What you want is what Facebook does Bigpipe and here is a relevant SO post: Facebook Bigpipe Technique Algorithm
There are other solutions involving all sorts of Javascript but since you want PHP and Facebook uses PHP you should read up on Bigpipe. Juho even has an example written in PHP so that should meet your PHP requirements (but yes it still requires js but not AJAX).
Prefetching Resources the web page require large files for loading can often benefited from changing the order that those files are requested from the server. Sometimes, it makes sense to download files before they are necessary, so that they are instantly available once requested. When the resources required for a page can be loaded in advance, the user-perceived network latency for that page can be significantly reduced or even eliminated. When you run Google pagespeed insights and see the result, you will see how the fix the problems in your website.
Some tips to load site faster:
Make fewer HTTP requests
Add a far-future expires header
Gzip your page's components
Minify your JavaScript, CSS and HTML
One more thing when loading a webpage and if you are using php with smarty you can use this plugin which reduces the number of http requests to you server and makes the site load faster by combining all the js and css resource's request into one single HTTP request.
Alternatively you might be looking for these plugins.
http://masonry.desandro.com/
http://isotope.metafizzy.co/
http://www.wookmark.com/jquery-plugin
Does all this stuff have to be on the same page? Does it make sense to split the content over multiple pages? Can some of it be delayed until the person requests it? Can it be grouped into tabs? Hidden tabs could be lazy loaded for instance.
Give serious thought to restructuring the content in other ways. You might be able to come up with an alternate arrangement that simplifies the problem.
Having in mind all that was mentioned above you may think of caching parts of your data/html code with memcache or in any other way possible so you skip its generation every time. Of course this depends pretty much on how often the data changes.
Don't browsers render the document as it comes in? Whatever you put at the top of the file will be received by the client first, and therefore will be displayed first. For example, when you try to view a very large image file online, it loads from top to bottom. The same is true for web pages. Just put the content you want to load first at the top of the page!
Answer to question one: yes
Answer to question two: above
Answer to question three: Nothing, just put the page in the correct order.
Well the idea is more or less the same as described by Pawan Nogariya above. You will need to fetch views and data asynchronously and then display these. But this means that you will never redirect or post back to any other page rather will get every view via ajaz. This will make you application SPA (Single Page Application) like Gmail. And, this will also mean you need to keep track of what has been renedered and what not, leaving you in a mess. So, instead of doing everything your way there are already developed and popular frameworks available that let you do that but they also make it SPA. Which means that your application doesnt "posts" to the server as in redirection but everything is doen using Ajax.
You can use Backbone (Backbone.js), Knockout (Knockout.js) and may others to achieve this. These are javascript based frameworks that help achieving what you have just asked and may expample and tutorials are also easily available. You can use it with any language as we are using it with C# (MVC) for a relatively large applicaiton.
this is going to be ugly! You should definitely consider using ajax calls to load page fragments AFTER a first content stage is loaded!
This is going to break almost all known web standards, but it might render the website in parts....
this being said: here's the ugly stuff
First: get rid of the <html> tag of your website, start with the <head> DO NOT use a <body> tag either.
Now send your html-code in the order you want it to be loaded (top first) using echo ...
after each closing tag of a group (say </table> or </div>) use flush(); ob_flush(); this will send all known content to the browser immediately.
The browser now decides if it can render the known content or not and if it will (based on the browser specifics and user settings) but with few exceptions it will.
some browsers like to wait for the closing body-tag that's why we dropped it, others even wait for the closing html tag (safari afair) that's why we dropped that too.
If you use the echo-flush scenario wisely you should be able to split the page into renderable parts which most browsers will display without an error.
Again... don't do it this way.. it's bad, ugly and not even near any web standards
But you asked for it.
For your this question
Except AJAX Is there way around for this?
I think you can try iframes if they can help.
Loading the main content in the page load without iframe while loading other contents in the iframes after pages is loaded.
This jsFiddle
jsfiddle.net/cGDuV/
can help you understand lazy loading with iframe, mentioned in this post of stackoverflow.
You can use javascript for the same if you want to avoid jquery.
With pure PHP? Not smart.
$(function() {
$('#body').delay(1).fadeOut();
});
Fiddle example: http://jsfiddle.net/r7MgY/

How much slower would be to cache JSON instead of ready HTML in simple blog-like articles

I've got a simple caching system that works like this:
1. Editor goes to the admin panel,
2. Enters the data,
3. The data is saved to MySQL (for good measure) and put in the HTML template.
The template itself is a part of my page where the article is presented (its like <article>...</article>). Saved in HTML as {id}.html
When user enters the page /articles/22/ I just include() the corresponding HTML page to the main template. Super simple.
But it's a little primitive IMO. And I started to wonder wouldn't it be better to store JSON with fields like title, content, tags and stuff and then parse this with PHP and put to template. It gives me a few benefits (like the possibility to put the data in other places in the template), but my first priority is speed.
So - my question would be: would it be noticeable slower to get JSON (pre-saved in text files), parse it with PHP and put into template than including pre-saved HTML file. I know there is nothing to wonder here if we talk about 100 request in the same time, but what if we talk about more? Or maybe my approach is not mature at all and I should stick to popular "user gets to the page, you check how long ago the cache file was created, you include it or get from SQL if it expired"? I don't like that. I just don't think there is any reason user should be involved in creating the cache files. The only time they change is when the editor makes some changes, so let him be the one who creates cache files.
Using read through caching will get you a long way. Basically, if an object (could be rendered HTML, json or whatever works in your flow), does not exist in the cache, you would read through to the database to build it, once built, you would store it in the cache.
If changes were made to the object, you could delete the cache and it would be rebuilt the next time it is requested.
As for a cache, you would probably want to use something like memcached, although apc could work pretty well too.

Rendering a Template with PHP

These day's I'm working into a New's Website ,and the back-end I'm writing from scratch without using any PHP Framework's.
My concern is unreasonable periodic query's against MySQL("What does it mean !:)")
On the first Page user would see only updated Posts ,so i thought when Page Administrator insert's a Post i will Render a .html File with updated newest Post's and User's will get redirected there where all Posts are there and everything is fine(no php execution no MySQL Query's against a large Database).
So far Index.php was Executed ,did a Select at MySQL and present the data ,now i want to Execute Index.php get it's content and save it as Index.html
So is there a way to call a .PHP file ,Execute it Localy and save the Output into an HTML File ,just like User's will Execute.
Yes. What you can do is by using Curl library, call your index.php with full url. (eg. http://127.0.0.1/index.php). So, you take output of executed index.php instead of its code. Then, by using file_put_contents function, you can save output to an index.html file.
The easiest way to do it would be to use PHP's output buffering and store the output buffer in a file.
ob_start();
// process page here
$buffer = ob_get_flush(); // this will display the contents of the output buffer and return the contents into $buffer
file_put_contents('index.html', $buffer);
Just a short hint:
Your php file gets data from a database and save the output of it via the output buffer and safe everything to a html file. You script just have to check whether the .html file exists or not. If not > create it; else > include it / print the content.
Rally simple and you don't have to query the db all the time.
I suggest you look into something like Varnish which sits in front of your web application and provides a caching layer.
Because it sits between the user and your application, it is language / framework agnostic, thus integration effort tends to be lower.
(I realise this doesn't answer your question exactly in terms of implementation detail, but I want to point out that caching internal to your application isn't the only option for reducing database load)
Some statements to think of:
Databases intended to be queried. Nothing essentially wrong with "periodic query's against MySQL".
On the real-world website there will be not only one dynamical part: there will be things like banners, number of comments, fresh blog posts and such.
Stackoverflow is using such way of caching. It turns out to be expremely annoying when you are trying to refresh the page to get new data and it returns nothing.
Premature optimization is a root of all evil.

How to change language without reloading page with PHP / Jquery

I am working on a multilangual website right now.
I am currently including the related language file ('lange/_en.php') for language phrases.
To change languages users will select their language from a < select > item. The thing i want to do is changing related phrases (and urls too if possible) in the page without refreshing or submitting the page.
I remember i saw something like this in web but i have no idea where.
Any help or any ideas about how this thing can be done?
The issue with this is that a language change doesn't only affect a small section of the page, it affects the whole page. So really, you are left with three choices.
The simple way which is indeed reloading the whole page. It's easy to implement, easy to maintain, and doesn't require you to make sure that JavaScript currently running on your page is aware of the new language at runtime.
The complicated way which is getting all the new markup via AJAX and replacing the content of the <body> tag with the reloaded content. This will cause issues with other scripts running (such as image carousels, etc.) that holds a reference to an element so you have to reinitialize every single script that is running on settimeout() on your page.
The close to impossible way which is to have a client side dictionary, selecting each relevant tag, and changing its contents with the new language. This is a pain to setup and a pain to maintain. You literally need a section tailored to each specific page. Again, if you have scripts with strings, you'll have to make sure that the strings they use are updated to the new language.
You are better off simply reloading the page. It will work without JavaScript and it's a one time deal that won't bother users.
check this plugin out:
http://keith-wood.name/localisation.html
It changes language 'on the fly' without going back to server side.
Image reload prototype if-modified i posted about image content update to selected language without reloading the page.
The image takes the value thats sent and updates to language/country code (which is bound to language) on DB and updates image content (characters) to match their keyboard layout..
Hope its some use

Categories