Tag Archive: css


Trò chơi chữ trực tuyến, luyện đánh máy hay bắn súng là những trò chơi chúng ta sẽ được thấy ở phần cuối này.

Tiếp tục phần 1 và phần 2, chúng tôi sẽ giới thiệu tới các bạn 1 số game khác trên nền HTML5 cũng không kém phần thú vị. Hi vọng bạn sẽ thoải mái sau khi trải nghiệm thử những game chúng tôi sắp giới thiệu sau đây.

WordSquared

Đây là 1 trò chơi chữ trực tuyến nhiều người chơi cùng lúc. Nhiệm vụ của bạn trong trò chơi này là dùng những từ được cung cấp ngẫu nhiên để ghép với những từ đã có thành 1 từ có nghĩa. Mọi người cùng chơi trên 1 “bàn” và tất các các từ họ ghép được sẽ liên kết với nhau thành 1 mạng lưới các từ ngữ khổng lồ.

VN-MAX.net

Cách chơi rất đơn giản, bạn kéo thả các từ được cung cấp sẵn ở bên khung bên dưới vào “bàn” sao cho chúng ghép lại với nhau thành 1 từ có nghĩa trong tiếng Anh, bạn bấm nút “Add Word” để đồng ý. Nếu thành công, từ của bạn vừa ghép sẽ được “đính” vào “bàn” và bạn được cộng điểm. Mục tiêu của bạn là ghép được càng nhiều từ càng tốt, sau mỗi từ ghép đúng, bạn sẽ được cung cấp thêm các kí tự mới. Bạn có thể bấm nút “Swap tiles” để đổi các kí tự khác và trả giá bằng việc bạn bị trừ 1 “mạng”, bạn chỉ có 3 “mạng” cho mỗi lần chơi.

VN-MAX.net

Đây là 1 trò chơi tuyệt vời để giúp bạn củng cố vốn từ vựng tiếng Anh, bạn có thể tạo 1 tài khoản và mời bạn bè tham gia để cùng nhau thi thố.

Z-type.

Z-type là trò chơi thuộc thể loại đánh chữ, giống như những trò chơi cùng thể loại, nhiệm vụ của bạn là đánh càng nhanh càng tốt các từ xuất hiện trên màn hình. Điểm đặc biệt của Z-type là trò chơi mô phỏng việc đánh chữ như là 1 cuộc chiến chống lại kẻ thù, bạn điều khiển 1 phi thuyền, và bạn gõ các từ xuất hiện trên quái vật để tiêu diệt chúng. Số lượng quái vật và tốc độ di chuyển của chúng ngày càng nhanh để tập cho bạn tốc độ đánh máy tốt hơn.

VN-MAX.net

Private Joe.

Trò chơi phiên lưu, bắn súng được viết trên HTML5 với âm thanh và hiệu ứng khá tốt. Cách chơi tương tự như Mario nhưng bạn vào vai 1 người lính đi vào hang ổ của kẻ thù, đối đầu với sự bắn trả quyết liệt của kẻ thù để cứu đồng đội.

VN-MAX.net

Bạn dùng phím “X” để nhảy lên, phím “C” để bắn, phím mũi tên để di chuyển. Hiệu ứng di chuyển, va chạm với đạn pháo của đối phương và âm thanh trong game khá tốt. Rất tiếc đồ họa lại đơn giản giống như 1 trò chơi thời MS-DOS. Tuy vậy, nội dung game khá hấp dẫn có thể dễ dàng thu hút bạn ngay lần thử đầu tiên.

Coil.

Đây là trò chơi mini đơn giản xứng đáng với vai trò “xả stress” sau những giờ làm việc căng thẳng. Nhiệm vụ của bạn là kéo chuột vòng quanh màn hình khoanh tròn các điểm sáng màu xanh để cho chúng không bị “nổ tung” ra. Bạn sẽ bị trừ điểm nếu để cho các điểm sáng này chuyển sang màu vàng và “nổ” cũng như lỡ tay khoanh các điểm màu đỏ.

VN-MAX.net

Game có hình nền màu đen với các điểm sáng màu xanh, đỏ và vàng làm cho mắt bạn cảm thấy thoải mái sau nhiều giờ tập trung vào máy vi tính.

Tiếp tục với chủ đề chơi Game trên web với công nghệ HTML5. Phần 2 này sẽ tiếp tục làm bạn bất ngờ với những khả năng vượt trội mà HTML5 đem lại.

Phần này, chúng tôi sẽ giới thiệu tới bạn những thể loại game tương đối hoành tráng và từng làm say mê không ít người dùng máy tính từ xưa tới nay.

Tank World

Trò chơi “Bắn xe tăng” được xây dựng với giao diện 3D đầy ấn tượng. Luật chơi tương tự những trò chơi trước đây, nhiệm vụ của bạn là phải điều khiển xe tăng của mình tiêu diệt toàn bộ đối phương và giải các nhiệm vụ trò chơi đưa ra.

VN-MAX.net

Tank World đem tới cho bạn 1 cảm giác “bắn tăng” thú vị hơn với giao diện 3D hình quả địa cầu, bạn điều khiển xe tăng bằng cách dùng phím mũi tên đi lên/đi xuống để điều khiển xe tăng di chuyển về phía trước hoặc đi lùi, phím mũi trên trái/ phải dùng để “lái” xe tăng rẽ trái hoặc phải. Để bắn, bạn dùng chuột hướng về phía đối phương và “Click”.

Âm thanh trong game khá đơn giản, không có nhạc nền và chỉ có tiếng súng và tiếng nổ khi đối tượng bị tiêu diệt. Hiệu ứng cháy nổ, đường đạn và va chạm nhìn chung khá tốt đối với 1 game trên web HTML5.

Pirates Love Daisies

Đây là trò chơi thuộc thể loại “Tower Defense” với giao diện khá đẹp mắt. Thay vì xây dựng/ nâng cấp những khẩu súng hoặc tháp canh, người chơi sẽ đặt những thủy thủ thường gặp trong các bộ phim cướp biển nổi tiếng vào những vị trí canh gác để không cho quái vật đi qua cầu.

VN-MAX.net

Mọi chức năng thường thấy trong game thể loại này để xuất hiện đầy đủ trong Pirates Love Daisies và được thể hiện 1 cách sinh động và ngộ nghĩnh hơn.

Worlds Biggest Pacman

Pacman là 1 trong những trò chơi nổi tiếng và kinh điển nhất từ trước tới nay. Luật chơi của game có lẽ bạn cũng đã biết, bạn phải điều khiển Pacman của mình di chuyển để ăn điểm và tránh “ma”.

VN-MAX.net

Điểm đặt biệt của Worlds Biggest Pacman là thư viện bản đồ chơi (map) khổng lồ được thiết kế bởi người chơi (hiện tại vào khoảng 25.500 người). Bạn sẽ thấy danh sách các bản đồ này ngay khi vào trang web. Bạn chỉ cần đưa chuột vào 1 bản đồ mình thích và bấm “play” để chơi.

VN-MAX.net

Mọi tính năng, đồ họa và âm thanh của game không có nhiều khác biệt so với các game Pacman trước đây. Tất cả được xây dựng trên nền HTML5 tiên tiến nhất.

Sand Trap

Sand Trap được phát triển bởi Casual Gameplay, thuộc thể loại game mini với cách chơi đơn giản, luật chơi đơn giản nhưng dễ dàng thu hút người dùng bỏ vào game hàng giờ liền.

VN-MAX.net

Nhiệm vụ của bạn trong Sand Trap là đổ cát trong hình chữ nhật “mê cung” ở trên vào trong xô màu đỏ ở bên dưới, bạn phải đổ đủ số cát yêu cầu vào xô để được qua màn tiếp theo. Để đổ cát, bạn bấm và kéo chuột để xoay hình chữ nhật, các hạt cát ở trong hình sẽ di chuyển theo quy luật của trọng lực. Để đổ được cát vào xô, bạn xoay hình chữ nhật sao cho khi cát rơi ra ngoài qua các khe trống sẽ vào đúng trong xô.

Cheat Sheets for Front-end Web Developers

Cheat sheets are helpful to have around because they allow you to quickly remember code syntax and see related concepts visually. Additionally, they’re nice decorative pieces for your office.In this article, you’ll find 23 excellent, print-ready cheat sheets for HTML/HTML, CSS, and JavaScript (including MooTools and jQuery).So go ahead – print out your favorites and pepper your workspace with these wonderful references.

HTML/XHTML

1. HTML Help Sheet

HTML Help Sheet Screenshot

2. HTML Cheat Sheet

HTML Cheat Sheet - Screen shot.

3. HTML Character Entities Cheat Sheet

HTML Character Entities Cheat Sheet - Screen shot.

4. XHTML Cheat Sheet v. 1.03 – PDF

XHTML Cheat Sheet v. 1.03 - screen shot.

CSS

5. CSS Cheat Sheet (V2)

CSS Cheat Sheet (V2) - screen shot.

6. CSS Cheat Sheet

CSS Cheat Sheet - screen shot.

7. CSS Shorthand Cheat Sheet

CSS Shorthand Cheat Sheet - screen shot.

8. CSS Level 1 Quick Reference – PDF

CSS Level 1 Quick Reference - screen shot.

9. CSS Level 2 Quick Reference – PDF

CSS Level 2 Quick Reference - screen shot.

10. CSS2.1 Quick Reference Card – PDF

CSS2.1 Quick Reference Card - screen shot.

11. CSS2 Reference Guide – PDF

CSS2 Reference Guide - screen shot.

JavaScript

12. JavaScript Cheat Sheet

JavaScript Cheat Sheet - screen shot.

13. Addison-Wesley’s JavaScript Reference Card – PDF

Addison-Wesley's JavaScript Reference Card - screen shot.

14. JavaScript and Browser Objects Quick Reference

JavaScript and Browser Objects Quick Reference - screen shot.

15. The most common DOM methods at a glance – PDF

The most common DOM methods at a glance - Screen shot.

16. JavaScript Quick Reference Card/Cheatsheet

avaScript Quick Reference Card/Cheatsheet - Screen shot.

17. mootools 1.2 cheat sheet

mootools 1.2 cheat sheet - screen shot.

18. jQuery Cheatsheet

jQuery Cheatsheet - screen shot.

19. jQuery 1.2 Cheat Sheet

jQuery 1.2 Cheat Sheet - screen shot.

20. jQuery Visual Map – PNG

jQuery Visual Map - screen shot.

Miscellaneous

21. RGB Hex Colour Chart

RGB Hex Colour Chart - screen shot.

22. The Web Developer’s SEO Cheat Sheet

The Web Developer's SEO Cheat Sheet - screen shot

23. The WordPress Help Sheet

The WordPress Help Sheet - screen shot.

Hope you picked up a cool cheat sheet or two. If your favorites aren’t on the list, don’t forget to share it with us in the comments.

Source: http://sixrevisions.com/resources/cheat_sheets_web_developer/

Cheat sheets are helpful to have around because they allow you to quickly remember code syntax and see related concepts visually. Additionally, they’re nice decorative pieces for your office.In this article, you’ll find 23 excellent, print-ready cheat sheets for HTML/HTML, CSS, and JavaScript (including MooTools and jQuery).So go ahead – print out your favorites and pepper your workspace with these wonderful references.

HTML/XHTML

1. HTML Help Sheet

HTML Help Sheet Screenshot

2. HTML Cheat Sheet

HTML Cheat Sheet - Screen shot.

3. HTML Character Entities Cheat Sheet

HTML Character Entities Cheat Sheet - Screen shot.

4. XHTML Cheat Sheet v. 1.03 – PDF

XHTML Cheat Sheet v. 1.03 - screen shot.

CSS

5. CSS Cheat Sheet (V2)

CSS Cheat Sheet (V2) - screen shot.

6. CSS Cheat Sheet

CSS Cheat Sheet - screen shot.

7. CSS Shorthand Cheat Sheet

CSS Shorthand Cheat Sheet - screen shot.

8. CSS Level 1 Quick Reference – PDF

CSS Level 1 Quick Reference - screen shot.

9. CSS Level 2 Quick Reference – PDF

CSS Level 2 Quick Reference - screen shot.

10. CSS2.1 Quick Reference Card – PDF

CSS2.1 Quick Reference Card - screen shot.

11. CSS2 Reference Guide – PDF

CSS2 Reference Guide - screen shot.

JavaScript

12. JavaScript Cheat Sheet

JavaScript Cheat Sheet - screen shot.

13. Addison-Wesley’s JavaScript Reference Card – PDF

Addison-Wesley's JavaScript Reference Card - screen shot.

14. JavaScript and Browser Objects Quick Reference

JavaScript and Browser Objects Quick Reference - screen shot.

15. The most common DOM methods at a glance – PDF

The most common DOM methods at a glance - Screen shot.

16. JavaScript Quick Reference Card/Cheatsheet

avaScript Quick Reference Card/Cheatsheet - Screen shot.

17. mootools 1.2 cheat sheet

mootools 1.2 cheat sheet - screen shot.

18. jQuery Cheatsheet

jQuery Cheatsheet - screen shot.

19. jQuery 1.2 Cheat Sheet

jQuery 1.2 Cheat Sheet - screen shot.

20. jQuery Visual Map – PNG

jQuery Visual Map - screen shot.

Miscellaneous

21. RGB Hex Colour Chart

RGB Hex Colour Chart - screen shot.

22. The Web Developer’s SEO Cheat Sheet

The Web Developer's SEO Cheat Sheet - screen shot

23. The WordPress Help Sheet

The WordPress Help Sheet - screen shot.

Hope you picked up a cool cheat sheet or two. If your favorites aren’t on the list, don’t forget to share it with us in the comments.

Since few days we have been registering heavy traffic spikes on our website. This lead to performance issues. As this site is currently hosted on a shared hosting server, it is very difficult to optimize the performance of the site.We are using WordPress as CMS for this blog, hence we decided to install WP-Super cache plugin for WordPress to improve the performance. This plugin will create static HTML files from your blogs post and other pages and save them on web server. These HTMLs are served to client whenever consecutive requests are made. Hence this greatly improve the performance as it reduce PHP parsing and database connections.Bandwidth control is an important task to be followed when your traffic is increasing. With limited monthly bandwidth hosting, your site may run out of bandwidth and thus result in increase in down time. Hence it is very much advisable to compress your websites response with GZip and then serve it to client. Compressing output can significantly improve your websites performance by reducing the size sometimes upto 80%!So how can you enable GZip compression and compress your websites output? Well there are several ways to achieve this. I have listed out following very useful tricks to enable compression.

GZip compression in Tomcat, JBoss server

You can find a full post explaining this trick here.

GZip using mod_gzip, mod_deflate and htaccess

Apache server supports server level GZip compression with the help of module mod_gzip and mod_deflate. You can use this module and enable GZip compression for your website using htaccess file. First you have to check whether your hosting provider has enabled mod_gzip or mod_deflate module or not? To check this, you can use php_info() function of PHP which prints all the information about server and modules.You can enable compression for text and html by adding following lines in your htaccess file.

# compress all text and html:AddOutputFilterByType DEFLATE text/html text/plain text/xml# Or, compress certain file types by extension:<Files *.html>SetOutputFilter DEFLATE</Files>

You can compress all type of content (image, css, js etc) using mod_deflate. Copy following code in htaccess to do this.

<Location />    SetOutputFilter DEFLATE      SetEnvIfNoCase Request_URI  \        \.(?:gif|jpe?g|png)$ no-gzip dont-vary    SetEnvIfNoCase Request_URI  \        \.(?:exe|t?gz|zip|gz2|sit|rar)$ no-gzip dont-vary</Location>

Also, you can add following code in your htaccess file and enable compression using mod_gzip.

<IfModule mod_gzip.c>    mod_gzip_on       Yes    mod_gzip_dechunk  Yes    mod_gzip_item_include file      \.(html?|txt|css|js|php|pl)$    mod_gzip_item_include handler   ^cgi-script$    mod_gzip_item_include mime      ^text/.*    mod_gzip_item_include mime      ^application/x-javascript.*    mod_gzip_item_exclude mime      ^image/.*    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*</IfModule>

This technique only works if mod_gzip or mod_deflate modules are loaded in Apache. In our case, these modules were not there and our hosting provider refused to load it as we were using a shared hosting. So following can be another way of enabling compression.

GZip using PHP ob_start() method

If your hosting provider does not support mod_gzip module, ob_start() method can be used to enable compression in PHP file. For this you need to copy following line in top of the PHP file. You may want to add this line in start of the header file that gets included in every php.

<?php	if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'))		ob_start("ob_gzhandler");	else		ob_start();?>

Above code will check whether your browser supports gzip, if yes, then it send ob_gzhandler method as handle to ob_start method which buffers the output. Thus output is compressed using ob_gzhandler. Only problem with this method is that you have to manually edit all PHP files or should have a header.php file that gets included in all files. There are still ways to achieve this without touching your PHP files. Read following trick.

GZip using php_value directive in htaccess

php_value directive can be used to append/prepend any PHP files in the request of change the output handler. First we will see how we can prepend a PHP file and achieve this. Copy the PHP code that we saw in above example in a file called gzip-enable.php. Now copy following lines in your htaccess file. Thus you need not to modify any of your PHP files can can prepend a PHP file with ob_start() method to all the files.

<FilesMatch "\.(txt|html|htm|php)">    ForceType application/x-httpd-php	php_value auto_prepend_file /the/full/path/gzip-enable.php</FilesMatch>

But what if you don’t want to prepend a PHP file? Still there is a way to specify default output handler using htaccess. Use following line in your htaccess file to tell your apache to register ob_gzhandler handler function as output handler.

    php_value output_handler ob_gzhandler

Compress CSS using htaccess and php_value

CSS Stylesheet files occupy significant size in overall webpage size. It is hence advisable to compress these files before sending them to client. This significantly improve the performance of a webpage. For compressing CSS files, we will first create a PHP file gzip-css.php with following code.

