前端重構其實能夠分爲兩個方面:
性能優化
和模塊化
。javascript
下面咱們先總結一下性能優化方面的東西:css
首先列舉一下常規的優化手段:前端
CSS置頂,JS置底java
靜態資源外聯、合併、壓縮jquery
圖片優化web
圖片延遲加載json
使用CSS Sprite,首屏圖片所有合併到一張圖上瀏覽器
靜態文件上CDN緩存
靜態文件設置強緩存性能優化
HTML壓縮
圖片預加載
加強型的手段:
基礎庫定製(用代碼分析代碼,自動打包被使用到的方法做爲基礎庫)
頁面數據存儲優化(從原來的的直接寫json形式的script,變爲將json隱藏在textarea中,初始化或用到的時候纔去提取並進行解析)
首屏CSS檢測,將不屬於首屏的css代碼單獨打包並移到首屏以外進行延遲加載
js按需加載
監控和測量
性能優化最重要的工做不是優化而是監控。這個道理很簡單,沒有監控體系就沒辦法衡量性能優化的效果,那麼你作的任何工做都是盲目的。
咱們對性能的監控是從多個維度展開的,包括平均時間、時段分佈、瀏覽器分佈、省份、運營商等。便於發現和定位任何一個細節的問題。
而在平均時間這一維度,咱們又分爲四個級別:
Head時間:head標籤加載完成的時間
TTi時間:頁面可交互時間(首屏第一次渲染出來的時間)
Dom時間:Dom Ready的時間
Load時間:頁面徹底加載完成的時間
這樣劃分的好處是,頁面加載每一個環節的耗時一目瞭然:
Head:CSS加載時間
TTI:總體HTML加載和渲染時間
DOM-TTI:js文件網絡傳輸時間和在瀏覽器進行解析的時間
Load減Dom:js初始化+圖片加載的時間
頁面加載的瓶頸就在script的下載和解析時間。
那麼,優化方案就很明顯了:最大限度地減少js文件大小,以減少網絡傳輸時間,提高頁面性能。
經過後來的優化工做咱們發現:js代碼壓縮、Gzip後每減少1k,頁面加載時間就能減少10ms左右。
按需加載:
這是除了js壓縮外,能想到的最有效減少js文件大小的辦法了。
樣式代替圖片。支持CSS3的瀏覽器愈來愈多,半透明、圓角、陰影、高光、漸變等均可以使用CSS3來實現
選擇最合適的圖片。jpg,png,gif
使用圖片壓縮工具
Icon font 缺點是隻支持純色圖標。
SVG:對於絕大多數圖案、圖標等,矢量圖更小,且可縮放無需生成多套圖。
data url:Base64是網絡上最多見的用語傳輸8Bit字節的編碼方式之一,可用以在http環境下傳遞較長的標示信息。將圖片轉化爲base64編碼格式,資源內嵌於CSS或HTML中,沒必要單獨請求。該方式的優勢是:
減小了http請求
避免了圖片從新上傳,還要清理緩存的問題
缺點:IE6,IE7不支持該類型編碼的圖片做爲背景圖,增長了CSS文件的大小,維護成本較高
按照Http協議設置合理的緩存
RWD設計
爲img標籤src設置統一的圖片連接,將真實連接地址裝在自定義屬性中,因此開始時候圖片是不會加載的,咱們將知足條件的圖片的src重置爲自定義屬性即可實現延遲加載功能
function imgLazyLoad(container){
container=container || $(window);
var imgArr={};
initImg();
lazyLoad();
container.scroll(function(){
lazyLoad();
})
$(window).resize(function(){
initImg();
})
function initImg(){
$('img').each(function(){
var el=$(this);
if(el.attr('lazy-src')&&el.attr('lazy-src')!=''){
var offset=el.offset();
if(!imgArr[offset.top]){
imgArr[offset.top]=[];
}
imgArr[offset.top].push(el);
}
})
}
function lazyLoad(){
var height=container.height();
var scrollHeight=container.scrollTop();
for(var k in imgArr){
if(parseInt(k)<scrollHeight+height){
var _imgs=imgArr[k];
for(var i=0;lens=_img.length;i++){
var temImg=_img[i];
if(tmpImg.attr('lazy-src')&&temImg.attr('lazy-src')!=''){
tmpImg.attr('src',tmpImg.attr('lazy-src'));
temImg.removeAttr('lazy-src');
}
}
delete imgArr[k];
}
}
}
}
imgLazyLoad($('#con'));
上述代碼沒有考慮到頁面空閒的狀況,當頁面空閒的狀況就不須要延遲加載了。
進行一下改進:
function imgLazyLoad(container) {
var imgLazyLoadTimer = null;
var resetImglazy = null;
container = container || $(window); //須要時jquery對象
var imgArr = {};
initImg();
lazyLoad();
imgLazyLoadTimer = setTimeout(autoLoad, 5000);
container.scroll(function () {
lazyLoad();
});
$(window).resize(function () {
initImg();
});
$(document).mousemove(function () {
if (imgLazyLoadTimer) clearTimeout(imgLazyLoadTimer);
if (resetImglazy) clearTimeout(resetImglazy);
resetImglazy = setTimeout(function () {
autoLoad();
}, 5000);
});
function initImg() {
$('img').each(function () {
var el = $(this);
if (el.attr('lazy-src') && el.attr('lazy-src') != '') {
var offset = el.offset();
if (!imgArr[offset.top]) {
imgArr[offset.top] = [];
}
imgArr[offset.top].push(el);
}
});
}
function lazyLoad() {
var height = container.height();
var srollHeight = container.scrollTop();
for (var k in imgArr) {
if (parseInt(k) < srollHeight + height) {
var _imgs = imgArr[k];
for (var i = 0, len = _imgs.length; i < len; i++) {
var tmpImg = _imgs[i];
if (tmpImg.attr('lazy-src') && tmpImg.attr('lazy-src') != '') {
tmpImg.attr('src', tmpImg.attr('lazy-src'));
tmpImg.removeAttr('lazy-src');
}
}
delete imgArr[k];
}
}
} //lazyLoad
function autoLoad() {
var _key = null;
for (var k in imgArr) {
if (!_key) {
_key = k;
break;
}
}
if (!_key) return false;
var _imgs = imgArr[_key];
for (var i = 0, len = _imgs.length; i < len; i++) {
var tmpImg = _imgs[i];
if (tmpImg.attr('lazy-src') && tmpImg.attr('lazy-src') != '') {
tmpImg.attr('src', tmpImg.attr('lazy-src'));
tmpImg.removeAttr('lazy-src');
}
}
delete imgArr[_key];
if (imgLazyLoadTimer) {
clearTimeout(imgLazyLoadTimer);
}
imgLazyLoadTimer = setTimeout(autoLoad, 1000);
}
} //imgLazyLoad
imgLazyLoad($('#con'));
另一種方式:
原理,當頁面載入的時候,使用jquery來循環遍歷每個img,判斷每個圖片是否在當前但是區域內,須要的數據:
瀏覽器但是區域的高度
圖片相對於文檔的偏移量
當圖片相對於文檔的偏移量小於瀏覽器可視區域的高度的時候,代表圖片已經進入可視區域,代碼以下:
$(document).ready(function(){
$('img').each(function(){
if($(this).offset().top < $(window).height()){
$(this).attr('src',$(this).attr("x-src"));
}
})
})
當用戶操做滾動條時,咱們還須要知道滾動條的高度:
$(window).scroll(function(){
$('img').each(function(){
if($(this).attr('src')==""){
if($(this).offset().top<$(window).height()+$(window).scrollTop()){
$(this).attr("src",$(this).attr("x-src"));
}
}
})
})
一般一個web網站最大的流量來源於靜態圖片文件,使用緩存後能夠減小同一客戶端對同一靜態資源的重複下載。
緩存並非瀏覽器緩存後就不會和服務端產生通訊,它須要和服務器端確認一下它緩存的東西是否是最新的,若是是則使用,不是則從新下載,所以瀏覽器緩存後並不會減小與服務器的交互次數,可是會下降與服務端的鏈接時長,變相地減小了服務端的併發。
所以瀏覽器緩存對於服務端來講節省了帶寬,對於客戶端來講減小了重複下載同一資源的次數,也就加快了訪問速度。
瀏覽器緩存某一信息後再次訪問時須要基於某一標識來確認一下它緩存的東西是不是最新的,這個標識有兩種:
Last_modified:
E-tag: