web頁面內容優化管理與性能技巧

來源:GBin1.comcss

web頁面內容優化管理與性能技巧

回 想一下,之前咱們不得不花費大量時間去優化頁面內容(圖片、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

web頁面內容優化管理與性能技巧

在此對話框中有多個選項,其中最重要的是質量,將其設計爲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

增長應用程序性能的方法之一,是減小到服務器的請求數。每個新圖像表明一個請求數。有一個辦法是將幾個圖片合併成一個,合併以後的圖像叫作一個sprite,在CSS中改變背景層的位置,就能準確的把特定部分的圖像顯示出來。好比Twitter Bootstrap利用sprites引導內部圖標:npm

web頁面內容優化管理與性能技巧

在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就如同寫代碼。你一樣須要組織模式,定義不一樣板塊和關係。因此我認爲CSS管理很是重要。應用程序的每一部分應該有對應的模式,並很好的獨 立。不一樣的內容存儲在不一樣的文件夾能夠有效的管理,但一樣也存在問題。使用@import狀態這種方法很差用,由於每用一個@import都意味着一個新 的請求發送到服務器。若是你有20個不一樣的.css文件,就至關於瀏覽器要發送20個請求。瀏覽器在渲染/下載全部內容以前不會顯示頁面。若是你 的.css文件丟失了或者太大,瀏覽器加載頁面的時間就會大大延長。

使用CSS預處理器

CSS預處理器能夠解決上述問題。你 一樣能夠保存不一樣的文件夾,預處理器能夠將這些散文件夾最終生成一個.css文件。實際上提供了一系列很是幫的功能好比變量、嵌套塊、混入和繼承。代碼看 上去相似CSS,但實際上被很好的統一格式與結構了。有幾種好用的預處理器值得體驗——SassLESSStylus。下面是用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的效率反映在頁面渲染上,若是模式低效,應用程序在瀏覽器上運行就會很慢。有趣的是瀏覽器解析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.comcss-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;
}

縮減代碼,也就是使用一個工具除去全部空間和線,可使用CSSOptimiserMinifycss。常見作法是在應用程序服務器端使用這種工具。也就是在後端寫的語言。一般狀況相愛這些組件能夠縮減你的代碼。

將你的CSS文件放在<head>標籤下

將你的CSS文件放在head標籤下是很好的方法,瀏覽器會首先下載它們。

JavaScript

減小HTTP請求數量

與CSS狀況同樣,減小服務器請求是有利的。大多數狀況下,加載JavaScript文件的同時不會中止渲染頁面,但會形成頁面某些部分失去做用。

縮減代碼

有些小工具能夠縮減JavaScript,使文件大小減少了,但要記住在開發環境中,保持代碼整潔是十分必要的。這些工具幾乎都會改變變量名稱,並轉換成一個單行的字符串,這個過程不可能調試。

試試CommonJS, AMD, RequireJS

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&lt;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中設計模式全部最棒的資源。

Assets-Pack

在 本文結尾的時候,我想分享一些關於服務器上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 極客標籤

來源:web頁面內容優化管理與性能技巧

相關文章
相關標籤/搜索