<?php   // initialize ob_gzhandler function to send and compress data   ob_start ("ob_gzhandler");   // send the requisite header information and character set   header ("content-type: text/css; charset: UTF-8");   // check cached credentials and reprocess accordingly   header ("cache-control: must-revalidate");   // set variable for duration of cached content   $offset = 60 * 60;   // set variable specifying format of expiration header   $expire = "expires: " . gmdate ("D, d M Y H:i:s", time() + $offset) . " GMT";   // send cache expiration header to the client broswer   header ($expire);?>

Now add following lines in your htaccess file to enable compression for CSS files.

<FilesMatch "\.(css)">    ForceType application/x-httpd-php	php_value auto_prepend_file "/the/full/path/of/this/file/gzip-css.php"</FilesMatch>

Whenever a http request for .css will come to a server, the type of css will get converted to application/x-httpd-php, thus making them parsed using PHP. Then a file gzip-css.php will be prepend to this request which in turns compress the output using ob_start (”ob_gzhandler”) method.

Compress JavaScript (JS) using htaccess and php_value

Similar to above example for CSS, JavaScript files can also be compressed and sent to client. For this create a PHP file gzip-js.php and copy following code in it.

<?php   // initialize ob_gzhandler function to send and compress data   ob_start ("ob_gzhandler");   // send the requisite header information and character set   header ("content-type: text/javascript; charset: UTF-8");   // check cached credentials and reprocess accordingly   header ("cache-control: must-revalidate");   // set variable for duration of cached content   $offset = 60 * 60;   // set variable specifying format of expiration header   $expire = "expires: " . gmdate ("D, d M Y H:i:s", time() + $offset) . " GMT";   // send cache expiration header to the client broswer   header ($expire);?>

Also add following lines in your htaccess file.

<FilesMatch "\.(js)">    ForceType application/x-httpd-php	php_value auto_prepend_file "/the/full/path/of/this/file/gzip-js.php"</FilesMatch>

Do you know other methods of compressing the output of PHP/JS/CSS files? Let me know, I will try to add them in this tutorial.Happy Compressing :)

As some of you may know, I am currently working on a content management system. Although I am not able to share all of the code – it is proprietary after all – I already made one debugging tool public. This tool can be used to test some common techniques which decreases the bandwidth generated by feed consumers. Today I am going to make a second tool public – including source code. It is a method to decrease the loading time of a page by combining all the different css or javascript files and compress them.About six months ago I noticed the pages generated by the content management system were in itself very clean and small, but that these pages still took a long time to load for new visitors. Even on a fast internet connection it took more than 8 seconds to load a basically empty page. The server generated the page in about 350ms, so that wasn’t the problem. The problem turned out to be a combination of two things: each page used more than 12 different css files because each plugin supplied its own css definitions and because the use of the rather large prototype and scriptaculous javascript libraries which also consists of a couple of different files. Now that an article about the same problem featured on the Yahoo! User Interface blog, I decided to make my solution public, so others can benefit from it.The solution turned out the be simple, combine all the different files into a single large file and compress that file using gzip. Unfortunately, if you do this manually you are going to run into maintenance problems. That single compressed file is no longer editable. So after editing one of the original source files you will have to recombine it with the other files and re-compress it.Instead of going for the easy – but hard to maintain – solution I decided to automate the process and thanks to a small PHP script and some clever URL rewriting I now have an easy to maintain method to speed up the loading of pages that use many or large css and javascript files.The idea is that you have one directory for css files and one directory for javascript files on your server. If you rewrite the URLs that point to these directories to a small script that intercepts the requests for those files. The script loads the file from disk and compresses it using gzip. It then sends that compressed file back to the browser. Given that javascript and css files compress really well this will greatly decrease the size of the data that is going to be transferred and thus decrease the time needed to download these files. Because this works completely transparently you do not need to change anything in your existing code.But there is more. Compressing the files will decrease the size of the data that needs to be transferred, it does not solve the problem that the browser can only download a limited number of files at the same time. If you have many different files that need to be loaded the browser will not optimally use the bandwidth it has access to. It will request some files from the server and wait until those files are retrieved before the rest of the files are requested. The solution to this problem is to combine all those different files into one large file. And this is exactly what the script tries to do. You can concatenate different files by simply adding the names of the other files to the URL of the first file.

Take for example the following URLs:
http://www.creatype.nl/javascript/prototype.js
http://www.creatype.nl/javascript/builder.js
http://www.creatype.nl/javascript/effects.js
http://www.creatype.nl/javascript/dragdrop.js
http://www.creatype.nl/javascript/slider.js

You can combine all these files to a single file by simply changing the URL to:
http://www.creatype.nl/javascript/prototype.js,builder.js,effects.js,dragdrop.js,slider.js

The script will intercept the attempt to retrieve something from the javascript directory and will notice that you want to fetch multiple files at once. It will then concatenate the requested files, compress it and send it as one to the browser. Also notice that I include the files that come with scriptaculous manually and I do not use the scriptaculous.js file like you normally would. The reason for this is that scriptaculous.js loads each javascript file individually. If I use the scriptaculous.js file I will get the benefit of compression, but the different files won’t be combined into a single file.Unfortunately I noticed a nasty side effect of the combination of these two methods. If you combine many files the resulting files can be come quite large. Compressing those files takes some time and on a busy server that time will become large enough to negate a significant portion of the improvements you made earlier. But this problem can also be solved by simply adding a cache that stores an already combined and compressed version of the files. The cached version is automatically created the first time that particular combination of files is used and used every time – as long as the files are not changed. The result is that once the cache is created there is almost no overhead and the compressed file is delivered almost instantly.I’ve done some informal testing on my own website and I did get some impressive results. Before this script was added to my website you needed to download 8 javascript files, in total 168 Kb – the prototype and scriptaculous libraries. On average this took about 1905 ms. After installing this script you now need to download only a single file of 37 Kb which only takes around 400 ms. Your results may vary of course, but given that it shaved 1.5 seconds of a total loading time of 3.5 seconds, this script almost cut the time needed to load a page on my weblog in two.Configurating this script is easy. First you need to download and configure the combine.php script. By default this script look in the javascript and css directory in the root of your website, but if you are currently using different directories you can change these values at the top of the combine.php script. Upload the combine.php script to the root of your website. Secondly you need to create a cache directory that is writable by the web server. Again, by default this script will look for the cache directory in the root of the website, but you can change this in the combine.php script. Finally you need to create or modify your .htaccess file. If you do not have a .htaccess file you can create it in the root of your website and add the following lines. If you already have an preexisting .htaccess file you can simply add the following lines to the file:

RewriteEngine On
RewriteBase /
RewriteRule ^css/(.*\.css) /combine.php?type=css&files=$1
RewriteRule ^javascript/(.*\.js) /combine.php?type=javascript&files=$1

Note: if your preexisting .htaccess file already uses URL rewriting you do not need to add the first two lines. You can simply add the last two lines to the bottom of the .htaccess file.

Serving JavaScript Fast

With our so-called “Web 2.0″ applications and their rich content and interaction, we expect our applications to increasingly make use of CSS and JavaScript. To make sure these applications are nice and snappy to use, we need to optimize the size and nature of content required to render the page, making sure we’re delivering the optimum experience. In practice, this means a combination of making our content as small and fast to download as possible, while avoiding unnecessarily refetching unmodified resources.This is complicated a little by the nature of CSS and JavaScript resources. In contrast to image assets, CSS and JavaScript source code is very likely to change many times as time goes by. When these resources change, we need our clients to download them all over again, invalidating the version in their local cache (and any versions stored in other caches along the way). In this article, we’ll look at ways we can make the whole experience as fast as possible for our users – the initial page load, subsequent page loads and ongoing resource loading as the application evolves and content changes.I believe strongly in making things as simple as possible for developers, so we’ll also be looking at ways we can set up our systems to automatically take care of these optimization issues for us. With a little up front work, we can get the best of both worlds – an environment that makes development easy with great end-user performance – all without changing the way we work.

Monolith

The old school of thought was that we could achieve optimal performance by combining multiple CSS and JavaScript files into fewer, larger blocks. Rather than having ten 5k JavaScript files, we combine them into a single 50k file. While the total size of the code is still the same, we avoid having the overhead associated with multiple HTTP requests. Each request has a setup and teardown phase on both the client and server, incurs request and response header size overhead, and resource overhead on the server side in the form of more processes or threads (and perhaps more CPU time for on-the-fly gzipped content).The parellization aspect is also important. By default, both Internet Explorer and Mozilla/Firefox will only download two resources from a single domain at once when using persistent connections (as suggested in the HTTP 1.1 spec, section 8.1.4). This means that while we’re waiting to download those JavaScript files, 2 at a time, we’re not loading image assets – the page our users see during the loading phase will be missing its images.However, there are a couple of downsides to this approach. By bundling all of our resources together, we force the user to download everything up front. By chunking content into multiple files we can spread out the cost of loading across several pages, amortizing the speed hit across a session (or avoiding some of the cost completely, depending on the path the user chooses). If we make the first page slow to speed up subsequent pages, we might find that we have more users who never wait around to request a second page.The big downside to the single file approach has not often, historically, been considered. In an environment where we will have to often change our resources, any changes to a single-file system will require the client to re-download a copy of the entire CSS or JavaScript working set. If our application has a single monolithic 100k JavaScript source file, any tiny change to our code will force all clients to suck down the 100k all over again.

A splintered approach

The alternative approach lies somewhere in the middle – we split our CSS and JavaScript resources into multiple sub-files, while at the same time keeping that number functionally low. This compromise comes at a cost – we need to be able to develop applications with our code split out into logical chunks to increase development efficiency, while delivering merged files for performance. With a few additions to our build system (the set of tools which turn your development code into production code, ready for deployment), this needn’t be a compromise we have to make.For an application environment with distinct development and production environments, you can use a few simple techniques to keep your code manageable. In your development environment, code can be split into many logical components to make separation clear. In Smarty (A PHP templating language) we can create a simple function to manage the loading of our JavaScript:

SMARTY:{insert_js files="foo.js,bar.js,baz.js"}
PHP: function smarty_insert_js($args){
  foreach (explode(',', $args['files']) as $file){
      echo "<script type=\"text/javascript\" src=\"/javascript/$file\"></script>\n";
  }
}
OUTPUT:<script type="text/javascript" src="/javascript/foo.js"></script><script type="text/javascript" src="/javascript/bar.js"></script><script type="text/javascript" src="/javascript/baz.js"></script>

So far, so easy. But then we instruct our build process to merge certain files together into single resources. In our example, imagine we merged foo.js and bar.js into foobar.js, since they are nearly always loaded together. We can then record this fact in our application configuration and modify our template function to use this information.

SMARTY:{insert_js files="foo.js,bar.js,baz.js"}

PHP:# map of where we can find .js source files after the build process# has merged as necessary
$GLOBALS['config']['js_source_map'] = array(
   'foo.js'	=> 'foobar.js',
   'bar.js'	=> 'foobar.js',
   'baz.js'	=> 'baz.js',
);
function smarty_insert_js($args){
  if ($GLOBALS['config']['is_dev_site']){
    $files = explode(',', $args['files']);
  }else{
    $files = array();
    foreach (explode(',', $args['files']) as $file){
      $files[$GLOBALS['config']['js_source_map'][$file]]++;
    }
    $files = array_keys($files);
  }
  foreach ($files as $file){
   echo "<script type=\"text/javascript\" src=\"/javascript/$file\"></script>\n";
  }
}
OUTPUT:<script type="text/javascript" src="/javascript/foobar.js"></script><script type="text/javascript" src="/javascript/baz.js"></script>

