1. Code
  2. PHP

3 formas de acelerar tu sitio con PHP

Scroll to top

Spanish (Español) translation by Elías Nicolás (you can also view the original English article)

En estos días, con las conexiones de banda ancha como norma, no tenemos que preocuparnos tanto por las velocidades de Internet o el tamaño del archivo de nuestras páginas. Sin embargo, eso no quiere decir que todavía no deberíamos hacerlo. Si desea reducir los tiempos de carga en su servidor, disminuir el número de solicitudes HTTP y obtener ese bit adicional para sus visitantes, existen algunas técnicas que puede usar. Este tutorial cubre una serie de trucos de PHP, incluidos el almacenamiento en caché y la compresión.

1. Amalgamación CSS con PHP

Como desarrolladores web, a menudo dividimos nuestro CSS entre varios archivos separados para mantener una separación lógica y facilitar las modificaciones. Sin embargo, esto aumenta la cantidad de solicitudes al servidor, lo que resulta en una carga de página más lenta. Usando algo de PHP podemos tener lo mejor de ambos mundos; mantener múltiples archivos de nuestro lado y usar una solicitud para recuperarlos todos.

Preparación

Antes de que podamos optimizar los archivos CSS, necesitaremos un poco de CSS para trabajar. Así que hagamos tres archivos y pongamos algo de CSS en ellos.

1
	// main.css
2
	// Just some sample CSS
3
	
4
	body {
5
		width: 800px;
6
		margin: 0 auto;
7
		color: grey;
8
	}
9
	
10
	#wrapper {
11
		margin-top: 30px;
12
		background: url(../images/cats.png);
13
	}
1
	// typography.css
2
	// Just some sample CSS
3
	
4
	body {
5
		font-family: Arial, san-serif;
6
		font-weight: bold;
7
	}
8
	
9
	strong {
10
		font-size: 120%;
11
	}
1
	// forms.css
2
	// Just some sample CSS
3
	
4
	form {
5
		position: relative;
6
		top: 400px;
7
		z-index: 99;
8
	}
9
	
10
	input {
11
		height: 50px;
12
		width: 400px;
13
	}

El PHP

Necesitamos obtener los contenidos de estos archivos y anexarlos en un orden específico. Por lo tanto, nuestro script debe recibir los nombres de los archivos CSS a través de parámetros de URL, abrir todos los archivos y juntarlos. Una explicación del código sigue.

1
<?php
2
//Lets define some useful variables
3
// --- NOTE: PATHS NEED TRAILING SLASH ---
4
$cssPath = './css/';
5
6
if (isset($_GET['q'])) {
7
	$files = $_GET['q'];
8
	// Got the array of files!
9
	
10
	//Lets just make sure that the files don't contain any nasty characters.
11
	foreach ($files as $key => $file) {
12
		$files[$key] = str_replace(array('/', '\\', '.'), '', $file);
13
	}
14
	
15
	$cssData = '';
16
	foreach ($files as $file) {
17
		$cssFileName = $cssPath . $file . '.css';
18
		$fileHandle = fopen($cssFileName, 'r');
19
		$cssData .= "\n" . fread($fileHandle, filesize($cssFileName));
20
		fclose($fileHandle);
21
	}
22
}
23
24
// Tell the browser that we have a CSS file and send the data.
25
header("Content-type: text/css");
26
if (isset($cssData)) {
27
	echo $cssData;
28
	echo "\n\n// Generated: " . date("r");
29
} else {
30
	echo "// Files not avalable or no files specified.";
31
}
32
?>

Separandolo

Parece bastante complicado, pero quédate conmigo, es realmente bastante simple.

1
<?php
2
//Lets define some usefull variables
3
// --- NOTE: PATHS NEED TRAILING SLASH ---
4
$cssPath = './css/';
5
6
if (isset($_GET['q'])) {
7
	$files = $_GET['q'];
8
	// Got the array of files!
9
	
10
	//Lets just make sure that the files don't contain any nasty charactors.
11
	foreach ($files as $key => $file) {
12
		$files[$key] = str_replace(array('/', '\\', '.'), '', $file);
13
	}

Este trozo de código establece la ruta para la carpeta CSS y comprueba que se nos han enviado algunos archivos con los que trabajar. La ruta CSS debe tener barras diagonales, de lo contrario nos encontraremos con una gran cantidad de errores. Si quisiéramos, podríamos verificar automáticamente una barra y agregarla si fuera necesario. Sin embargo, en aras de la simplicidad, omití ese comportamiento.

A continuación, verificamos cada nombre de archivo y eliminamos todas las paradas y / o barras inclinadas. Esto evita que las personas naveguen por el sistema de archivos pasando nombres de archivos como '../../secret/file'.

1
	$cssData = '';
2
	foreach ($files as $file) {
3
		$cssFileName = $cssPath . $file . '.css';
4
		$fileHandle = fopen($cssFileName, 'r');
5
		$cssData .= "\n" . fread($fileHandle, filesize($cssFileName));
6
		fclose($fileHandle);
7
	}
8
}

Ahora tenemos que construir nuestros datos de CSS a partir de los archivos individuales. Para hacer esto, recorremos la matriz de archivos con foreach, abrimos cada archivo y anexamos los contenidos a nuestros datos. El "\n" simplemente agrega un nuevo carácter de línea para mantener las cosas agradables y ordenadas. La función filesize() se usa para encontrar la longitud del archivo para que podamos decirle a fread() cuánto queremos (el archivo completo).

1
// Tell the browser that we have a CSS file and send the data.
2
header("Content-type: text/css");
3
if (isset($cssData)) {
4
	echo $cssData;
5
	echo "\n\n// Generated: " . date("r");
6
} else {
7
	echo "// Files not avalable or no files specified.";
8
}
9
?>

El último bit del script es enviar los datos de CSS al navegador. Esto significa que tenemos que decirle a PHP que estamos enviando datos de CSS, y que debe informar al navegador. Hacemos esto con la función de encabezado, configurando el tipo de contenido como 'text/css'. Luego enviamos el CSS al cliente. Primero verificamos si hay algún dato de CSS para enviar. Si no lo hay, significa que no se enviaron nombres de archivos CSS. Si este es el caso, simplemente respondemos con un comentario CSS diciendo que sí. Sin embargo, si tenemos algunos datos para enviar, los enviamos y agregamos un mensaje que detalla cuándo se generó. Si quisieras, por ejemplo, agregar alguna información de copyright a todas tus CSS de una sola vez, entonces este sería un lugar ideal.

Poniéndolo a prueba

De acuerdo, ahora es el momento de probar el guión; primero necesitamos construir una estructura de directorio y luego colocar nuestra secuencia de comandos y los archivos CSS. Echa un vistazo a la imagen a continuación e intenta replicar esa estructura. Si desea algo diferente, no olvide cambiar las rutas para reflejar esos cambios.

Una vez que todo esté en el lugar correcto, podemos probar nuestro guión. La estructura del directorio deberá colocarse en la carpeta 'htdocs' o 'www' de un servidor web con PHP (casi todos los servidores web actualmente). Navegue al archivo index.php. Debería recibir un solo comentario: 'Los archivos no están disponibles o no hay archivos especificados'. Esto significa que no hemos dado ningún archivo para que funcione. Sin embargo, la buena noticia es que este es un comentario CSS válido y no causará ningún problema.

Vamos a darle algo un poco más complicado; escriba 'index.php?q[]=main', debe obtener el CSS de su archivo main.css y un aviso en la parte inferior.

Si queremos juntar varios archivos (ya que este fue realmente el punto completo del script) podemos enviar esta solicitud: 'index.php?q[]=main&q[]=forms'. Como puede ver, podemos repetir 'q[]=' tantas veces como queramos porque está agregando cada valor a una matriz. Podría potencialmente agregar 50 archivos CSS juntos si quisiera usar este script.

Concluyendo

El uso de este método puede ser muy útil y puede proporcionar beneficios, como la posibilidad de tener una hoja de estilo predeterminada para cada página y un archivo CSS adicional para las páginas con formularios. También es fácil de implementar si ya está utilizando algún tipo de procesamiento de CSS con PHP. Si lo desea, puede cambiar el nombre de index.php a index.css siempre y cuando configure .htaccess para tratar los archivos CSS como PHP.

Es posible que observe que estoy tratando diferentes órdenes de archivos CSS como diferentes. Esto se debe a que es posible que desee que una hoja de estilo reemplace a otra y, por lo tanto, el orden de los archivos es importante. Si esto no es un problema, es posible que desee realizar una función de clasificación en la matriz de archivos antes del procesamiento.

Solo una palabra de precaución; si coloca el archivo index.php en cualquier carpeta que no sea la que contiene el CSS, entonces debe escribir las rutas relativas de su imagen de fondo como si index.php fuera su hoja de estilo. Esto es porque eso es lo que el navegador cree que es. Alternativamente, podría agregar algún código para reescribir estas URL, sin embargo, eso está más allá del alcance de este tutorial.

2. Eliminar espacios en blanco de su HTML y CSS

Muchos de nosotros usamos grandes cantidades de espacios en blanco al escribir código. La buena noticia es que el espacio en blanco en PHP en realidad no se envía al navegador. Sin embargo, lo hace en HTML.

