最近部署了个新的博客主题,并花了些时间来做前端优化,在这过程中有不少收获,也遇到不少问题。现就部分笔者比较感兴趣的点拿出来记录一下。
笔者没有相关知识和技能,主要是按照 YSlow 和 Google PageSpeed 所建议的做,有些项是比较容易出问题的。
减少请求次数
通常的做法是将同类资源合并。例如将多个 JavaScript 脚本合并,将多个 CSS 文件合并,将每个图标一个图片的形式改为 CSS sprites(单个图片,基于背景定位及分割)。
减少 HTTP 传输数据量
A) 启用 HTTP 压缩(Gzip)。B) 压缩(Minify) JavaScript 和 CSS 文件。
正确设置外部资源引入顺序
将 CSS 放在 HTML 的头部,将 JavaScript 放在 HTML 的底部。CSS 用于渲染页面,需要放在前面。而 JavaScript 会阻塞式加载,应该放在最后。
充分利用浏览器缓存
给静态资源加上比较长的过期时间和缓存有效期。设置 ETags(通常 Apache 会自动设置)。
使用 cookie-free 域
静态资源通常都不需要发送和设置 cookie 信息,所以应该使用一个单独的域来做 cookie-free domain。
使用 CDN(Content Delivery Network)
A) 整个站点使用 CDN。这需要较高的成本。
B) 仅公共资源使用 CDN。这是比较通常的做法,可以非常好的利用浏览器缓存,并能分散服务器压力。比如多个网站都使用了 Google CDN 提交的 jQuery.js 时,浏览器仅在第一次访问第一个站点时下载该文件,访问其它站点时,可直接从缓存中获取。
目前有这样一些提供公共资源的CDN:
减少 DNS 查询
使用 Cookie-free 域和使用公共资源 CDN 都会增加整个网站要访问的域的数量,同时也增加了 DNS 查询数,一个 DNS 查询通常需要 20 到 120 毫秒的时间,在 DNS 查询期间浏览器无法下载任何数据。所以 YSlow 建议一个页面的使用的域不要超过 4 个。
较少 DOM 对象数量
保持比较简单的 HTML 结构,减少标签嵌套层次,这样可以增加页面渲染速度。对于负责页面来说优化该项比较有效果,但需要较高的设计水平。
以上优化建议其实需要辩证统一的,因为有些是有矛盾的,笔者就曾主要纠结于与公共资源相关的部分:
笔者最终将 jQuery,Bootstrap 脚本压缩合并到网站的脚本中了,主要是考虑到使用 Google Hosted 的 jQuery 会偶尔抽风。
以下是笔者优化时的 Apache 配置
<IfModule mod_mime.c> # Text AddType text/css .css AddType application/x-javascript .js AddType text/html .html .htm AddType text/richtext .rtf .rtx AddType text/plain .txt AddType text/xml .xml # Image AddType image/gif .gif AddType image/x-icon .ico AddType image/jpeg .jpg .jpeg .jpe AddType image/png .png AddType image/svg+xml .svg .svgz # Video AddType video/asf .asf .asx .wax .wmv .wmx AddType video/avi .avi AddType video/quicktime .mov .qt AddType video/mp4 .mp4 .m4v AddType video/mpeg .mpeg .mpg .mpe # PDF AddType application/pdf .pdf # Flash AddType application/x-shockwave-flash .swf # Font AddType application/x-font-ttf .ttf .ttc AddType application/vnd.ms-fontobject .eot AddType application/x-font-otf .otf AddType application/font-woff .woff # Audio AddType audio/mpeg .mp3 .m4a AddType audio/ogg .ogg AddType audio/wav .wav AddType audio/wma .wma # Zip/Tar AddType application/x-tar .tar AddType application/x-gzip .gz .gzip AddType application/zip .zip </IfModule> <IfModule mod_expires.c> ExpiresActive On # Text ExpiresByType text/css A31536000 ExpiresByType application/x-javascript A31536000 ExpiresByType text/html A3600 ExpiresByType text/richtext A3600 ExpiresByType text/plain A3600 ExpiresByType text/xml A3600 # Image ExpiresByType image/gif A31536000 ExpiresByType image/x-icon A31536000 ExpiresByType image/jpeg A31536000 ExpiresByType image/png A31536000 ExpiresByType image/svg+xml A31536000 # Video ExpiresByType video/asf A31536000 ExpiresByType video/avi A31536000 ExpiresByType video/quicktime A31536000 ExpiresByType video/mp4 A31536000 ExpiresByType video/mpeg A31536000 # PDF ExpiresByType application/pdf A31536000 # Flash ExpiresByType application/x-shockwave-flash A31536000 # Font ExpiresByType application/x-font-ttf A31536000 ExpiresByType application/vnd.ms-fontobject A31536000 ExpiresByType application/x-font-otf A31536000 ExpiresByType application/font-woff A31536000 # Audio ExpiresByType audio/mpeg A31536000 ExpiresByType audio/ogg A31536000 ExpiresByType audio/wav A31536000 ExpiresByType audio/wma A31536000 # Zip/Tar ExpiresByType application/x-tar A31536000 ExpiresByType application/x-gzip A31536000 ExpiresByType application/zip A31536000 </IfModule> <FilesMatch "\.(?i:css|js|htm|html|rtf|rtx|txt|xml|gif|ico|jpg|jpeg|jpe|png|svg|svgz|asf|asx|wax|wmv|wmx|avi|mov|qt|mp4|m4v|mpeg|mpg|mpe|pdf|swf|ttf|ttc|eot|otf|woff|mp3|m4a|ogg|wav|wma|tar|gz|gzip|zip)$"> <IfModule mod_headers.c> Header set Pragma "public" Header append Cache-Control "public, must-revalidate, proxy-revalidate" Header unset ETag </IfModule> </FilesMatch> <FilesMatch "\.(?i:css|js|gif|ico|jpg|jpeg|jpe|png|pdf|swf|ttf|ttc|eot|otf|woff)$"> <IfModule mod_headers.c> Header unset Set-Cookie </IfModule> </FilesMatch> <FilesMatch "\.(?i:ttf|ttc|eot|otf|woff)$"> <IfModule mod_headers.c> Header set access-control-allow-origin "SOMEDOMAIN or *" </IfModule> </FilesMatch> <IfModule mod_deflate.c> SetOutputFilter DEFLATE SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|iso|tar|bz2|sit|rar)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|jpg|ico|png)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.flv$ no-gzip dont-vary BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html Header append Vary User-Agent env=!dont-vary </IfModule>
如上一篇文章提到的,Web Fonts 似乎越来越流行了,而且不仅仅用做字体,还有个主要的用途就是图标。将字体用作图标有很多便利,比如可以随意调整大小而不会失真(因为字体是矢量的),可以随意设置颜色等。当前博客的部分图标就是基于自定义字体的。
说道自定义字体,不得不说说 IcoMoon App 这个超牛的工具。通过这个工具,你可以在线选择你需要的图标,然后生成 CSS Sprites 的图片或者生成 Web Fonts 下载,下载包中已经包含了定义好的 CSS 和实例 HTML 文件。此外,你还可以上传自己的 SVG 或者其它图片文件, IcoMoon App 会自动转成 CSS Sprites 或者 Web Fonts。
上面的这个图标,实质上是一个字符,就是通过 Web Fonts 定义的。
<i class="opoo-opooorg" style="font-size:36px;color:blue;"></i>
Source |
|