Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
(1)響應的簡介
當一個web服務器響應一個http請求時,響應通常包括一個狀態行、一些響應報頭、一個空行和文檔。一個典型的響應如下所示:
HTTP/1.1 200 OK
Content-Type: text/html
Header2: ...
...
HeaderN: ...
(Blank Line)
<!doctype ...>
<html>
<head>...</head>
<body>
...
</body>
</html>
(2)補充:
狀態行包括:http版本、一個狀態碼和一個對應于狀態碼的短消息。
(3)下表總結了從web服務器端返回到瀏覽器的最有用的http1.1響應報頭:
下面的方法可用于servlet程序中設置http響應報頭。這些方法通過HttpServletResponse對象可用。
(1)在webtest工程下的com.web.test包下創建類ResponseInfo
補充:通過用 setIntHeader() 方法來設置 Refresh 頭,達到自動刷新的目的。
(2)啟動tomcat訪問,訪問鏈接如下:
http://localhost:8080/webtest/responseinfo
(3)效果如下
擊上方 關注訂閱黑碼教主獲取更多精彩內容
在多重嵌套循環的程序上,如果能分出出多個獨立循環也比嵌套在一個循環體內來的更有益。
優化循環的3種方式:減少每次迭代的開銷、減少迭代的次數或者重新設計應用程序。
在測試的時候僅可能模擬真實環境:如低端機器和低速網絡。
?
對于連續頁面之間的差別很小的應用而言,使用Ajax技術能帶來顯著的改善。
?
在HTML頁面完成展現之后,動態改變頁面元素或調整CSS樣式都會引起瀏覽器重繪,性能的損耗直接取決于動態改變的范圍:如果只是改變一個元素的顏色之類的信息則只會重繪該元素;而如果是增刪節點或調整節點位置則會引起其兄弟節點也一并重繪。
減少重繪并不是說不要重繪,而是要注意重繪范圍:
以改變一個<a>標簽的背景色、寬度和顏色為例。
<a href="javascript:void(0);" id="example">傳統的代碼</a> <script> var example=document.getElementById("example"); example.ondblclick=function() { example.style.backgroundColor="red"; example.style.width="200px"; example.style.color="white"; } </script>
以上會執行3次重繪,而通過CSS代替javascript多次執行則只進行一次重繪。
<style> .dblClick { width: 200px; background: red; color: white; } </style> <a href="javascript:;" id="example">CSS優化的代碼</a> <script> var example=document.getElementById("example"); example.ondblclick=function() { example.className="dblClick"; } </script>
當瀏覽器在解析常規的script標簽時,它需要等待script下載完畢,再解析執行,而后續的HTML代碼只能等待。CSS文件引入要放在頭部,因為這是HTML渲染必備元素。
?
為了避免阻塞加載,應把腳本放到文檔的末尾,而CSS是需要放在頭部的!
<head> <link rel="stylesheet" href="common.css"> ...... <script src="example.js"></script> </body>
深層級嵌套的節點在初始化構建時往往需要更多的內存占用,并且在遍歷節點時也會更慢些,這與瀏覽器構建DOM文檔的機制有關。瀏覽器會把整個HTML文檔的結構存儲為DOM“樹”結構。當文檔節點的嵌套層次越深,構建的DOM樹層次也會越深。
如下代碼,完全能夠去掉
或其中一個標簽。<div> <span> <label>嵌套</label> </span> </div>
頁面緩存
通常不設置緩存的情況下,每次刷新頁面都會重新讀取服務器的文件,而如果設置緩存之后,所有文件都可以從本地取得,這樣明顯極大提高了頁面效率。
我們可以通過設置頁面頭的expires來定義頁面過期時間,將過期時間定久一點就達到了“永久”緩存。
<meta http-equiv="expires" content="Sunday 26 October 2099 01:00 GMT" />
當然,如果你的項目代碼有變更,因為客戶端緩存了文件就得不到最新的文件,勢必造成顯示錯誤?;谶@個問題的解決方案就是給鏈接文件加一個時間戳,如果時間戳有變化,瀏覽器會認為是新文件,就會向服務器請求最新文件。
<script src="example2014-6-17.js"></script> //如果是JSP,可以用EL表達式來取時間戳信息,這樣管理更加方便 <script src="example${your time param}.js"></script> //或者這樣的寫法更優秀: <script src="example.js?time=2014-6-7"></script> <script src="example.js?time=${your time param}"></script>
所有涉及到請求數據的文件盡量做壓縮,比如Javascript文件、css文件及圖片文件,特別是圖片文件,如果沒有高清晰要求,完全可以壓縮后再使用。
數量少體積大的文件要比數量多體積小的文件加載速度快,所以有時候可以考慮將多個js文件、多個css文件合并在一起。
除此之外減少HTML文檔大小還可以采取下面幾種方法:
圖像合并其實就是把網頁中一些背景圖片整合到一張圖片文件中,再利用CSS 的“background-image”,“background- repeat”,“background-position”的組合進行背景定位,background-position可以用數字能精確的定位出背景圖片的位置。
一個頁面要用到多個圖標,完全可以將多個圖標合并成一個圖,然后只需要發一次圖片請求,通過css定位分割圖標即可。
使用iframe并不會增加同域名下的并行下載數,瀏覽器對同域名的連接總是共享瀏覽器級別的連接池,在頁面加載過程中iframe元素還會阻塞父文檔onload事件的觸發。并且iframe是html標簽中最消耗資源的標簽,它的開銷比DIV、SCRIPT、STYLE等DOM高1~2個數量級。
避免onload事件被阻塞,可使用JavaScript動態的加載iframe元素或動態設置iframe的src屬性(但其僅在高級瀏覽器IE9及以上有效)。
<iframe id="if"></iframe> document.getElementById("if").setAttribute("src","url");
一般來說,瀏覽器對于相同域名的圖片,最多用2-4個線程并行下載(不同瀏覽器的并發下載數是不同的)。而相同域名的其他圖片,則要等到其他圖片下載完后才會開始下載。
有時候,圖片數據太多,一些公司的解決方法是將圖片數據分到多個域名的服務器上,這在一方面是將服務器的請求壓力分到多個硬件服務器上,另一方面,是利用了瀏覽器的特性。(大家可以去新浪、騰訊門戶網站查看,這些大型站點同一頁面加載的圖片可能由多個站點提供)
注:一個HTML請求的域名也不要太多(2~3個差不多),多了可能造成不同服務器連接時間差異,反而影響速度。
如<img src=""><a href="">這樣的設置方式是非常不可取的,即使鏈接為空,在舊的瀏覽器也會以固定步驟發送請求信息。
另外<a href="#"></a>也不可取,最好的方式是在鏈接中加一個空的js代碼<a href="javascript:void();"></a>
base64是一串字符串,他可以代表一個圖片的所有信息,也就是可以通過
(S表示一串base64碼)來顯示圖片,這種方式不需要再向服務器發送請求,完全由瀏覽器解析成圖片。
目前高級瀏覽器都支持此功能,但要注意兩點:
如果HTML里的圖片沒有指定尺寸(寬和高),或者代碼描述的尺寸與實際圖片的尺寸不符時,瀏覽器則要在圖片下載完成后再“回溯”該圖片并重新顯示,這會消耗額外時間。
<iframe id="if"></iframe> document.getElementById("if").setAttribute("src","url");
如果瀏覽器不能獲知頁面的編碼字符集,一般都會在執行腳本和渲染頁面前,把字節流緩存,然后再搜索可進行解析的字符集,或以默認的字符集來解析頁面代碼,這會導致消耗不必要的時間。
<iframe id="if"></iframe> document.getElementById("if").setAttribute("src","url");
漸進式增強設計的通俗解釋就是:首先寫一段滿足所有瀏覽器的基本樣式,再在后面針對不同高級瀏覽器編寫更漂亮的樣式
如下代碼,所有瀏覽器都支持background-color: #2067f5;滿足了瀏覽器基本現實需求,而后面的background-image: -webkit-gradient等則為不同高級瀏覽器使用,只要瀏覽器識別就能執行這段代碼(不識別,CSS也不會報錯只會直接忽略)。
<div class="someClass"></div> .someClass { width: 100px; height: 100px; background-color: #2067f5; background-image: -webkit-gradient(linear, left top, left bottom, from(#2067f5), to(#154096)); background-image: -webkit-linear-gradient(top, #2067f5, #154096); background-image: -moz-linear-gradient(top, #2067f5, #154096); background-image: -ms-linear-gradient(top, #2067f5, #154096); background-image: -o-linear-gradient(top, #2067f5, #154096); background-image: linear-gradient(to bottom, #2067f5, #154096); }
預加載和懶加載,是一種改善用戶體驗的策略,它實際上并不能提高程序性能,但是卻可以明顯改善用戶體驗或減輕服務器壓力。
預加載表示當前用戶在請求到需要的數據之后,頁面自動預加載下一次用戶可能要看的數據,這樣用戶下一次操作的時候就立刻呈現,依次類推。
懶加載表示用戶請求什么再顯示什么,如果一個請求要響應的時間非常長,就不推薦懶加載。
當一個頁面非常大,內容非常多,可以采用flush的形式分部分返回給頁面,這樣能告訴用戶我正在工作,顯示一部分內容比白屏等很長時間要好得多。在Java Web技術中,實現Flush非常簡單,只要調用 HttpServletResponse.getWriter輸出流的flush方法,就可以將已經完成加載的內容寫回給客戶端。
這種方式只適用于返回數據特別多、請求時間特別長的情況,常規數據還是用正常的實時全部返回最佳。這種實現方式實際會增加瀏覽器渲染時間和用戶整體等待時間,但從用戶體驗上會更加優秀。
所謂的CDN,就是一種內容分發網絡,它采用智能路由和流量管理技術,及時發現能夠給訪問者提供最快響應的加速節點,并將訪問者的請求導向到該加速節點,由該加速節點提供內容服務。
通俗點說,你在成都(瀏覽器)購買了北京賣家(服務器)的產品,北京賣家通過快遞(CDN服務)寄送包裹,從北京到成都可以走路、坐汽車、火車或飛機,而采用CND的快遞會選擇飛機直達,因為這種寄送方式最快。
當然使用CDN有兩個注意事項:
瀏覽器緩存帶來的性能提升已經眾人皆知了,而很多人卻并不知道瀏覽器的緩存過期時間、緩存刪除、什么頁面可以緩存等,都可以由我們程序員來控制,只要您熟悉HTTP協議,就可以輕松的控制瀏覽器。
所謂的動靜分離,就是將Web應用程序中靜態和動態的內容分別放在不同的Web服務器上,有針對性的處理動態和靜態內容,從而達到性能的提升。我們知道如果一個HTML有多個域名請求數據文件會提高
Tomcat服務器在處理靜態和并發問題上比較弱,所以事先動靜分離的方式一般會用Apache+Tomcat、Nginx+Tomcat等。
以Apache+Tomcat為例,其運行機理是:頁面請求首先給Apache,然后Apache分析請求信息是靜態還是動態,靜態則本機處理,動態則交給Tomcat做處理。
這其實是負載均衡的雛形,這樣的實現不用讓開發人員做任何特殊開發,一個
交給服務器即可,至于這個文件是從Apache還是從Tomcat取得,開發人員完全無需關注。
持久連接(Keep-Alive)也叫做長連接,它是一種TCP的連接方式,連接會被瀏覽器和服務器所緩存,在下次連接同一服務器時,緩存的連接被重新使用。HTTP無狀態性表示了它不屬于長連接,但HTTP/1.1提供了對長連接的支持(不過這必須依賴瀏覽器和服務器雙方均支持長連接功能才行),最常見的HTTP長連接例子是“斷點下載”。
瀏覽器在請求的頭部添加 Connection:Keep-Alive,以此告訴服務器“我支持長連接,你支持的話就和我建立長連接吧”,而倘若服務器的確支持長連接,那么就在響應頭部添加“Connection:Keep-Alive”,從而告訴瀏覽器“我的確也支持,那我們建立長連接吧”。服務器還可以通過Keep-Alive:timeout=..., max=...的頭部告訴瀏覽器長連接失效時間。
配置長連接通常是要服務器支持設置,有測試數據顯示,使用長連接和不使用長連接的性能對比,對于Tomcat配置的maxKeepAliveRequests為50來說,效率竟然提升了將近5倍。
HTTP協議支持GZIP的壓縮格式,當服務器返回的HTML信息報頭中包含Content-Encoding:gzip,它就告訴瀏覽器,這個響應的返回數據已經壓縮成GZIP格式,瀏覽器獲得數據后要進行解壓縮操作,一定程度上減輕了服務器傳輸數據的壓力。
很多服務器已經支持通過配置來自動將HTML信息壓縮成GZIP,比如tomcat、又比如很火的Nginx。如果無法配置服務器級別的GZIP壓縮機制,可以改為程序壓縮。
// 監視對 gzipCategory 文件夾的請求 @WebFilter(urlPatterns={ "/gzipCategory/*" }) public class GZIPFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String parameter=request.getParameter("gzip"); // 判斷是否包含了 Accept-Encoding 請求頭部 HttpServletRequest s=(HttpServletRequest)request; String header=s.getHeader("Accept-Encoding"); //"1".equals(parameter) 只是為了控制,如果傳入 gzip=1,才執行壓縮,目的是測試用 if ("1".equals(parameter) && header !=null && header.toLowerCase().contains("gzip")) { HttpServletResponse resp=(HttpServletResponse) response; final ByteArrayOutputStream buffer=new ByteArrayOutputStream(); HttpServletResponseWrapper hsrw=new HttpServletResponseWrapper( resp) { @Override public PrintWriter getWriter() throws IOException { return new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding())); } @Override public ServletOutputStream getOutputStream() throws IOException { return new ServletOutputStream() { @Override public void write(int b) throws IOException { buffer.write(b); } }; } }; chain.doFilter(request, hsrw); byte[] gzipData=gzip(buffer.toByteArray()); resp.addHeader("Content-Encoding", "gzip"); resp.setContentLength(gzipData.length); ServletOutputStream output=response.getOutputStream(); output.write(gzipData); output.flush(); } else { chain.doFilter(request, response); } } // 用 GZIP 壓縮字節數組 private byte[] gzip(byte[] data) { ByteArrayOutputStream byteOutput=new ByteArrayOutputStream(10240); GZIPOutputStream output=null; try { output=new GZIPOutputStream(byteOutput); output.write(data); } catch (IOException e) { } finally { try { output.close(); } catch (IOException e) { } } return byteOutput.toByteArray(); } …… }
如果你覺得本篇還不錯,請點贊關注!
文字由黑碼教主創作,配圖源于網絡,版權歸原作者所有,如有侵權聯系刪除!
你有更好的網站性能優化方案嗎?
歡迎留言分享。
往一些不足的地方,通過博客,好好總結一下。
.disabled {
pointer-events: none;
cursor: default;
opacity: 0.6;
}
復制代碼
超文本傳輸協議(HTTP)的設計目的是保證客戶機與服務器之間的通信。 HTTP 的工作方式是客戶機與服務器之間的請求-應答協議。 web 瀏覽器可能是客戶端,而計算機上的網絡應用程序也可能作為服務器端。
HEAD: 與 GET 相同,但只返回 HTTP 報頭,不返回文檔主體 PUT: 上傳指定的 URI 表示 DELETE: 刪除指定資源 OPTIONS: 返回服務器支持的 HTTP 方法 CONNECT: 把請求連接轉換到透明的 TCP/IP 通道 POST: 向指定的資源提交要被處理的數據
// 查詢字符串(名稱/值對)是在 POST 請求的 HTTP 消息主體中發送的
POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2
復制代碼
GET: 從指定的資源請求數據
GET 請求可被緩存 GET 請求保留在瀏覽器歷史記錄中 GET 請求可被收藏為書簽 GET 請求不應在處理敏感數據時使用 GET 請求有長度限制(2048字符),IE和Safari瀏覽器限制2k;Opera限制4k;Firefox,Chrome限制8k GET 請求只應當用于取回數據
POST 請求不會被緩存 POST 請求不會保留在瀏覽器歷史記錄中 POST 不能被收藏為書簽 POST 請求對數據長度沒有要求
nth-child(even/odd)
// odd表示基數,此時選中基數行的樣式,even表示偶數行
.row:nth-child(odd){
background: #eee;
}
復制代碼
nth-of-type(odd)
.row:nth-of-type(odd){
background: #eee;
}
復制代碼
漸變實現linear-gradient
.stripe-bg{
padding: .5em;
line-height: 1.5em;
background: beige;
background-size: auto 3em;
background-origin: content-box;
background-image: linear-gradient(rgba(0,0,0,.2) 50%, transparent 0);
}
復制代碼
// 數據可以以數組方式存儲,也可以是對象方式
let a={x:'6', y:10},
b={x: 8, y: 20};
function distant(a,b){
let dx=Number(a.x) - Number(b.x)
let dy=Number(a.y) - Number(b.y)
return Math.pow(dx*dx + dy*dy, .5)
}
復制代碼
body{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
復制代碼
// indexOf實現
var array=[1, 1, '1'];
function unique(array) {
var res=[];
for (var i=0, len=array.length; i < len; i++) {
var current=array[i];
if (res.indexOf(current)===-1) {
res.push(current)
}
}
return res;
}
console.log(unique(array));
// 排序后去重
var array=[1, 1, '1'];
function unique(array) {
var res=[];
var sortedArray=array.concat().sort();
var seen;
for (var i=0, len=sortedArray.length; i < len; i++) {
// 如果是第一個元素或者相鄰的元素不相同
if (!i || seen !==sortedArray[i]) {
res.push(sortedArray[i])
}
seen=sortedArray[i];
}
return res;
}
console.log(unique(array));
// filter實現
var array=[1, 2, 1, 1, '1'];
function unique(array) {
var res=array.filter(function(item, index, array){
return array.indexOf(item)===index;
})
return res;
}
console.log(unique(array));
// 排序去重
var array=[1, 2, 1, 1, '1'];
function unique(array) {
return array.concat().sort().filter(function(item, index, array){
return !index || item !==array[index - 1]
})
}
console.log(unique(array));
// Object鍵值對
var array=[{value: 1}, {value: 1}, {value: 2}];
function unique(array) {
var obj={};
return array.filter(function(item, index, array){
console.log(typeof item + JSON.stringify(item))
return obj.hasOwnProperty(typeof item + JSON.stringify(item)) ? false : (obj[typeof item + JSON.stringify(item)]=true)
})
}
console.log(unique(array)); // [{value: 1}, {value: 2}]
// ES6 Set實現
var unique=(a)=> [...new Set(a)]
復制代碼
CDN:CDN是將源站內容分發至最接近用戶的節點,使用戶可就近取得所需內容,提高用戶訪問的響應速度和成功率。解決因分布、帶寬、服務器性能帶來的訪問延遲問題,適用于站點加速、點播、直播等場景。 好處: 1、多域名加載資源 一般情況下,瀏覽器都會對單個域名下的并發請求數(文件加載)進行限制,通常最多有4個,那么第5個加載項將會被阻塞,直到前面的某一個文件加載完畢。 因為CDN文件是存放在不同區域(不同IP)的,所以對瀏覽器來說是可以同時加載頁面所需的所有文件(遠不止4個),從而提高頁面加載速度。
2、文件可能已經被加載過并保存有緩存 一些通用的js庫或者是css樣式庫,如jQuery,在網絡中的使用是非常普遍的。當一個用戶在瀏覽你的某一個網頁的時候,很有可能他已經通過你網站使用的CDN訪問過了其他的某一個網站,恰巧這個網站同樣也使用了jQuery,那么此時用戶瀏覽器已經緩存有該jQuery文件(同IP的同名文件如果有緩存,瀏覽器會直接使用緩存文件,不會再進行加載),所以就不會再加載一次了,從而間接的提高了網站的訪問速度
3、高效率 你的網站做的再NB也不會NB過百度NB過Google吧?一個好的CDNs會提供更高的效率,更低的網絡延時和更小的丟包率。
4、分布式的數據中心 假如你的站點布置在北京,當一個香港或者更遠的用戶訪問你的站點的時候,他的數據請求勢必會很慢很慢。而CDNs則會讓用戶從離他最近的節點去加載所需的文件,所以加載速度提升就是理所當然的了。
5、使用情況分析 一般情況下CDNs提供商(如百度云加速)都會提供數據統計功能,可以了解更多關于用戶訪問自己網站的情況,可以根據統計數據對自己的站點適時適當的做出些許調整。
6、有效防止網站被攻擊 一般情況下CDNs提供商也是會提供網站安全服務的
參考連接
function checkPhone(){
if(!(/^1[345678]\d{9}$/.test(phone))){
alert("手機號碼有誤,請重填");
return false;
}
}
復制代碼
1.js外聯文件放到body底部,css外聯文件放到head內 2.http靜態資源盡量用多個子域名 3.服務器端提供html和http靜態資源時最好開啟gzip 4.在js,css,img等資源響應的http headers里設置expires,last-modified 5.盡量減少http requests的數量 6.js/css/html/img資源壓縮 7.使用css spirtes,可以減少img請求次數 8.大圖使用lazyload懶加載 9.避免404,減少外聯js 10.減少cookie大小可以提高獲得響應的時間 11.減少dom elements的數量 12.使用異步腳本,動態創建腳本
IE/360/搜狗瀏覽器: Trident Chrome/Safari/Opera: WebKit(KHTML的一個開源的分支) (雖然我們稱WebKit為瀏覽器內核,但不太適合直接稱渲染引擎,因為WebKit本身主要是由兩個引擎構成的,一個正是渲染引擎“WebCore”,另一個則是javascript解釋引擎“JSCore”,它們均是從KDE的渲染引擎KHTML及javascript解釋引擎KJS衍生而來。) (在13年發布的Chrome 28.0.1469.0版本開始,Chrome放棄Chromium引擎轉而使用最新的Blink引擎(基于WebKit2——蘋果公司于2010年推出的新的WebKit引擎),Blink對比上一代的引擎精簡了代碼、改善了DOM框架,也提升了安全性。) (為了減少研發成本,Opera在2013年2月宣布放棄Presto,轉而跟隨Chrome使用WebKit分支的Chromium引擎作為自家瀏覽器核心引擎) Firefox/SeaMonkey: Gecko
1)解析: 一個是HTML/SVG/XHTML,事實上,Webkit有三個C++的類對應這三類文檔。解析這三種文件會產生一個DOM Tree。 CSS,解析CSS會產生CSS規則樹。 Javascript,腳本,主要是通過DOM API和CSSOM API來操作DOM Tree和CSS Rule Tree. 2)渲染:瀏覽器引擎會通過DOM Tree 和 CSS Rule Tree 來構造 Rendering Tree。注意: Rendering Tree 渲染樹并不等同于DOM樹,因為一些像Header或display:none的東西就沒必要放在渲染樹中了。 CSS 的 Rule Tree主要是為了完成匹配并把CSS Rule附加上Rendering Tree上的每個Element。也就是DOM結點。也就是所謂的Frame。 然后,計算每個Frame(也就是每個Element)的位置,這又叫layout和reflow過程。 3)繪制:最后通過調用操作系統Native GUI的API繪制。
減少reflow和repaint 1)不要一條一條地修改DOM的樣式。還不如預先定義好css的class,然后修改DOM的className。
(1)link屬于XHTML標簽,除了加載CSS外,還能用于定義RSS, 定義rel連接屬性等作用;而@import是CSS提供的,只能用于加載CSS; (2)頁面被加載的時,link會同時被加載,而@import引用的CSS會等到頁面被加載完再加載; (3)import是CSS2.1 提出的,只在IE5以上才能被識別,而link是XHTML標簽,無兼容問題; (4)link支持使用js控制DOM去改變樣式,而@import不支持;
用正確的標簽做正確的事情。 html語義化讓頁面的內容結構化,便于對瀏覽器、搜索引擎解析; 即使在沒有樣式CSS情況下也以一種文檔格式顯示,并且是容易閱讀的; 搜索引擎的爬蟲也依賴于HTML標記來確定上下文和各個關鍵字的權重,利于SEO; 使閱讀源代碼的人對網站更容易將網站分塊,便于閱讀維護理解。
cookie是網站為了標示用戶身份而儲存在用戶本地終端(Client Side)上的數據(通常經過加密)。 cookie數據始終在同源的http請求中攜帶(即使不需要),記會在瀏覽器和服務器間來回傳遞。 sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。
存儲大?。?cookie數據大小不能超過4k。 sessionStorage和localStorage 雖然也有存儲大小的限制,但比cookie大得多,可以達到5M或更大。
有期時間: localStorage 存儲持久數據,瀏覽器關閉后數據不丟失除非主動刪除數據; sessionStorage 數據在當前瀏覽器窗口關閉后自動刪除。 cookie 設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉
*iframe會阻塞主頁面的Onload事件; *搜索引擎的檢索程序無法解讀這種頁面,不利于SEO; *iframe和主頁面共享連接池,而瀏覽器對相同域的連接有限制,所以會影響頁面的并行加載。 使用iframe之前需要考慮這兩個缺點。如果需要使用iframe,最好是通過javascript 動態給iframe添加src屬性值,這樣可以繞開以上兩個問題。
(圖片來自vue官網,更多vue學習推薦去官網查看詳細文檔)
區分用戶是計算機還是人的公共全自動程序??梢苑乐箰阂馄平饷艽a、刷票、論壇灌水; 有效防止黑客對某一個特定注冊用戶用特定程序暴力破解方式進行不斷的登陸嘗試。
(1)有兩種, IE 盒子模型、W3C 盒子模型; (2)盒模型: 內容(content)、填充(padding)、邊界(margin)、 邊框(border); (3)區 別: IE的content部分把 border 和 padding計算了進去;
absolute 生成絕對定位的元素,相對于值不為 static的第一個父元素進行定位。 fixed (老IE不支持) 生成絕對定位的元素,相對于瀏覽器窗口進行定位。 relative 生成相對定位的元素,相對于其正常位置進行定位。 static 默認值。沒有定位,元素出現在正常的流中(忽略 top, bottom, left, right z-index 聲明)。 inherit 規定從父元素繼承 position 屬性的值。
png24位的圖片在iE6瀏覽器上出現背景,解決方案是做成PNG8.
超鏈接訪問過后hover樣式就不出現了 被點擊訪問過的超鏈接樣式不在具有hover和active了解決方法是改變CSS屬性的排列順序: L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}
關鍵選擇器(key selector)。選擇器的最后面的部分為關鍵選擇器(即用來匹配目標元素的部分); 如果規則擁有 ID 選擇器作為其關鍵選擇器,則不要為規則增加標簽。過濾掉無關的規則(這樣樣式系統就不會浪費時間去匹配它們了); 提取項目的通用公有樣式,增強可復用性,按模塊編寫組件;增強項目的協同開發性、可維護性和可擴展性; 使用預處理工具或構建工具(gulp對css進行語法檢查、自動補前綴、打包壓縮、自動優雅降級);
input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
background-color: rgb(250, 255, 189); /* #FAFFBD; */
background-image: none;
color: rgb(0, 0, 0);
}
復制代碼
-webkit-font-smoothing: antialiased;
復制代碼
-webkit-overflow-scrolling: touch;
復制代碼
function commafy(num){
return num && num
.toString()
.replace(/(\d)(?=(\d{3})+\.)/g, function($1, $2){
return $2 + ',';
});
}
復制代碼
全局函數無法查看局部函數的內部細節,但局部函數可以查看其上層的函數細節,直至全局細節。 當需要從局部函數查找某一屬性或方法時,如果當前作用域沒有找到,就會上溯到上層作用域查找, 直至全局函數,這種組織形式就是作用域鏈。
this總是指向函數的直接調用者(而非間接調用者); 如果有new關鍵字,this指向new出來的那個對象; 在事件中,this指向觸發這個事件的對象,特殊的是,IE中的attachEvent中的this總是指向全局對象Window;
它的功能是把對應的字符串解析成JS代碼并運行; 應該避免使用eval,不安全,非常耗性能(2次,一次解析成js語句,一次執行)。 由JSON字符串轉換為JSON對象的時候可以用eval,var obj=eval('('+ str +')');
window對象是指瀏覽器打開的窗口。 document對象是Documentd對象(HTML 文檔對象)的一個只讀引用,window對象的一個屬性。
["1", "2", "3"].map(parseInt) 答案也就是:[1, NaN, NaN]
閉包是指有權訪問另一個函數作用域中變量的函數,創建閉包的最常見的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量,利用閉包可以突破作用鏈域,將函數內部的變量和方法傳遞到外部。
使JS編碼更加規范化的模式,消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為。 默認支持的糟糕特性都會被禁用,比如不能用with,也不能在意外的情況下給全局變量賦值; 全局變量的顯示聲明,函數必須聲明在頂層,不允許在非函數代碼塊內聲明函數,arguments.callee也不允許使用; 保證代碼運行的安全,限制函數中的arguments修改; 提高編譯器效率,增加運行速度;
if(a instanceof Person){
alert('yes');
}
// 判斷對象類型最好的方式
// 對于 Object 對象,直接調用 toString() 就能返回 [object Object] 。而對于其他對象,則需要通過 call / apply 來調用才能返回正確的類型信息。
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全局對象 global 的引用
復制代碼
1、創建一個空對象,并且 this 變量引用該對象,同時還繼承了該函數的原型。
2、屬性和方法被加入到 this 引用的對象中。
3、新創建的對象由 this 所引用,并且最后隱式的返回 this 。
復制代碼
1、在ajax發送請求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。
2、在ajax發送請求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。 3、在URL后面加上一個隨機數: "fresh=" + Math.random();。 4、在URL后面加上時間戳:"nowtime=" + new Date().getTime();。 5、如果是使用jQuery,直接這樣就可以了 $.ajaxSetup({cache:false})。這樣頁面的所有ajax都會執行這條語句就是不需要保存緩存記錄。
jsonp、 iframe、window.name、window.postMessage、服務器上設置代理頁面
立即執行函數,不暴露私有成員
var module1=(function(){
????var _count=0;
????var m1=function(){
??????//...
????};
????var m2=function(){
??????//...
????};
????return {
??????m1 : m1,
??????m2 : m2
????};
??})();
復制代碼
對于依賴的模塊,AMD 是提前執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改成可以延遲執行(根據寫法不同,處理方式不同)。 2. CMD 推崇依賴就近,AMD 推崇依賴前置。
// CMD
define(function(require, exports, module) {
var a=require('./a')
a.doSomething()
// 此處略去 100 行
var b=require('./b') // 依賴可以就近書寫
b.doSomething()
// ...
})
// AMD 默認推薦
define(['./a', './b'], function(a, b) { // 依賴必須一開始就寫好
a.doSomething()
// 此處略去 100 行
b.doSomething()
// ...
})
復制代碼
參考鏈接
參考連接
(1)不要在同一行聲明多個變量 (2)如果你不知道數組的長度,使用 push (3)請使用===/!==來比較 true/false 或者數值 (4)對字符串使用單引號 ''(因為大多時候我們的字符串。特別html會出現") (5)使用對象字面量替代 new Array 這種形式 (6)絕對不要在一個非函數塊里聲明一個函數,把那個函數賦給一個變量。瀏覽器允許你這么做,但是它們解析不同 (7)不要使用全局函數 (8)總是使用 var 來聲明變量,如果不這么做將導致產生全局變量,我們要避免污染全局命名空間 (9)Switch 語句必須帶有 default 分支 (10)使用 /**...*/ 進行多行注釋,包括描述,指定類型以及參數值和返回值 (11)函數不應該有時候有返回值,有時候沒有返回值 (12)語句結束一定要加分號 (13)for 循環必須使用大括號 (14)if 語句必須使用大括號 (15)for-in 循環中的變量應該使用 var 關鍵字明確限定作用域,從而避免作用域污染 (16)避免單個字符名,讓你的變量名有描述意義 (17)當命名對象、函數和實例時使用駝峰命名規則 (18)給對象原型分配方法,而不是用一個新的對象覆蓋原型,覆蓋原型會使繼承出現問題
1)創建新節點 createDocumentFragment() //創建一個DOM片段 createElement() //創建一個具體的元素 createTextNode() //創建一個文本節點 (2)添加、移除、替換、插入 appendChild() removeChild() replaceChild() insertBefore() //在已有的子節點前插入一個新的子節點 (3)查找 getElementsByTagName() //通過標簽名稱 getElementsByName() //通過元素的Name屬性的值(IE容錯能力較強,會得到一個數組,其中包括id等于name值的) getElementById() //通過元素Id,唯一性
參考鏈接
jQuery中沒有提供這個功能,所以你需要先編寫兩個jQuery的擴展:
$.fn.stringifyArray=function(array) {
return JSON.stringify(array)
}
$.fn.parseArray=function(array) {
return JSON.parse(array)
}
然后調用:
$.fn.stringifyArray(array)
復制代碼
// 淺復制
$={
extend : function(target, options) {
for (name in options) {
target[name]=options[name];
}
return target;
}
};
// 深復制
$={
extend : function(deep, target, options) {
for (name in options) {
copy=options[name];
if (deep && copy instanceof Array) {
target[name]=$.extend(deep, [], copy);
} else if (deep && copy instanceof Object) {
target[name]=$.extend(deep, {}, copy);
} else {
target[name]=options[name];
}
}
return target;
}
};
復制代碼
jquery.extend 為jquery類添加類方法,可以理解為添加靜態方法
this===window ? 'browser' : 'node';
復制代碼
參考鏈接
之前推薦的方法(已過時):之前解決這個問題的方法是把script標簽放到body標簽之后 ,這確保了解析到</body>之前都不會被script終端。這個方法是有問題的: 瀏覽器在整個文檔解析完成之前都不能下載script文件,如果文檔很大的話,解析完HTML,用戶依然要等待script文件下載并執行完成之后,才能操作這個網站。
現在推薦的解決方案: 現在瀏覽器script標簽支持 async 和 defer 屬性. 應用這些屬性當script被下載時,瀏覽器更安全而且可以并行下載(下載script并不阻斷HTML解析)。 1.async標記的Script異步執行下載,并執行。這意味著script下載時并不阻塞HTML的解析,并且下載結束script馬上執行。 2.defer標簽的script順序執行。這種方式也不會阻斷瀏覽器解析HTML。 跟 async不同, defer scripts在整個文檔里的script都被下載完才順序執行。
//多個事件同一個函數:
$("div").on("click mouseover", function(){});
//多個事件不同函數
$("div").on({
click: function(){},
mouseover: function(){}
});
復制代碼
參考鏈接
功能檢測、userAgent特征檢測
比如:navigator.userAgent
//"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
復制代碼
polyfill 是“在舊版瀏覽器上復制標準 API 的 JavaScript 補充”,可以動態地加載 JavaScript 代碼或庫,在不支持這些標準 API 的瀏覽器中模擬它們。 例如,geolocation(地理位置)polyfill 可以在 navigator 對象上添加全局的 geolocation 對象,還能添加 getCurrentPosition 函數以及“坐標”回調對象, 所有這些都是 W3C 地理位置 API 定義的對象和函數。因為 polyfill 模擬標準 API,所以能夠以一種面向所有瀏覽器未來的方式針對這些 API 進行開發, 一旦對這些 API 的支持變成絕對大多數,則可以方便地去掉 polyfill,無需做任何額外工作。
html5shiv、Geolocation、Placeholder
按照W3C的標準,先發生捕獲事件,后發生冒泡事件。所有事件的順序是:其他元素捕獲階段事件 -> 本元素代碼順序事件 -> 其他元素冒泡階段事件
// div-capture > btn-bubble > btn-capture > div-bubble
var btn=document.querySelector('button');
var div=document.querySelector('div');
btn.addEventListener('click', function(){
console.log('bubble','btn');
},false);
btn.addEventListener('click', function(){
console.log('capture','btn');
},true);
div.addEventListener('click', function(){
console.log('bubble','div');
},false);
div.addEventListener('click', function(){
console.log('capture','div');
},true);
復制代碼
Webpack編譯期,為需要熱更新的 entry 注入熱更新代碼(EventSource通信)
參考鏈接
網站重構:在不改變外部行為的前提下,簡化結構、添加可讀性,而在網站前端保持一致的行為。 也就是說是在不改變UI的情況下,對網站進行優化,在擴展的同時保持一致的UI。
對于傳統的網站來說重構通常是:
表格(table)布局改為DIV+CSS 使網站前端兼容于現代瀏覽器(針對于不合規范的CSS、如對IE6有效的) 對于移動平臺的優化 針對于SEO進行優化 深層次的網站重構應該考慮的方面
減少代碼間的耦合 讓代碼保持彈性 嚴格按規范編寫代碼 設計可擴展的API 代替舊有的框架、語言(如VB) 增強用戶體驗 通常來說對于速度的優化也包含在重構中
壓縮JS、CSS、image等前端資源(通常是由服務器來解決) 程序的性能優化(如數據讀寫) 采用CDN來加速資源加載 對于JS DOM的優化 HTTP服務器的文件緩存
事件不同之處:
觸發事件的元素被認為是目標(target)。而在 IE 中,目標包含在 event 對象的 srcElement 屬性;
獲取字符代碼、如果按鍵代表一個字符(shift、ctrl、alt除外),IE 的 keyCode 會返回字符代碼(Unicode),DOM 中按鍵的代碼和字符是分離的,要獲取字符代碼,需要使用 charCode 屬性;
阻止某個事件的默認行為,IE 中阻止某個事件的默認行為,必須將 returnValue 屬性設置為 false,Mozilla 中,需要調用 preventDefault() 方法;
停止事件冒泡,IE 中阻止事件進一步冒泡,需要設置 cancelBubble 為 true,Mozzilla 中,需要調用 stopPropagation();
復制代碼
*(優點)因為Node是基于事件驅動和無阻塞的,所以非常適合處理并發請求, 因此構建在Node上的代理服務器相比其他技術實現(如Ruby)的服務器表現要好得多。 此外,與Node代理服務器交互的客戶端代碼是由javascript語言編寫的, 因此客戶端和服務器端都用同一種語言編寫,這是非常美妙的事情。
*(缺點)Node是一個相對新的開源項目,所以不太穩定,它總是一直在變, 而且缺少足夠多的第三方庫支持??雌饋恚拖袷荝uby/Rails當年的樣子。
(1) 減少http請求次數:CSS Sprites, JS、CSS源碼壓縮、圖片大小控制合適;網頁Gzip,CDN托管,data緩存 ,圖片服務器。
(2) 前端模板 JS+數據,減少由于HTML標簽導致的帶寬浪費,前端用變量保存AJAX請求結果,每次操作本地變量,不用請求,減少請求次數
(3) 用innerHTML代替DOM操作,減少DOM操作次數,優化javascript性能。
(4) 當需要設置的樣式很多時設置className而不是直接操作style。
(5) 少用全局變量、緩存DOM節點查找的結果。減少IO讀取操作。
(6) 避免使用CSS Expression(css表達式)又稱Dynamic properties(動態屬性)。
(7) 圖片預加載,將樣式表放在頂部,將腳本放在底部 加上時間戳。
(8) 避免在頁面的主體布局中使用table,table要等其中的內容完全下載之后才會顯示出來,顯示比div+css布局慢。
對普通的網站有一個統一的思路,就是盡量向前端優化、減少數據庫操作、減少磁盤IO。向前端優化指的是,在不影響功能和體驗的情況下,能在瀏覽器執行的不要在服務端執行,能在緩存服務器上直接返回的不要到應用服務器,程序能直接取得的結果不要到外部取得,本機內能取得的數據不要到遠程取,內存能取到的不要到磁盤取,緩存中有的不要去數據庫查詢。減少數據庫操作指減少更新次數、緩存結果減少查詢次數、將數據庫執行的操作盡可能的讓你的程序完成(例如join查詢),減少磁盤IO指盡量不使用文件系統作為緩存、減少讀寫文件次數等。程序優化永遠要優化慢的部分,換語言是無法“優化”的。
復制代碼
1**(信息類):表示接收到請求并且繼續處理 100——客戶必須繼續發出請求 101——客戶要求服務器根據請求轉換HTTP協議版本
2**(響應成功):表示動作被成功接收、理解和接受
200——表明該請求被成功地完成,所請求的資源發送回客戶端
201——提示知道新文件的URL
202——接受和處理、但處理未完成
203——返回信息不確定或不完整
204——請求收到,但返回信息為空
205——服務器完成了請求,用戶代理必須復位當前已經瀏覽過的文件
206——服務器已經完成了部分用戶的GET請求
3**(重定向類):為了完成指定的動作,必須接受進一步處理
300——請求的資源可在多處得到
301——本網頁被永久性轉移到另一個URL
302——請求的網頁被轉移到一個新的地址,但客戶訪問仍繼續通過原始URL地址,重定向,新的URL會在response中的Location中返回,瀏覽器將會使用新的URL發出新的Request。
303——建議客戶訪問其他URL或訪問方式
304——自從上次請求后,請求的網頁未修改過,服務器返回此響應時,不會返回網頁內容,代表上次的文檔已經被緩存了,還可以繼續使用
305——請求的資源必須從服務器指定的地址得到
306——前一版本HTTP中使用的代碼,現行版本中不再使用
307——申明請求的資源臨時性刪除
4**(客戶端錯誤類):請求包含錯誤語法或不能正確執行
400——客戶端請求有語法錯誤,不能被服務器所理解
401——請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用
HTTP 401.1 - 未授權:登錄失敗
??HTTP 401.2 - 未授權:服務器配置問題導致登錄失敗
??HTTP 401.3 - ACL 禁止訪問資源
??HTTP 401.4 - 未授權:授權被篩選器拒絕
HTTP 401.5 - 未授權:ISAPI 或 CGI 授權失敗
402——保留有效ChargeTo頭響應
403——禁止訪問,服務器收到請求,但是拒絕提供服務
HTTP 403.1 禁止訪問:禁止可執行訪問
??HTTP 403.2 - 禁止訪問:禁止讀訪問
??HTTP 403.3 - 禁止訪問:禁止寫訪問
??HTTP 403.4 - 禁止訪問:要求 SSL
??HTTP 403.5 - 禁止訪問:要求 SSL 128
??HTTP 403.6 - 禁止訪問:IP 地址被拒絕
??HTTP 403.7 - 禁止訪問:要求客戶證書
??HTTP 403.8 - 禁止訪問:禁止站點訪問
??HTTP 403.9 - 禁止訪問:連接的用戶過多
??HTTP 403.10 - 禁止訪問:配置無效
??HTTP 403.11 - 禁止訪問:密碼更改
??HTTP 403.12 - 禁止訪問:映射器拒絕訪問
??HTTP 403.13 - 禁止訪問:客戶證書已被吊銷
??HTTP 403.15 - 禁止訪問:客戶訪問許可過多
??HTTP 403.16 - 禁止訪問:客戶證書不可信或者無效
HTTP 403.17 - 禁止訪問:客戶證書已經到期或者尚未生效
404——一個404錯誤表明可連接服務器,但服務器無法取得所請求的網頁,請求資源不存在。eg:輸入了錯誤的URL
405——用戶在Request-Line字段定義的方法不允許
406——根據用戶發送的Accept拖,請求資源不可訪問
407——類似401,用戶必須首先在代理服務器上得到授權
408——客戶端沒有在用戶指定的餓時間內完成請求
409——對當前資源狀態,請求不能完成
410——服務器上不再有此資源且無進一步的參考地址
411——服務器拒絕用戶定義的Content-Length屬性請求
412——一個或多個請求頭字段在當前請求中錯誤
413——請求的資源大于服務器允許的大小
414——請求的資源URL長于服務器允許的長度
415——請求資源不支持請求項目格式
416——請求中包含Range請求頭字段,在當前請求資源范圍內沒有range指示值,請求也不包含If-Range請求頭字段
417——服務器不滿足請求Expect頭字段指定的期望值,如果是代理服務器,可能是下一級服務器不能滿足請求長。
5**(服務端錯誤類):服務器不能正確執行一個正確的請求
HTTP 500 - 服務器遇到錯誤,無法完成請求
??HTTP 500.100 - 內部服務器錯誤 - ASP 錯誤
??HTTP 500-11 服務器關閉
??HTTP 500-12 應用程序重新啟動
??HTTP 500-13 - 服務器太忙
??HTTP 500-14 - 應用程序無效
??HTTP 500-15 - 不允許請求 global.asa
??Error 501 - 未實現
HTTP 502 - 網關錯誤
HTTP 503:由于超載或停機維護,服務器目前無法使用,一段時間后可能恢復正常
復制代碼
而高手可以根據自己擅長的領域自由發揮,從URL規范、HTTP協議、DNS、CDN、數據庫查詢、 到瀏覽器流式解析、CSS規則構建、layout、paint、onload/domready、JS執行、JS API綁定等等;
詳細版:
1、瀏覽器會開啟一個線程來處理這個請求,對 URL 分析判斷如果是 http 協議就按照 Web 方式來處理;
2、調用瀏覽器內核中的對應方法,比如 WebView 中的 loadUrl 方法;
3、通過DNS解析獲取網址的IP地址,設置 UA 等信息發出第二個GET請求;
4、進行HTTP協議會話,客戶端發送報頭(請求報頭);
5、進入到web服務器上的 Web Server,如 Apache、Tomcat、Node.JS 等服務器;
6、進入部署好的后端應用,如 PHP、Java、JavaScript、Python 等,找到對應的請求處理;
7、處理結束回饋報頭,此處如果瀏覽器訪問過,緩存上有對應資源,會與服務器最后修改時間對比,一致則返回304;
8、瀏覽器開始下載html文檔(響應報頭,狀態碼200),同時使用緩存;
9、文檔樹建立,根據標記請求所需指定MIME類型的文件(比如css、js),同時設置了cookie;
10、頁面開始渲染DOM,JS根據DOM API操作DOM,執行事件綁定等,頁面顯示完成。
復制代碼
js秘密花園 jquery原理解析 css3 js標準
var pattern=/^([A-Za-z0-9_\-\.\u4e00-\u9fa5])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,8})$/;
復制代碼
參考鏈接
readyState屬性有五個狀態值。
0:是uninitialized,未初始化。已經創建了XMLHttpRequest對象但是未初始化。
1:是loading.已經開始準備好要發送了。
2:已經發送,但是還沒有收到響應。
3:正在接受響應,但是還不完整。
4:接受響應完畢。
responseText:服務器返回的響應文本。只有當readyState>=3的時候才有值,根據readyState的狀態值,可以知道,當readyState=3,返回的響應文本不完整,只有readyState=4,完全返回,才能接受全部的響應文本。
responseXML:response as Dom Document object。響應信息是xml,可以解析為Dom對象。
status:服務器的Http狀態碼,若是200,則表示OK,404,表示為未找到。
statusText:服務器http狀態碼的文本。比如OK,Not Found。
復制代碼
參考鏈接
參考鏈接
復制代碼
優點:1.保護函數內部變量的安全,加強了封裝性 2.在內存中維持一個變量 3.設計私有方法和變量 4.可以讀取函數內部的變量 缺點:1.導致內存泄漏,使用不當會造成額外的內存占用 2.可以改變父函數的變量,所以使用時要謹慎
1.從圖像類別區分,Canvas是基于像素的位圖,而SVG卻是基于矢量圖形??梢院唵蔚陌褍烧叩膮^別看成photoshop與illustrator的區別。 2.從結構上說,Canvas沒有圖層的概念,所有的修改整個畫布都要重新渲染,而SVG則可以對單獨的標簽進行修改。 3.從操作對象上說,Canvas是基于HTML canvas標簽,通過宿主提供的Javascript API對整個畫布進行操作的,而SVG則是基于XML元素的。 4.從功能上講,SVG發布日期較早,所以功能相對Canvas比較完善。 5.關于動畫,Canvas更適合做基于位圖的動畫,而SVG則適合圖表的展示。 6.從搜索引擎角度分析,由于svg是有大量標簽組成,所以可以通過給標簽添加屬性,便于爬蟲搜索
//目前,像Chrome/Filefox/Safari/IE9+以及最新版本Opera都支持硬件加速,當檢測到某個DOM元素應用了某些CSS規則時就會自動開啟,從而解決頁面閃白,保證動畫流暢。
.css {
-webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
復制代碼
<button></button>元素一定要寫上type屬性不然會默認提交表單,出現想不到的bug
復制代碼
html,body{
overflow: hidden;/*手機上寫overflow-x:hidden;會有兼容性問題,如果子級如果是絕對定位有運動到屏幕外的話ios7系統會出現留白*/
-webkit-overflow-scrolling:touch;/*流暢滾動,ios7下會有滑一下滑不動的情況,所以需要寫上*/
position:realtive;/*直接子級如果是絕對定位有運動到屏幕外的話,會出現留白*/
}
復制代碼
.overflow-hidden{
display: box !important;
display: -webkit-box !important;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;/*第幾行出現省略號*/
/*text-align:justify;不能和溢出隱藏的代碼一起寫,會有bug*/
}
復制代碼
.element {
-webkit-touch-callout: none;
}
復制代碼
::-webkit-input-placeholder { /* WebKit browsers */
color: #999; }
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color: #999; }
::-moz-placeholder { /* Mozilla Firefox 19+ */
color: #999; }
:-ms-input-placeholder { /* Internet Explorer 10+ */
color: #999; }
input:focus::-webkit-input-placeholder{ color:#999; }
復制代碼
//JS綁定自動播放(操作window時,播放音樂)
$(window).one('touchstart', function(){
music.play();
})
//微信下兼容處理
document.addEventListener("WeixinJSBridgeReady", function () {
music.play();
}, false);
復制代碼
消除transition閃屏
.css {
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
}
復制代碼
文中如有一些不足,歡迎指正。筆者1天后將推出開源的CMS系統,技術架構:
后面將推出該系統的設計思想,架構和實現過程,歡迎在公眾號《趣談前端》里查看更詳細的介紹。
原鏈接:https://juejin.im/post/5d8989296fb9a06b1f147070
*請認真填寫需求信息,我們會在24小時內與您取得聯系。