来源:GBin1.comcss
回 想一下,之前咱们不得不花费大量时间去优化页面内容(图片、CSS等等),现在用户有更快速的互联网连接,咱们彷佛可以使用更大的图像或更大的闪 存文件,里面包含的有视频或者图片。然而,随着移动开发的兴起,咱们又回到了过去的窘状。网站优化是十分重要的,须要下载的内容少,反应速度快,就能使我 们加载应用程序更快速。html
图片:控制在合适的尺寸大小前端
不少时候咱们在不一样的网站使用一样的图像,例如一个网上商店,全部产品 都 有一个概览图片。打个比方,有三个页面描述产品,第一个页面显示产品清单,第二个页面显示产品细节图,第三个页面显示产品原始大小图。所以,咱们须要三种 不一样大小的图片。若是使用一个文件放到不一样的三个页面上,那么浏览器会自动加载完整大小的图片,就连清单页也是,实际上清单页只须要200×200尺寸的 图片。若是原始文件大小在1MB左右,每页上有十个产品介绍,那么用户就要下载10MB大小的资源。这样作效果很差。若是能够的话,尽可能为你的网站不一样位 置分配不一样的图像文件,那么就可让用户少下载资源。把屏幕分辨率因素也考虑进去也是很好的。若是有人用iPhone打开你的网站页面,手机上不须要显示 电脑上那么大尺寸的图片,只需适应手机屏幕的大小就能够了。经过CSS Media Queries,你就能将图像压缩到较小尺寸发送出去了:git
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) { .header { background-image: url(../images/background_400x200.jpg); } }
传送图像的时候单单控制适当的尺寸每每是不够的。很多文件格式在不失真的前提下能够被压缩不少。有一类应用程序能够达到这个效果。好比Photoshop有个很好的功能叫作Save for Web and Devices:github
在此对话框中有多个选项,其中最重要的是质量,将其设计为80%左右,就能显著减小文件大小了。固然,你还可使用代码来压缩文件,但我我的偏向于使用PS。下面是用PHP编写的一个简单的例子:web
function compressImage($source, $destination, $quality) { $info = getimagesize($source); switch($info['mime']) { case "image/jpeg": $image = imagecreatefromjpeg($source); imagejpeg($image, $destination, $quality); break; case "image/gif": $image = imagecreatefromgif($source); imagegif($image, $destination, $quality); break; case "image/png": $image = imagecreatefrompng($source); imagepng($image, $destination, $quality); break; } } compressImage('source.png', 'destination.png', 85);
增长应用程序性能的方法之一,是减小到服务器的请求数。每个新图像表明一个请求数。有一个办法是将几个图片合并成一个,合并以后的图像叫作一个sprite,在CSS中改变背景层的位置,就能准确的把特定部分的图像显示出来。好比Twitter Bootstrap利用sprites引导内部图标:npm
在CSS中,你能够参照如下方式,显示你喜欢的sprite部分: 编程
.icon-edit { background-image: url("../img/glyphicons-halflings-white.png"); background-position: -96px -72px; }
浏览器超高速缓存十分好用。尽管有时在开发过程当中会致使一些很是有趣的状况,但它确实有助于提升你的网站的性能。全部浏览器的超高速缓存下来的内容包括图片、JavaScript或者CSS。有几种方法能够控制缓存,建议你阅读相关文章。通常状况下,你能够经过设置标题,达到控制效果:json
$expire = 60 * 60 * 24 * 1;// seconds, minutes, hours, days header('Cache-Control: maxage='.$expire); header('Expires: '.gmdate('D, d M Y H:i:s', time() + $expire).' GMT'); header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
HTML 5天天都在进步,有一个很好的功能叫作预读取,它让浏览器提早下载你立刻须要用到的资源:bootstrap
<link rel="prefetch" href="/images/background.jpg">
数据URI方案/内联图像
几年前我曾开发了一个简单的网页,只包含一个HTML文件夹,但固然里面应该还包括一些我须要的图像。数据URI方案帮助我解决了问题。咱们的想法是将图像转换成一个base64编码的字符串,并将其放置在src属性中的img标签里,例如:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
经过这种方法,你的图像实际上在HTML中并保存了一个HTTP请求。你的图像越大的话,字符串就越长。下面是一个简单的PHP脚本图像转换为base64字符串的实例:
$picture = fread($fp,filesize($file)); fclose($fp); // base64 encode the binary data, then break it // into chunks according to RFC 2045 semantics $base64 = base64_encode($picture); $tag = '<img src="data:image/jpg;base64,'.$base64.'" alt="" />'; $css = 'url(data:image/jpg;base64,'.str_replace("\n", "", $base64).'); ';
有些状况下这种方法挺好用的,但请注意,在IE浏览器中没法很好的兼容。
我 以为编写CSS就如同写代码。你一样须要组织模式,定义不一样板块和关系。因此我认为CSS管理很是重要。应用程序的每一部分应该有对应的模式,并很好的独 立。不一样的内容存储在不一样的文件夹能够有效的管理,但一样也存在问题。使用@import状态这种方法很差用,由于每用一个@import都意味着一个新 的请求发送到服务器。若是你有20个不一样的.css文件,就至关于浏览器要发送20个请求。浏览器在渲染/下载全部内容以前不会显示页面。若是你 的.css文件丢失了或者太大,浏览器加载页面的时间就会大大延长。
使用CSS预处理器
CSS预处理器能够解决上述问题。你 一样能够保存不一样的文件夹,预处理器能够将这些散文件夹最终生成一个.css文件。实际上提供了一系列很是帮的功能好比变量、嵌套块、混入和继承。代码看 上去相似CSS,但实际上被很好的统一格式与结构了。有几种好用的预处理器值得体验——Sass、LESS、Stylus。下面是用LESS编写的例子:
.position(@top: 0, @left: 0) { position: absolute; top: @top; left: @left; text-align: left; font-size: 24px; } .header { .position(20px, 30px); .tips { .position(10px, -20px); } .logo { .position(10px, 20px); } }
运行生成:
.header { position: absolute; top: 20px; left: 30px; text-align: left; font-size: 24px; } .header .tips { position: absolute; top: 10px; left: -20px; text-align: left; font-size: 24px; } .header .logo { position: absolute; top: 10px; left: 20px; text-align: left; font-size: 24px; }
又如你想再建立一个一样样式的按钮,可是颜色不一样,你能够这样作:
.button { border: solid 1px #000; padding: 10px; background: #9f0; color: #0029FF; } .active-button { .button(); color: #FFF; }
一般状况下,大多数开发人员没有考虑过CSS效率问题。CSS的效率反映在页面渲染上,若是模式低效,应用程序在浏览器上运行就会很慢。有趣的是浏览器解析CSS选择器是从右到左的。因此如下代码更不一点效率都没有:
body ul li a { color: #F000; text-decoration: none; }
这是由于该引擎首先识别全部的<a>标签,评估每一个母元素,最终收集到所需模式。你要知道,为了提升效率,选择器有个 前后排序:ID、类、标签及其通常。这意味着一个带有id的元素集比只带有标签选择器的元素更快的被渲染。固然,在全部DOM树元素都加上id是没有意义 的,但你应该特定检查代码,把可能加id的地方都加上。好比你能够按照如下方式作:
ul #navigation li {
background: #ff0232;
}
.content元素是body tag的子集,实际上全部元素都是body tag的子集。关于这个话题有两个有用的连接:developers.google.com和css-tricks.com。
文件大小
正如咱们上面提到的,代码越少越好,由于浏览器在加载CSS以前不渲染页面。下面几个技巧可供缩小文件大小:
把相似的行
.header { font-size: 24px; } .content { font-size: 24px; }
转换成
.header, .content { font-size: 24px; }
用速记,而不是如下
.header { background-color: #999999; background-image: url(../images/header.jpg); background-position: top right; }
用下面的风格编写
.header { background: #999 url(../images/header.jpg) top right; }
缩减代码,也就是使用一个工具除去全部空间和线,可使用CSSOptimiser或Minifycss。常见作法是在应用程序服务器端使用这种工具。也就是在后端写的语言。一般状况相爱这些组件能够缩减你的代码。
将你的CSS文件放在<head>标签下
将你的CSS文件放在head标签下是很好的方法,浏览器会首先下载它们。
减小HTTP请求数量
与CSS状况同样,减小服务器请求是有利的。大多数状况下,加载JavaScript文件的同时不会中止渲染页面,但会形成页面某些部分失去做用。
缩减代码
有些小工具能够缩减JavaScript,使文件大小减少了,但要记住在开发环境中,保持代码整洁是十分必要的。这些工具几乎都会改变变量名称,并转换成一个单行的字符串,这个过程不可能调试。
JavaScript自己并无一个机制来管理模数,所以,这些工具是为了解决这个问题的。他们提供一个应用程序接口,你能够定义和使用模数。例如http://requirejs.org/:
<!DOCTYPE html>
<html>
<head>
<title>My Sample Project</title>
<!-- data-main attribute tells require.js to load
scripts/main.js after require.js loads. -->
<script data-main="scripts/main" src="scripts/require.js"></script>
</head>
<body>
<h1>My Sample Project</h1>
</body>
</html>
运行脚本,你能够用require()代替main.js
require(["helper/util"], function(util) { //This function is called when scripts/helper/util.js is loaded. //If util.js calls define(), then this function is not fired until //util's dependencies have loaded, and the util argument will hold //the module value for "helper/util". });
使用名字空间
提到代码组织,必然要提到命名空间的部分。本来在JavaScript中是没有这个功能的,但你能够经过几行代码来实现这个功能。好比,你想达一个MVC框架,就能够用如下方式:
var model = function() { ... }; var view = function() { ... }; var controller = function() { ... };
光有以上代码是不够的,很容易与其余行的代码发生冲突。因此须要按照如下方式将它们做为独立的对象(命名空间)分组,以保护总体框架:
var MyAwesomeFramework = { model: function() { ... }, view: function() { ... }, controller: function() { ... } }
JavasScript之因此很受欢迎是由于里面包含了大量例子。可重复使用的设计模式是编程中常见问题的解决方案。遵循某些设计模式能够帮助你更好的设计应用程序。若是我全都写下来,估计均可以出书了,因此这里只写出一些例子:
用这个模式构建具体对象实例:
var Class = function(param1, param2) { this.var1 = param1; this.var2 = param2; } Class.prototype = { method:function() { alert(this.var1 + "/" + this.var2); } };
或者:
function Class(param1, param2) { this.var1 = param1; this.var2 = param2; this.method = function() { alert(param1 + "/" + param2); }; }; var instance = new Class("value1", "value2");
模块模式可让咱们建立私有和公共方法。好比下面的代码中,变量_index和方法privateMethod是私有的,increment和getIndex是公开的。
var Module = (function() { var _index = 0; var privateMethod = function() { return _index * 10; } return { increment: function() { _index += 1; }, getIndex: function() { return _index; } }; })();
事件的订阅和分派发生的时候就能看到这种模式。观察者对特定对象相关的东西有兴趣,一旦发生动做,就会通知观察者。下面的例子显示咱们如何才能增长用户对象的观察者:
var Users = { list: [], listeners: {}, add: function(name) { this.list.push({name: name}); this.dispatch("user-added"); }, on: function(eventName, listener) { if(!this.listeners[eventName]) this.listeners[eventName] = []; this.listeners[eventName].push(listener); }, dispatch: function(eventName) { if(this.listeners[eventName]) { for(var i=0; i<this.listeners[eventName].length; i++) { this.listeners[eventName][i](this); } } }, numOfAddedUsers: function() { return this.list.length; } } Users.on("user-added", function() { alert(Users.numOfAddedUsers()); }); Users.add("Krasimir"); Users.add("Tsonev");
这种模式能够很好的组织模块的公共接口。节省时间,提升可读性:
var User = { profile: {}, name: function(value) { this.profile.name = value; return this; }, job: function(value) { this.profile.job = value; return this; }, getProfile: function() { return this.profile; } }; var profile = User.name("Krasimir Tsonev").job("web developer").getProfile(); console.log(profile);
我强烈推荐Addy Osmani出的书,它涵盖了JavaScript中设计模式全部最棒的资源。
在 本文结尾的时候,我想分享一些关于服务器上CSS和JavaScript代码管理方面的想法。这是一个经常使用手段来添加合并、缩小、编译成应用程序的逻辑。 时常有种缓存机制,但在程序运行的时候全部事情都在同时发生。就是说你或许有代码的逻辑,同时处理.js或.css文件请求,而后提供适当的内容。这个过 程的背后是汇编、压缩,以及其余。在我最新一个项目中我用到一种叫作Assets-Pack的工具。它很是有用,我能够详尽解释它能作什么,但更有趣的是 我是怎样使用这个工具的。只能用在开发模式中,不是停留在基于代码形式的,也不是在服务器上调配的。
个人想法是运用这个工具只当你在处理 CSS和JS的时候,它能够监视特定目录中的变化,而后把代码编译/打包成为一个单一的文件。经过这个步骤,你不须要再去考虑压缩或者汇编。全部你所要作 的仅仅是将编译后的静态文件发送给用户。这增长了应用程序的性能,由于它只能提供静态文件,这固然让事情变得更简单。你不须要设置任何服务器或实施没必要要 的逻辑。
下面是你如何安装和使用Assets-Pack:
npm install -g assetspack
该模块可与JSON配置,当它经过命令行被调用的时候,你应该把设置放到.json文件中。
经过命令行
建立assets.json文件夹,在同一个目录下执行如下代码:
assetspack
若是你想使用另外一种名称或者换一个目录:
assetspack --config [path to json file]
代码形式的
var AssetsPack = require("assetspack"); var config = [ { type: "css", watch: ["css/src"], output: "tests/packed/styles.css", minify: true, exclude: ["custom.css"] } ]; var pack = new AssetsPack(config, function() { console.log("AssetsPack is watching"); }); pack.onPack(function() { console.log("AssetsPack did the job"); });
配置应该是一个有效的JSON文件/对象,下面只是一个对象数组:
[
(asset object),
(asset object),
(asset object),
...
]
Asset Object
Asset Object的基本结构以下:
{ type: (file type /string, could be css, js or less for example), watch: (directory or directories for watching /string or array of strings/), pack: (directory or directories for packing /string or array of strings/. ), output: (path to output file /string/), minify: /boolean/, exclude: (array of file names) }
pack属性不是强制的,若是丢失了,它的值仍是相等的,默认状况下的缩减是假属性。
下面是一些例子:
Packing CSS
{ type: "css", watch: ["tests/data/css", "tests/data/css2"], pack: ["tests/data/css", "tests/data/css2"], output: "tests/packed/styles.css", minify: true, exclude: ["header.css"] }
Packing JavaScript
{ type: "js", watch: "tests/data/js", pack: ["tests/data/js"], output: "tests/packed/scripts.js", minify: true, exclude: ["A.js"] }
Packing .less Files
Packing .less Files有点不一样,pack属性是强制性的,基于你的切入点。你应当导入全部其余的.less文件。排除属性在这里无效。
{ type: "less", watch: ["tests/data/less"], pack: "tests/data/less/index.less", output: "tests/packed/styles-less.css", minify: true }
若是有其余问题,能够在源代码(GitHub)库中查看tests/packing-less.spec.js
压缩其余格式文件
assets-pack适用于全部文件格式。好比你能够结合HTML模板和一个简单文件,用如下方式:
{ type: "html", watch: ["tests/data/tpl"], output: "tests/packed/template.html", exclude: ["admin.html"] }
有一点须要注意的是这里没有缩小倍率。
结论
做为前端Web开发人员,咱们应该尽可能为的用户提供最佳的性能。上面的提示不该该涵盖全部资产的组织和性能方面的技巧,但它们是经常使用的几种。
via 极客标签