Los navegadores tienden a mostrar solo un espacio sin importar cuántas pestañas use en su código. Esto significa que hay un poco de ancho de banda desperdiciado. Sin embargo, con algunos PHP simples podemos eliminar este ancho de banda de espacio en blanco.

Preparación

Una vez más, necesitaremos algunos datos sin procesar para trabajar; así que copie el siguiente ejemplo de código HTML y CSS. Guarde lo siguiente en un archivo .htm y .css en una carpeta dentro del directorio webroot de su servidor.

1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
	"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
<html>
4
	<head>
5
		<title>Hey a Page!</title>
6
		<link rel="stylesheet" href="./css.css" type="text/css">
7
	</head>
8
	<body id="homepage">
9
		<div id="wrapper">
10
			<div id="header">
11
				<h1>Kittens for sale!</h1>
12
				<div>
13
					There   are      lots      of spaces here! But we need to get    rid   of  them!
14
				</div>
15
			</div>
16
			<div id="mainbody">
17
				Lorem Ipsum dol...
18
			</div>
19
		</div>
20
	</body>
21
</html>
1
body {
2
	min-height: 800px;
3
	background: black;
4
	font-size: 18px;
5
}
6
7
#wrapper {
8
	width: 960px;
9
	margin: 20px auto;
10
	padding: 15px;
11
}
12
13
#header h1 {
14
	text-indent: -99999em;
15
	background: url(../images/header.png);
16
	display: block;
17
	width: 100%;
18
	height: 48px;
19
}
20
21
#mainbody {
22
	font-weight: bold;
23
}

El PHP

Una de las ventajas de este método es que el mismo script funcionará tanto con HTML como con CSS. Nuestra secuencia de comandos tiene que aceptar un nombre de archivo como parte de la solicitud. Una vez que el archivo ha sido cargado, tiene que quitar todos los espacios en blanco a solo un carácter de espacio. ¡Esto se debe a que no queremos eliminar todos los espacios entre palabras!

Una vez más, hay un montón de PHP aquí, pero lo revisaré cuidadosamente contigo.

1
<?php
2
$fileDirectory = '';
3
$file = $_GET['q'];
4
$nameExplode = explode('.', $file);
5
$ext = $nameExplode[1];
6
$fileName = $fileDirectory . $file;
7
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
8
	//Check for evil people...
9
	die('Hackers...!');
10
} else {
11
	//Lets get down to business
12
	$handle = fopen($fileName, 'r');
13
	$fileData = fread($handle, filesize($fileName));
14
	//Now for some regex wizzardry!
15
	$newData = preg_replace('/\s+/', ' ', $fileData);
16
	fclose($handle);
17
	//Time to output the data.
18
	if ($ext == 'css') {
19
		header("Content-type: text/css");
20
	}
21
	echo $newData;
22
}
23
?>

Tener una mirada más cercana

Este no es tan complicado, pero aún así lo dividiremos y nos aseguraremos de que entendamos lo que está sucediendo.

Estamos obteniendo el nombre del archivo a través de un parámetro pasado con la solicitud GET y comprobando para asegurarse de que sea un tipo de archivo permitido. Luego procedemos a buscar los datos y procesarlos para eliminar el exceso de espacio en blanco. Este método es relativamente primitivo y no eliminará todos los espacios en blanco innecesarios, ¡pero tratará la mayor parte de él en solo unas pocas líneas de código!

1
<?php
2
$fileDirectory = '';
3
$file = $_GET['q'];
4
$nameExplode = explode('.', $file);
5
$ext = $nameExplode[1];
6
$fileName = $fileDirectory . $file;

Este fragmento solo establece algunas variables. Una vez más, estamos pasando nuestros datos a través de 'q', ya que es bueno y corto. Esto también nos da un lugar para definir nuestro directorio de archivos y extraer la extensión del archivo. La función explode() rasga el nombre de archivo cada vez que ve un '.' y pone los bits en una matriz.

1
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
2
	//Check for evil people...
3
	die('Hackers...!');
4
} else {

Aquí estamos comprobando para asegurarnos de que el archivo sea CSS o HTML. Si fuera algo más, podríamos encontrarnos dándole a los hackers un hoyo en nuestro sitio como mostrarles settings.php! ¡Entonces, después de darle a los hackers la película, podemos pasar a procesar nuestros datos!

1
	//Lets get down to business
2
	$handle = fopen($fileName, 'r');
3
	$fileData = fread($handle, filesize($fileName));
4
	//Now for some regex wizzardry!
5
	$newData = preg_replace('/\s+/', ' ', $fileData);
6
	fclose($handle);
7
	//Time to output the data.
8
	if ($ext == 'css') {
9
		header("Content-type: text/css");
10
	}
11
	echo $newData;
12
}
13
?>

Ahora para la atracción principal; lo único que estamos haciendo aquí es abrir el archivo y leerlo, como hicimos en el primer guión, y luego eliminar el mayor espacio en blanco posible. Esto se logra a través de una expresión regular relativamente simple que busca en el archivo espacios, pestañas o líneas nuevas y luego los reemplaza con un espacio único.

Por último, devolvemos los datos, configurando los encabezados necesarios si se trata de CSS.

¿Pero funciona?

Si accede a su navegador y navega a 'index.php?q=css.css', deberíamos ver una línea de CSS en la página. ¡Esto muestra que todo está bien! También podemos ver el mismo efecto en el código fuente para el ejemplo html. De hecho, en ese pequeño ejemplo, hemos reducido un archivo CSS de 314 caracteres a 277 caracteres y un archivo html de 528 caracteres a 448 caracteres. No está mal para 15 líneas de código.

Conclusión

Entonces ese es un buen ejemplo de cómo podemos hacer bastante con muy poco trabajo. Si echas un vistazo al origen de las páginas como Google, encontrarás que casi no tienen espacios en blanco porque, cuando recibes millones de solicitudes, se suman unos pocos kilobytes adicionales por solicitud. Desafortunadamente, la mayoría de nosotros no tenemos tanta suerte.

3. Almacenamiento en caché en tus scripts PHP

En esta parte, le mostraré cómo 'adaptar' el almacenamiento en caché en sus scripts usando el script anterior como ejemplo. El objetivo es acelerar las cosas al no tener que regenerar los datos cada vez que alguien solicita un archivo. Generar el contenido de cada solicitud es solo un desperdicio, especialmente en datos estáticos como nuestro CSS.

Para agregar almacenamiento en caché, necesitamos agregar tres cosas a nuestro script. En primer lugar, tenemos que recopilar la entrada de datos al script y generar un nombre de archivo único para ese conjunto de entradas. En segundo lugar, debemos buscar un archivo de caché y ver si es suficientemente reciente. Por último, debemos usar la copia en caché o generar nuevo contenido y almacenarlo en caché para la próxima vez.

Rompiendo el flujo

Esta parte del proceso realmente depende de la secuencia de comandos individual, sin embargo, mostraré dónde voy a romper el flujo de este script para el almacenamiento en caché.

1
<?php
2
$fileDirectory = '';
3
$file = $_GET['q'];
4
$nameExplode = explode('.', $file);
5
$ext = $nameExplode[1];
6
$fileName = $fileDirectory . $file;
7
8
//-- WE HAVE ENOUGH DATA TO GENERATE A CACHE FILE NAME HERE --
9
10
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
11
	//Check for evil people...
12
	die('Hackers...!');
13
} else {
14
	
15
	//-- WE CAN INTERCEPT AND CHECH FOR THE CACHED VERSION HERE --
16
	
17
	//Lets get down to business
18
	$handle = fopen($fileName, 'r');
19
	$fileData = fread($handle, filesize($fileName));
20
	//Now for some regex wizardry!
21
	$newData = preg_replace('/\s+/', ' ', $fileData);
22
	fclose($handle);
23
	//Time to output the data.
24
	
25
	//-- NOW WE CAN STORE THE NEW DATA IF REQUIRED AND OUTPUT THE DATA --
26
	
27
	if ($ext == 'css') {
28
		header("Content-type: text/css");
29
	}
30
	echo $newData;
31
}
32
?>

Poniéndolo en acción

Ahora realmente escribiremos el código para el almacenamiento en caché en este script. Primero mostraré el guión completado y luego revisaré cada pieza.

1
<?php
2
$fileDirectory = '';
3
$file = $_GET['q'];
4
$nameExplode = explode('.', $file);
5
$ext = $nameExplode[1];
6
$fileName = $fileDirectory . $file;
7
$cacheName = './cache/' . $nameExplode[0] . $nameExplode[1] . '.tmp';
8
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
9
	//Check for evil people...
10
	print_r($ext);
11
	die('Hackers...!');