The source code in our templates doesn’t need to change between development and production, but allows us to keep files separated while developing and merged in production. For bonus points, we can write our merging process in PHP and use the same configuration block to perform the merge process, allowing us to keep a single configuration file and avoid having to keep anything in sync. For super-bonus points, we could analyze the occurrence of scripts and style sheets together on pages we serve, to determine which files would be best to merge (files that nearly always appear together are good candidates for merging).For CSS, a useful model to start from is that of a master and subsection relationship. A single master style sheet controls style across your entire application, while multiple sub-sheets control various distinct feature areas. In this way, most pages will load only two sheets, one of which is cached the first time any page is requested (the master sheet).For small CSS and JavaScript resource sets, this approach may be slower for the first request than a single large resource, but if you keep the number of components low then you’ll probably find it’s actually faster, since the data size per page is much lower. The painful loading costs are spread out around different application areas, so the number of parallel loads is kept to a minimum while also keeping the resources-per-page size low.

Compression

When talk about asset compression, most people think immediately of mod_gzip. Beware, however – mod_gzip is actually evil, or at the least, a resource hogging nightmare. The idea behind it is simple – browsers request resources and send along a header to show what kind of content encodings they accept. It looks something like this:

Accept-Encoding: gzip,deflate

When a server encounters this header, it can then gzip or deflate (compress) the content it’s sending to the client, where the client will then decompress it. This burns CPU time on both the client and server, while reducing the amount of data transferred. All well and good. The way mod_gzip works, however, is to create a temporary file on disk in which to compress the source data, serve that file out, then delete it. For high volume systems, you very quickly become bound by disk IO. We can avoid this by using mod_deflate instead (Apache 2 only), which does all the compression in memory – sensible. For Apache 1 users, you can instead create a RAM disk and have mod_gzip writes its temporary files there – not quite as fast as pure in-memory compression, but not nearly as slow as writing to disk.Even so, we can avoid the compression overhead completely by pre-compressing the relevant static resources and using mod_gzip to serve people the compressed version where appropriate. If we add this compression into our build process, it all happens transparently to us. The number of files that need compressing is typically quite low – we don’t compress images since we don’t gain much, if any, size benefit (since they’re already compressed) so we only need to compress our JavaScript and CSS (and any other uncompressed static content). Configuration options tell mod_gzip where to look for pre-compressed files.

mod_gzip_can_negotiate Yes mod_gzip_static_suffix	.gzAddEncoding	gzip	.gz

Newer versions of mod_gzip (starting with version 1.3.26.1a) can pre-compress files for you automatically by adding a single extra configuration option. You’ll need to make sure that Apache has the correct permissions to create and overwrite the gzipped files for this to work.

mod_gzip_update_static	Yes

However, it’s not that simple. Certain versions of Netscape 4 (specifically 4.06 to 4.08) identify themselves as being able to interpret gzipped content (they send a header saying they do), but they cannot correctly decompress it. Most other versions of Netscape 4 have issues with loading compressed JavaScript and CSS in different and exciting ways. We need to detect these agents on the server side and make sure they get served an uncompressed version. This is fairly easy to work around, but Internet Explorer (versions 4 through 6) has some more interesting issues. When loading gzipped JavaScript, Internet Explorer will sometimes incorrectly decompress the resource, or halt compression halfway through, presenting half a file to the client. If you rely on your JavaScript working, you need to avoid sending gzipped content to Internet Explorer. In the cases where Internet Explorer does receive gzipped JavaScript correctly, some older 5.x versions won’t cache the file, regardless of it’s e-tag headers.Since gzip compression of content is so problematic, we can instead turn our attention to compressing content without changing its format. There are many JavaScript compression scripts available, most of which use a regular expression driven rule set to reduce the size of JavaScript source. There are several things which can be done to make the source smaller – removing comments, collapsing whitespace, shortening privately scoped variable names and removing optional syntax.Unfortunately, most of these scripts either obtain a fairly low compression rate, or are destructive under certain circumstances (or both). Without understanding the full parse tree, it’s difficult for a compressor to distinguish between a comment and what looks like a comment inside a quoted string. Adding closures to the mix, it’s not easy to find which variables have a private lexical scope using regular expressions, so some variable name shortening techniques will break certain kinds of closure code.One compressor does avoid this fate – the Dojo Compressor (there’s a ready-to-use version here) works by using Rhino (Mozilla’s JavaScript engine implemented in Java) to build a parse tree, which it then reduces before serializing it to a file. The Dojo Compressor can give pretty good savings for a low cost – a single compression at build time. By building this compression into our build process, it all happens transparently for us. We can add as much whitespace and as many comments as we like to our JavaScript in our development environment, without worrying about bloating our production code.Compared to JavaScript, CSS is relatively simple to compress. Because of a general lack of quoted strings (typically paths and font names) we can mangle the whitespace using regular expressions. In the cases where we do have quoted strings, we can nearly always collapse a whitespace sequence into a single space (since we don’t tend to find multiple spaces or tabs in URL paths or font names). A simple Perl script should be all we need:

#!/usr/bin/perlmy
$data = '';
open F, $ARGV[0] or die "Can't open source file: $!";
$data .= $_ while <F>;
close F;
$data =~ s!\/\*(.*?)\*\/!!g;
# remove comments
$data =~ s!\s+! !g;
# collapse space
$data =~ s!\} !}\n!g;
# add line breaks
$data =~ s!\n$!!;
# remove last break
$data =~ s! \{ ! {!g;
# trim inside brackets
$data =~ s!; \}!}!g;
# trim inside bracketsprint
$data;

We can then feed individual CSS files through the script to compress them like so:

perl compress.pl site.source.css > site.compress.css

With these simple plaintext optimizations we can reduce the amount of data sent over the wire by as much as 50% (depending upon your coding style – it might be much less), which can translate to a much faster experience for our users. But what we’d really like to do is avoid users having to even request files unless completely necessary – and that’s where an intimate knowledge of HTTP caching comes in handy.

Caching is your friend

When a user agent requests a resource from a server for the first time, it caches the response to avoid making the same request in the future. How long it stores this response for is influenced by two factors – the agent configuration and any cache control response headers from the server. All browsers have subtly different configuration options and behaviors, but most will cache a given resource for at least the length of a session, unless explicitly told otherwise.It’s quite likely you already send out anti-caching headers for dynamic content pages to avoid the browser caching pages which constantly change. In PHP, you can achieve this with a pair of function calls:

<?php
header("Cache-Control: private");
header("Cache-Control: no-cache", false);
?>

Sounds too easy? It is – some agents will ignore this header under certain circumstances. To really convince a browser not to cache a document, you’ll need to be a little more forceful:

<?php
# 'Expires' in the past
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
# Always modified
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
# HTTP/1.1
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
# HTTP/1.0
header("Pragma: no-cache");
?>

This is fine for content we don’t want to be cached, but for content that doesn’t change with every request we want to encourage the browser to cache it aggressively. The “If-Modified-Since” request header allows us to get part of the way there. If a client sends an “If-Modified-Since” header with its request, Apache (or your web server of choice) can respond with status code 304 (”Not Modified”), telling the browser that its cached copy of the file is already up to date. With this mechanism, we can avoid sending the contents of a file to the browser, but we still incur the overhead of an HTTP request. Hmmm.Similar to the if-modified-since mechanism are entity tags. Under Apache, each response for a static resource is given an “ETag” header containing a checksum generated from the file’s modified-time, size and inode number. A browser can then perform a HEAD request to check the e-tag for a resource without downloading it. E-tags suffer from the same problem as the if-modified-since mechanism – the client still needs to perform an HTTP request to determine the validity of the locally cached copy.In addition, you need to be careful with if-modified-since and e-tags if you serve content from multiple servers. With two load-balanced web servers, a single resource could be requested from either server by a single agent – and could be requested from each at different times. This is great – it’s why we load balance. However, if the two servers generate different e-tags or modified dates for the same files, then browsers won’t be able to properly cache content. By default, e-tags are generated using the inode number of the file, which will vary from server to server. You can turn this off using a single Apache configuration option:

FileETag MTime Size

With this option, Apache will use only the modification time and file size to determine the e-tag. This, unfortunately, leads us to the other problem with e-tags, which can affect if-modified-since too (though not nearly as badly). Since the e-tag relies on the modified time of the file, we need those times to be in sync. If we’re pushing files to multiple web servers, there’s always a chance that the time at which the files are pushed are subtly different by a second or two. In this case, the e-tags generated by two servers will still be different. We could change the configuration to generate e-tags only from the file size, but this means that we’ll generate the same e-tag if we change a file’s contents without changing its size. Not ideal.

Caching is your best friend

The problem here is that we are approaching the issue from the wrong direction. These possible caching strategies all revolve around the client asking the server if its cached copy is fresh. If we could notify the client when we change a file, it would know that its own cached copy was fresh, until we told it otherwise. But the web doesn’t work that way – the client makes requests to the server.But that’s not quite true – before fetching any JavaScript or CSS files, the client makes a request to the server for the page which will be loading those files via <script> or <link> tags. We can use the response from the server to notify the client of any changes in those resources. This is all a little cryptic, so let’s spell it out – if we change the filenames of JavaScript and CSS files when we change their contents, we can tell the client to cache every URL forever, since the content of any given URL will never change.If we are sure that a given resource will never change, then we can send out some seriously aggressive caching headers. In PHP, we just need a couple of lines:

<?php
header("Expires: ".gmdate("D, d M Y H:i:s", time()+315360000)." GMT");
header("Cache-Control: max-age=315360000");
?>

Here we tell the browser that the content will expire in 10 years (there are 315,360,000 seconds in 10 years, more or less) and that it can keep it around for 10 years. Of course, we’re probably not serving our JavaScript and CSS via PHP – we’ll address that in a few moments.

Mistakes abound

Manually changing the filenames of resources when the contents are modified is a dangerous task. What happens if you rename the file, but not the templates pointing to it? What happens if you change some templates but not others? What happens if you change the templates but don’t rename the file? Most likely of all, what happens if you modify a resource but forget to rename it or change any references to it. In the best of these cases, users will not see the new content and be stuck with the old versions. In the worst case, no valid resource is found and your site stops working. This sounds like a dumb idea.Luckily computers are really good at this sort of thing – dull repetitive tasks which need to be done exactly right, over and over again, when some kind of change occurs.The first step in making this process as painless as possible is to realize that we don’t need to rename files at all. URLs we serve content from and where the content is located on disk don’t have to have anything to do with each other. Using Apache’s mod_rewrite we can create a simple rule to redirect certain URLs to certain files.

RewriteEngine onRewriteRule ^/(.*\.)v[0-9.]+\.(css|js|gif|png|jpg)$	/$1$2	[L]

This rule matches any URL with one of the specified extensions which also contains a ‘version’ nugget. The rule then rewrites these URLs to a path without the version nugget. Some examples:

URL			   Path
/images/foo.v2.gif	-> /images/foo.gif
/css/main.v1.27.css	-> /css/main.css
/javascript/md5.v6.js	-> /javascript/md5.js

With this rule in-place, we can change the URL (by changing the version number) without changing where the file lives on disk. Because the URL has changed, the browser treats it as a different resource. For bonus points, you can combine this with the script grouping function from earlier to produce a list of versioned <script> tags as needed.At this point, you might ask why we don’t just add a query string to the end of the resource – /css/main.css?v=4. According the letter of the HTTP caching specification, user agents should never cache URLs with query strings. While Internet Explorer and Firefox ignore this, Opera and Safari don’t – to make sure all user agents can cache your resources, we need to keep query strings out of their URLs.Now that we can change our URLs without moving the file, it would be nice to be able to have the URLs updated automatically. In a small production environment (or a development environment, for people with large production environments), we can do this really easily using a template function. This example is for Smarty, but applies equally well to other templating engines.

SMARTY:<link href="{version src='/css/group.css'}" rel="stylesheet" type="text/css" />
PHP: function smarty_version($args){
  $stat = stat($GLOBALS['config']['site_root'].$args['src']);
  $version = $stat['mtime'];
  echo preg_replace('!\.([a-z]+?)$!', ".v$version.\$1", $args['src']);
}
OUTPUT:<link href="/css/group.v1234567890.css" rel="stylesheet" type="text/css" />

For each linked resource, we determine the file’s location on disk, check its mtime (the date and time the file was last modified on disk) and insert that into the URL as the version number. This works great for low traffic sites (where stat operations are cheap) and for development environments, but it doesn’t scale well to high volume deployments – each call to stat requires a disk read.The solution is fairly simple. In a large system we already have a version number for each resource, in the form of the source control revision number (you’re already using source control, right?). At the point when we go to build our site for deployment, we simply check the revision numbers of all of our resource files and write them to a static configuration file.

<?php
$GLOBALS['config']['resource_versions'] = array(
  '/images/foo.gif'    => '2.1',
  '/css/main.css'      => '1.27',
  '/javascript/md5.js' => '6.1.4',
);?>

We can then modify our templating function to use these version numbers when we’re operating in production.

<?php
function smarty_version($args){
  if ($GLOBALS['config']['is_dev_site']){
    $stat = stat($GLOBALS['config']['site_root'].$args['src']);
    $version = $stat['mtime'];
  }else{
    $version = $GLOBALS['config']['resource_versions'][$args['src']];
  }
  echo preg_replace('!\.([a-z]+?)$!', ".v$version.\$1", $args['src']);
}
?>

In this way, we don’t need to rename any files, or even remember when we modify resources – the URL will be automatically changed everywhere whenever we push out a new revision – lovely. We’re almost where we want to be.

Bringing it all together

When we talked about sending very-long-period cache headers with our static resources earlier, we noted that since this content isn’t usually served through PHP, we can’t easily add the cache headers. We have a couple of obvious choices for dealing with this; inserting PHP into the process or letting Apache do the work.Getting PHP to do our work for us is fairly simple. All we need to do is change the rewrite rule for the static files to be routed through a PHP script, then have the PHP script output headers before outputting the content of the requested resource.

Apache: RewriteRule ^/(.*\.)v[0-9.]+\.(css|js|gif|png|jpg)$  /redir.php?path=$1$2  [L]
PHP:
header("Expires: ".gmdate("D, d M Y H:i:s", time()+315360000)." GMT");
header("Cache-Control: max-age=315360000");
# ignore paths with a '..'
if (preg_match('!\.\.!', $_GET[path])){
 go_404();
}
# make sure our path starts with a known directory
if (!preg_match('!^(javascript|css|images)!', $_GET[path])){
 go_404();
}
# does the file exist?
if (!file_exists($_GET[path])){
 go_404();
}
# output a mediatype header
$ext = array_pop(explode('.', $_GET[path]));
switch ($ext){
  case 'css':
    header("Content-type: text/css");
    break;
  case 'js' :
    header("Content-type: text/javascript");
    break;
  case 'gif':
    header("Content-type: image/gif");
    break;
  case 'jpg':
    header("Content-type: image/jpeg");
    break;
  case 'png':
    header("Content-type: image/png");
    break;
  default:
    header("Content-type: text/plain");
}
# echo the file's contents
echo implode('', file($_GET[path]));
function go_404(){
  header("HTTP/1.0 404 File not found");
  exit;
}

While this works, it’s not a great solution. PHP demands more memory and execution time than if we did everything in Apache. In addition, we have to be careful to protect against exploits made possible by sending us doctored values for the path query parameter. To avoid all this headache, we can have Apache add the headers directly. The RewriteRule directive allows us to set environment variables when a rule is matched, while the Header directive lets us add headers only when a given environment variable is set. Combining these two directives, we can easily chain the rewrite rule together with the header settings.

RewriteEngine onRewriteRule ^/(.*\.)v[0-9.]+\.(css|js|gif|png|jpg)$ /$1$2 [L,E=VERSIONED_FILE:1]
Header add "Expires" "Mon, 28 Jul 2014 23:30:00 GMT" env=VERSIONED_FILEHeader add "Cache-Control" "max-age=315360000" env=VERSIONED_FILE

Because of Apache’s order of execution, we need to add the RewriteRule line to the main configuration file (httpd.conf) and not a per-directory (.htaccess) configuration file, otherwise the Header lines get run first, before the environment variable gets set. The Header lines can either go in the main configuration file or in an .htaccess file – it makes no difference.

Skinning rabbits

By combining the above techniques, we can build a flexible development environment and a fast and performant production environment. Of course, this is far from the last word on speed. There are further techniques we could look at (separate serving of static content, multiple domain names for increased concurrency) and different ways of approaching the ones we’ve talked about (building an Apache filter to modify outgoing URLs in HTML source to add versioning information on the fly). Tell us about techniques and approaches that have worked well for you by leaving a comment.

Read more

Cal’s new book, Building Scalable Web Sites, contains more tips and tricks to help you develop and manage the next generation of web applications.

Hôm trước đi soi mấy cái optimize thấy bài này cũng được, post lên cho mọi người cùng tham khảo.

There is a lot of whitespace in both stylesheets and JavaScript files. This is because of indented text and line breaks to name a few. They are typically also filled with comments to make them more maintainable. Believe it or not, it all adds up substantially to the overall file size. My tests show that stylesheets can be reduced by more than 30% and JavaScript files by 20%. That’s a lot.

I made two C# classes, which implement the IHttpHandler interface, one for stylesheets and one for JavaScript files. The easiest way to implement them is simply to add this line to the <system.web> section of the web.config.

<httpHandlers>
<add verb=”*” path=”*.js” type=”ScriptHandler” validate=”false”/>
<add verb=”*” path=”*.css” type=”CssHandler” validate=”false”/>
</httpHandlers>

You also have to make sure that the IIS lets the ASP.NET ISAPI filter handle files with .css and .js extensions.

The classes use regular expressions to remove whitespace and comments. Then it caches the cleaned file and adds a dependency to the real .css/.js file on disk. Every time you change the source file, the cache reloads.

In order to remove comments properly, you should use the /*  …  */ syntax and not //. Further more, it can be a problem for the JavaScript handler if a line isn’t closed with a semicolon. Enjoy.

File name: httphandlers.zip
File size:1.95 KB

By Mads Kristensen

Powered by WordPress | Theme: by 85ideas. Editor by Khoanguyen