一篇《WordPress 網(wǎng)站全方位速度優(yōu)化:主機(jī)篇》講的是關(guān)于WordPress 網(wǎng)站所在主機(jī)的設(shè)置,這次我們來講網(wǎng)站內(nèi)部臃腫導(dǎo)致加載變慢。
還是上一篇那個例子,一個網(wǎng)站首頁總大小,如果從3MB下降到1MB。即便是1M 帶寬的主機(jī),加載時間也會從25秒下降到8秒,也是很可觀的。但是要給網(wǎng)站減肥可不是一件容易的事兒,我盡可能的詳細(xì)介紹:
訪客的瀏覽器從遠(yuǎn)程主機(jī)上抓取網(wǎng)頁,先抓取首頁的HTML 文件,然后再從 HTML 文件里提取出 CSS、JS、圖片、視頻等文件分別加載,有的 JS 和 CSS 里還會加載更多的 CSS、圖片、視頻。
有一個工具可以看到網(wǎng)頁加載過程,比如:文件數(shù)量、加載順序、每個元素的響應(yīng)時間、明細(xì)等信息。谷歌Chrome瀏覽器自帶的“檢查”工具,火狐 Firefox 的FireBug 工具都可以完成以上的工作。此外360瀏覽器,Safari 瀏覽器,IE 新版本都集成了這個功能。(如圖:minify是個 css 文件,大小426KB)
如果是咱們自己寫的 HTML、CSS、JS 文件,可以輕易瘦身,自己熟悉代碼哪里能優(yōu)化,但 WordPress 主題的 HTML、CSS、JS 我們是無能為力,只能通過Gzip壓縮解決。(如下圖,經(jīng)過 Gzip 壓縮,minify 文件 從426KB變成了57KB)
Gzip是服務(wù)器或者虛機(jī)提供的一種組件服務(wù),簡單地說:Gzip開啟后,從主機(jī)到訪客之間傳送的文件會被壓縮處理,這樣就會減小通過網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量,提高瀏覽的速度。比如一個首頁150KB,但是經(jīng)過壓縮真實(shí)傳輸大小是25KB。(如下圖)
Gzip具體使用方法:主機(jī)不同調(diào)用方法也不同,有的是寫.htaccess,有的是安裝個插件,不管是那種,可以到 Chinaz 站長工具里面檢測(網(wǎng)址:http://tool.chinaz.com/Gzips/)。比如小紅公司的網(wǎng)站:www.jianzhan1.cn的 html 文件是150KB,Gzip 壓縮之后變成26KB,然后在火狐里用 FireBug 檢查首頁果然是25.9KB。雙重驗(yàn)證說明 Gzip 生效了。此外Gzip 對 CSS 這類文本類的文件也會壓縮,比如有個CSS 文件是426KB,壓縮之后是57KB。
上圖為 ChinaZ 網(wǎng)站檢查結(jié)果,我們也可以從其他網(wǎng)站看出Gzip 是否生效,另外也可以用瀏覽器檢查工具檢查 header 是否有 Gzip。
通常Gzip只會壓縮 HTML 和 TXT 之類的文本文件,不建議用它來壓縮圖片,因?yàn)檫@樣會增加服務(wù)器 CPU 的負(fù)擔(dān),還會增加圖片的體積,具體原因大家百度一下。后面會說給圖片瘦身。
網(wǎng)站上用的圖片大概這么幾種:1 頭部Slider的背景圖和前景圖。2 產(chǎn)品和案例的圖片。3 其他裝飾圖片。
不論什么圖片,第一步先看寬高尺寸,大小夠用就好,切忌貪大,尺寸越大,容量越大,下載越慢,特別是產(chǎn)品圖,有的同學(xué)直接上傳2000px寬的2MB 圖片。(很多同學(xué)不了解常識)
此外圖片還分透明圖片和不透明圖片:透明圖比如說去掉背景的產(chǎn)品圖,還有特殊字體的文字也需要做成透明圖片,可以把他們放到背景圖上。不透明的圖片比如說背景圖片和產(chǎn)品展示圖等。
先說透明圖片,常用PNG格式,當(dāng)然 PNG 圖片也有透明和不透明之分,還有8位和24位的區(qū)別。總而言之,透明圖片我們用 PNG,但是 PNG 圖片很大,解決辦法是,到 TingPNG 網(wǎng)站優(yōu)化壓縮,網(wǎng)址:https://tinypng.com/,通常可以得到比較好的壓縮比,圖片質(zhì)量幾乎沒變化。因?yàn)檫@種壓縮是在線壓縮,需要上傳和下載,有點(diǎn)麻煩,但是一次麻煩終身受益。
再說經(jīng)常用到的JPG 圖片,通常我們直接在PhotoShop 里修改,裁切大小,另存為 web 格式壓縮,jpg 質(zhì)量60左右。這個大家都會,我再分享個秘籍:“WP Smush”,這是一個 WordPress 插件,每次上傳圖片時會自動在線壓縮,壓縮比很高,質(zhì)量損失很小,速度稍慢,絕對值得,一般人我不告訴他。
PNG 透明圖和 JPG 圖的究極壓縮方法都是在線工具,小而精 小而美,這是他們的獨(dú)門秘籍,不會輕易外傳,在線提供服務(wù)也是一種保護(hù)。
網(wǎng)站上用的視頻通常有兩種方式,一種是托管在視頻網(wǎng)站,比如優(yōu)酷,我們在自己網(wǎng)站上引用優(yōu)酷視頻的地址,通常會有優(yōu)酷的標(biāo)志或者廣告。另外一種方式是把視頻存放在本地主機(jī)上,我們主要說這種。這種視頻往往容量很大,用戶下載慢,使用時一定要注意。下面說說如何優(yōu)化:
以小紅建站公司網(wǎng)站首頁為例,第一屏有個背景視頻,1000kb碼率的MP4格式,36秒,5.4MB,嚴(yán)重影響打開速度。壓縮成384kb碼率的webm格式視頻后,變成1.4MB,但畫質(zhì)很粗糙,顯得很low。最后把視頻剪輯成22秒,壓縮成512kb碼率的webm是1.4MB,質(zhì)量好些,在視頻上覆蓋一層灰色,遮住粗糙的視頻,整體顯得高檔。
這樣做還有個問題,IE11瀏覽器 和 微軟Edge瀏覽器 不支持webm 格式的視頻,這需要額外增加mp4格式的視頻給微軟的瀏覽器。訪客瀏覽器如果是支持webm視頻的谷歌等瀏覽器,網(wǎng)站直接給他看webm視頻;訪客如果是 IE 瀏覽器,網(wǎng)站會給他看 MP4視頻。
同樣22秒 512k的碼率MP4也是1.4MB,但是質(zhì)量差很多,不得不提升768k碼率,視頻質(zhì)量和webm的512k碼率類似。吐槽Edge瀏覽器,播放MP4的質(zhì)量好差,同樣一段視頻比IE11差不少,馬賽克嚴(yán)重。
以上是對站內(nèi)HTML,CSS,JS,圖片,視頻的優(yōu)化壓縮,木桶理論的兩塊木板“主機(jī)提速”和“站內(nèi)減肥”介紹完了,下集將是最后一集,講谷歌這個“外患”,還有外鏈,緩存,調(diào)用系統(tǒng)中文字體微軟雅黑,。
注:相關(guān)網(wǎng)站建設(shè)技巧閱讀請移步到建站教程頻道。
動菜單通常是指一個下拉框的選項(xiàng)值發(fā)生改變后,另一個下拉框的選項(xiàng)值會發(fā)生對應(yīng)的變化。在 HTML 頁面中,可以使用 JavaScript 結(jié)合 HTML DOM 來實(shí)現(xiàn)這一功能。下面我來舉一個例子。
假設(shè)我們有三個下拉框,分別是“省份”、“城市”和“區(qū)縣”。當(dāng)“省份”下拉框的選項(xiàng)值發(fā)生改變時,我們需要動態(tài)更新“城市”下拉框的選項(xiàng)值,并且根據(jù)“城市”的選項(xiàng)值動態(tài)更新“區(qū)縣”下拉框的選項(xiàng)值。具體實(shí)現(xiàn)步驟如下:
1 首先在 HTML 文件中定義三個下拉框,并分別給它們一個唯一的 ID,如下所示:
<label>省份:</label>
<select id="province"></select>
<label>城市:</label>
<select id="city"></select>
<label>區(qū)縣:</label>
<select id="district"></select>
2 在 JavaScript 中定義三個函數(shù),分別用于更新“城市”、“區(qū)縣”下拉框的選項(xiàng)值,以及初始化頁面時的默認(rèn)值:
// 更新城市下拉框內(nèi)容
function updateCity() {
var provinceSelect = document.getElementById("province");
var citySelect = document.getElementById("city");
citySelect.innerHTML = ""; // 清空城市下拉框內(nèi)容
// 根據(jù)選中的省份,獲取該省份對應(yīng)的城市列表
var provinceName = provinceSelect.value;
var cityList = getCityList(provinceName);
// 根據(jù)城市列表,動態(tài)生成城市下拉框的選項(xiàng)
for (var i = 0; i < cityList.length; i++) {
var option = document.createElement("option");
option.text = cityList[i];
citySelect.add(option);
}
// 觸發(fā)區(qū)縣下拉框更新
updateDistrict();
}
// 更新區(qū)縣下拉框內(nèi)容
function updateDistrict() {
var citySelect = document.getElementById("city");
var districtSelect = document.getElementById("district");
districtSelect.innerHTML = ""; // 清空區(qū)縣下拉框內(nèi)容
// 根據(jù)選中的城市,獲取該城市對應(yīng)的區(qū)縣列表
var cityName = citySelect.value;
var districtList = getDistrictList(cityName);
// 根據(jù)區(qū)縣列表,動態(tài)生成區(qū)縣下拉框的選項(xiàng)
for (var i = 0; i < districtList.length; i++) {
var option = document.createElement("option");
option.text = districtList[i];
districtSelect.add(option);
}
}
// 初始化頁面
function initPage() {
var provinceSelect = document.getElementById("province");
var citySelect = document.getElementById("city");
var districtSelect = document.getElementById("district");
// 根據(jù)省份列表,動態(tài)生成省份下拉框的選項(xiàng)
for (var i = 0; i < provinceList.length; i++) {
var option = document.createElement("option");
option.text = provinceList[i];
provinceSelect.add(option);
}
// 觸發(fā)城市下拉框更新
updateCity();
}
現(xiàn)在我們已經(jīng)完成了省份和城市兩個下拉框的聯(lián)動效果,接下來我們需要再次綁定城市下拉框的change事件,以實(shí)現(xiàn)城市與區(qū)縣下拉框的聯(lián)動。
首先,我們需要在HTML中添加第三個下拉框,用于選擇區(qū)縣:
<select id="county"></select>
然后,我們需要更新updateCity和initPage兩個函數(shù),使其能夠更新城市和區(qū)縣兩個下拉框:
function updateCity() {
var province = document.getElementById('province').value;
var cityOptions = '';
for (var i = 0; i < cities[province].length; i++) {
cityOptions += '<option value="' + cities[province][i] + '">' + cities[province][i] + '</option>';
}
document.getElementById('city').innerHTML = cityOptions;
// 清空區(qū)縣下拉框
document.getElementById('county').innerHTML = '<option value="">--請選擇--</option>';
}
function updateCounty() {
var province = document.getElementById('province').value;
var city = document.getElementById('city').value;
var countyOptions = '';
for (var i = 0; i < counties[province][city].length; i++) {
countyOptions += '<option value="' + counties[province][city][i] + '">' + counties[province][city][i] + '</option>';
}
document.getElementById('county').innerHTML = countyOptions;
}
function initPage() {
// 初始化省份下拉框
var provinceOptions = '<option value="">--請選擇--</option>';
for (var province in cities) {
provinceOptions += '<option value="' + province + '">' + province + '</option>';
}
document.getElementById('province').innerHTML = provinceOptions;
// 綁定省份下拉框的change事件
document.getElementById('province').addEventListener('change', updateCity);
// 初始化城市下拉框
updateCity();
// 綁定城市下拉框的change事件
document.getElementById('city').addEventListener('change', updateCounty);
// 初始化區(qū)縣下拉框
updateCounty();
}
在updateCity函數(shù)中,我們添加了清空區(qū)縣下拉框的代碼,以確保每次更改城市時,區(qū)縣下拉框都會被清空。
在updateCounty函數(shù)中,我們根據(jù)選擇的省份和城市,動態(tài)生成區(qū)縣下拉框的選項(xiàng)。
在initPage函數(shù)中,我們綁定了城市下拉框的change事件,并調(diào)用updateCounty函數(shù)初始化區(qū)縣下拉框的選項(xiàng)。
最后,我們需要在JavaScript代碼中定義counties變量,以存儲每個城市對應(yīng)的區(qū)縣信息:
var counties = {
"北京市": {
"市轄區(qū)": ["東城區(qū)", "西城區(qū)", "崇文區(qū)", "宣武區(qū)", "朝陽區(qū)", "豐臺區(qū)", "石景山區(qū)", "海淀區(qū)", "門頭溝區(qū)", "房山區(qū)", "通州區(qū)", "順義區(qū)", "昌平區(qū)", "大興區(qū)", "懷柔區(qū)", "平谷區(qū)"],
"縣": ["密云縣", "延慶縣"]
},
"上海市": {
"市轄區(qū)": ["黃浦區(qū)", "盧灣區(qū)", "徐匯區(qū)", "長寧區(qū)", "靜安區(qū)", "普陀區(qū)", "閘北區(qū)", "虹口區(qū)", "楊浦區(qū)", "閔行區(qū)", "寶山區(qū)", "嘉定區(qū)", "浦東新區(qū)", "金山區(qū)", "松江區(qū)", "青浦區(qū)", "南匯區(qū)", "奉賢區(qū)"],
"縣": ["崇明縣"]
},
// 省略部分?jǐn)?shù)據(jù)...
};
接下來是第三個函數(shù)setDefaultValue(),用于初始化頁面時設(shè)置默認(rèn)值。在這個函數(shù)中,我們先根據(jù)省份的默認(rèn)值設(shè)置省份下拉框的選中項(xiàng),然后根據(jù)省份和城市的默認(rèn)值,從數(shù)據(jù)中獲取相應(yīng)的區(qū)縣數(shù)據(jù),并設(shè)置區(qū)縣下拉框的選項(xiàng)。
function setDefaultValue() {
// 設(shè)置省份下拉框默認(rèn)選中項(xiàng)
var provinceSelect = document.getElementById("province");
for (var i = 0; i < provinceSelect.options.length; i++) {
if (provinceSelect.options[i].value === defaultProvince) {
provinceSelect.selectedIndex = i;
break;
}
}
// 根據(jù)省份和城市設(shè)置區(qū)縣下拉框選項(xiàng)
var citySelect = document.getElementById("city");
var districtSelect = document.getElementById("district");
var districtData = data[defaultProvince][defaultCity];
districtSelect.options.length = 0; // 清空區(qū)縣下拉框
for (var i = 0; i < districtData.length; i++) {
var option = new Option(districtData[i], districtData[i]);
if (districtData[i] === defaultDistrict) {
option.selected = true; // 設(shè)置默認(rèn)選中項(xiàng)
}
districtSelect.options.add(option);
}
}
在這個函數(shù)中,我們首先獲取省份下拉框的DOM元素,并通過循環(huán)找到選中項(xiàng)為默認(rèn)省份的選項(xiàng),并設(shè)置為選中狀態(tài)。然后獲取城市和區(qū)縣的DOM元素,并從數(shù)據(jù)中獲取對應(yīng)的區(qū)縣數(shù)據(jù)。最后根據(jù)區(qū)縣數(shù)據(jù)動態(tài)創(chuàng)建選項(xiàng),并設(shè)置默認(rèn)選中項(xiàng)。注意,在設(shè)置區(qū)縣下拉框的選項(xiàng)時,我們先要將下拉框的長度設(shè)為0,以清空之前的選項(xiàng)。同時,我們還需要為新創(chuàng)建的選項(xiàng)設(shè)置selected屬性,以設(shè)置默認(rèn)選中項(xiàng)。
以上就是一個簡單的基于JavaScript和HTML DOM實(shí)現(xiàn)聯(lián)動菜單的示例,可以根據(jù)具體的業(yè)務(wù)需求進(jìn)行擴(kuò)展和修改。
者開始學(xué)習(xí)Javascript的時候,對模塊不太懂,不知道怎么導(dǎo)入模塊,導(dǎo)出模塊,就胡亂一通試
比如 import xx from 'test.js' 不起作用,就加個括號 import {xx} from 'test.js'
反正總是靠蒙,總有一種寫法是對的,其實(shí)還是沒有理解,還是不懂
尤其是在當(dāng)初寫 www.helloworld.net 網(wǎng)站的時候,一遇到這種問題,就懵逼了,尤其是引入第三方庫的時候
這種情況下更多,此篇文章也是為了怕以后忘記,自查用的,也希望能幫助更多的朋友,此篇文章只是針對ES6的模塊相關(guān)知識
我們知道,JS 模塊導(dǎo)入導(dǎo)出,使用 import , export 這兩個關(guān)鍵字
也就是說使用 export 導(dǎo)出一個模塊之后,其它文件就可以使用 import 導(dǎo)入相應(yīng)的模塊了
下面我們具體看看, import 和 export 到底怎么用?怎么導(dǎo)出模塊(比如變量,函數(shù),類,對象等)
//a.js 導(dǎo)出一個變量,語法如下
export var site = "www.helloworld.net"
//b.js 中使用import 導(dǎo)入上面的變量
import { site } from "/.a.js" //路徑根據(jù)你的實(shí)際情況填寫
console.log(site) //輸出: www.helloworld.net
上面的例子是導(dǎo)出單個變量,那么如何導(dǎo)出多個變量呢
//a.js 中定義兩個變量,并導(dǎo)出
var siteUrl="www.helloworld.net"
var siteName="helloworld開發(fā)者社區(qū)"
//將上面的變量導(dǎo)出
export { siteUrl ,siteName }
// b.js 中使用這兩個變量
import { siteUrl , siteName } from "/.a.js" //路徑根據(jù)你的實(shí)際情況填寫
console.log(siteUrl) //輸出: www.helloworld.net
console.log(siteName) //輸出: helloworld開發(fā)者社區(qū)
導(dǎo)出函數(shù)和導(dǎo)出變量一樣,需要添加{ }
//a.js 中定義并導(dǎo)出一個函數(shù)
function sum(a, b) {
return a + b
}
//將函數(shù)sum導(dǎo)出
export { sum }
//b.js 中導(dǎo)入函數(shù)并使用
import { sum } from "/.a.js" //路徑根據(jù)你的實(shí)際情況填寫
console.log( sum(4,6) ) //輸出: 10
js中一切皆對象,所以對象一定是可以導(dǎo)出的,并且有兩種寫法
使用 export default 關(guān)鍵字導(dǎo)出,如下
//a.js 中,定義對象并導(dǎo)出, 注意,使用export default 這兩個關(guān)鍵字導(dǎo)出一個對象
export default {
siteUrl:'www.helloworld.net',
siteName:'helloworld開發(fā)者社區(qū)'
}
//b.js 中導(dǎo)入并使用
import obj from './a.js' //路徑根據(jù)你的實(shí)際情況填寫
console.log(obj.siteUrl) //輸出:www.helloworld.net
console.log(obj.siteName) //輸出:helloworld開發(fā)者社區(qū)
同樣是使用export default 關(guān)鍵字,如下
//a.js 中定義對象,并在最后導(dǎo)出
var obj = {
siteUrl:'www.helloworld.net',
siteName:'helloworld開發(fā)者社區(qū)'
}
export default obj //導(dǎo)出對象obj
//b.js 中導(dǎo)入并使用
import obj from './a.js' //路徑根據(jù)你的實(shí)際情況填寫
console.log(obj.siteUrl) //輸出:www.helloworld.net
console.log(obj.siteName) //輸出:helloworld開發(fā)者社區(qū)
導(dǎo)出類與上面的導(dǎo)出對象類似,同樣是用 export default 關(guān)鍵字,同樣有兩種寫法
//a.js 中定義一個類并直接導(dǎo)出
export default class Person {
//類的屬性
site = "www.helloworld.net"
//類的方法
show(){
console.log(this.site)
}
}
//b.js 中導(dǎo)入并使用
//導(dǎo)入類
import Person from './a.js'
//創(chuàng)建類的一個對象person
let person = new Person()
//調(diào)用類的方法
person.show() //輸出:www.helloworld.net
//a.js 中定義一個類,最后導(dǎo)出
class Person {
//類的屬性
site = "www.helloworld.net"
//類的方法
show(){
console.log(this.site)
}
}
//導(dǎo)出這個類
export default Person
//b.js 中導(dǎo)入并使用
//導(dǎo)入類
import Person from './a.js'
//創(chuàng)建類的一個對象person
let person = new Person()
//調(diào)用類的方法
person.show() //輸出:www.helloworld.net
下面我們簡單總結(jié)一下
export與export default的區(qū)別
對于 import ,export , export default ,他們的用法上面的例子已經(jīng)很詳細(xì)的列出了,忘記的時候,可以當(dāng)作參考看看
最重要的還是要明白為什么要這么寫,實(shí)在不明白記住就行了。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。