12
} else {
13
	if (file_exists($cacheName) AND filemtime($cacheName) > (time() - 86400)) {
14
		$cacheHandle = fopen($cacheName, 'r');
15
		$newData = fread($cacheHandle, filesize($cacheName));
16
		fclose($cacheHandle);
17
		$isCached = TRUE;
18
	} else {
19
		//Lets get down to business
20
		$handle = fopen($fileName, 'r');
21
		$fileData = fread($handle, filesize($fileName));
22
		//Now for some regex wizardry!
23
		$newData = preg_replace('/\s+/', ' ', $fileData);
24
		fclose($handle);
25
		//Lets cache!
26
		$cacheHandle = fopen($cacheName, 'w+');
27
		fwrite($cacheHandle, $newData);
28
		fclose($cacheHandle);
29
		$isCached = FALSE;
30
	}
31
	//Time to output the data.
32
	if ($ext == 'css') {
33
		header("Content-type: text/css");
34
		if ($isCached) {
35
			echo "// Retrieved from cache file. \n";
36
		}
37
	} else {
38
		if ($isCached) {
39
			echo '<!-- Retrieved from cache file. -->';
40
		}
41
	}
42
	echo $newData;
43
	
44
}
45
?>

La explicación

Este es un poco más complicado y es más probable que te deje rascándote la cabeza. Pero no se preocupe, no mucho ha cambiado y repasaremos cada sección. Una característica adicional que hemos incluido es la actualización del caché cada 24 horas. Esto es útil, así que si cambias algo, puedes esperar 24 horas o simplemente vaciar el directorio de caché. Si desea un intervalo de actualización diferente, simplemente calcule en segundos.

1
$cacheName = './cache/' . $nameExplode[0] . $nameExplode[1] . '.tmp';

Este fragmento de código simplemente obtiene el nombre y la extensión del archivo, los pega juntos y agrega el directorio de caché y la extensión apropiada '.tmp'.

1
	if (file_exists($cacheName) AND filemtime($cacheName) > (time() - 86400)) {
2
		$cacheHandle = fopen($cacheName, 'r');
3
		$newData = fread($cacheHandle, filesize($cacheName));
4
		fclose($cacheHandle);
5
		$isCached = TRUE;
6
	} else {

Aquí estamos verificando si guardamos un archivo de caché y si el archivo de caché se creó dentro de las 24 horas. Si se cumplen ambas condiciones, abrimos el archivo y extraemos su contenido para sustituir el resultado de las secuencias de comandos. También configuramos $isCached en verdadero para que podamos enviar algunos mensajes al final.

1
		//Lets cache!
2
		$cacheHandle = fopen($cacheName, 'w+');
3
		fwrite($cacheHandle, $newData);
4
		fclose($cacheHandle);
5
		$isCache = FALSE;
6
	}

Ahora estamos almacenando en caché el resultado del script para que podamos usarlo en solicitudes posteriores. Simplemente abrimos un archivo en modo de escritura, volcamos nuestros datos en él y luego lo cerramos. Estrictamente no tienes que cerrar archivos en PHP, pero se considera una buena práctica, así que lo he hecho aquí.

1
2
	//Time to output the data.
3
	if ($ext == 'css') {
4
		header("Content-type: text/css");
5
		if ($isCached) {
6
			echo "// Retrieved from cache file. \n";
7
		}
8
	} else {
9
		if ($isCached) {
10
			echo '<!-- Retrieved from cache file. -->';
11
		}
12
	}

Esta es otra parte del guión que se modificó un poco para que podamos ofrecer algunos comentarios a través del navegador. Si el archivo se recuperó de la memoria caché, podemos agregar un mensaje a la salida del script. Tenga en cuenta que el mensaje para los scripts CSS tiene '\n' al final. Esto se debe a que los caracteres "//" comentan toda nuestra línea y "\n" empujan todo lo demás a otra línea. Si desea deshabilitar los mensajes, todo lo que tiene que hacer es comentar la línea '$isCached = TRUE;'.

Dándole un giro

Si utilizamos nuestro script nuevamente, no notaremos ningún cambio hasta que lo actualicemos nuevamente, cuando veamos un mensaje que dice que el archivo fue recuperado del caché. ¡Dulce éxito! Esta configuración de almacenamiento en caché también se puede aplicar a la primera secuencia de comandos con poca modificación, sin embargo, se deja como un ejercicio para el lector.

Concluyendo

Ser capaz de agregar rápidamente un caché simple pero efectivo a cualquier script en el que esté trabajando es una habilidad extremadamente útil. Simplemente agrega ese bit adicional a la secuencia de comandos, reduciendo la carga en su servidor y acelerando el sitio para los usuarios. ¡Eso es ganar-ganar!

Resumiendo

En este tutorial, le he mostrado algunas formas prácticas pero simples de acelerar su sitio con una pizca de PHP. Realmente espero que los encuentres útiles y que puedas aplicarlos a un proyecto en el futuro. ¿Cómo se mejora el rendimiento de su sitio?