### 你真的了解script標簽嗎?
先來看一個簡單的html文檔:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Examples</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href=".style.css" rel="stylesheet">
<script src="./app.js"></script>
</head>
<body>
<h1>hello Word</h1>
</body>
</html>
```
這是一份最簡單不過的html文檔了,我們只關注script標簽,js的加載就可以了。
還有常見的這樣的:
```
……
<script src="./jquery.js"></script>
<script src="./jquery.xxx.js"></script>
……
```
我們都知道依賴于jQuery的插件必須放在jQuery加載之后引入,否則會出錯。
所以我們將插件加載的script標簽寫在后面,這樣就不會出錯了。
但是有一個問題,我們這樣寫真的能保證jQuery在之前加載嗎,如果jQuery的cdn很慢呢,瀏覽器一定會保證加載順序一定是按照我們寫的順序嗎?以script標簽的形式加載時瀏覽器是串行加載的嗎?
是的,瀏覽器的確是保證加載順序**按照我們寫的script標簽的順序來依次加載并執行**(注意這里強調的**按照書寫的script標簽的順序**,**依次加載并執行**),并且保證是串行加載的,所以我們這樣寫代碼沒有問題。所以如果cdn很慢,那么頁面會一直卡在那里顯示白屏,不會解析內容給用戶,并且你可以嘗試一下,在./app.js里面寫一個死循環也是這樣的,也就是說**瀏覽器是單進程執行js和加載js的,并且解析html和執行js也是單進程的,是阻塞的**,這種特性很多時候我們很容易感受到,比如彈窗時頁面會“卡住”,加載時頁面白屏等等,所以通常我們都建議不重要的js放在文檔的最后body標簽的前面就可以了,這樣不會阻塞頁面解析渲染。
(其實這里面瀏覽器有很復雜的細節,DOM書寫順序是執行順序沒錯,但是加載是串行阻塞的還是并行的瀏覽器有自己的策略吧,這里面涉及的細節很復雜,不過可以肯定的是,DOM的順序就表示了依賴關系,依賴的要寫在上面,并且script的特性就是加載了就會執行里面的腳本,所以上面說加載并執行)
> 但為了不破壞您的頁面渲染,我們還是建議您將涉及到javascript標簽的代碼,放到頁面的最底部。
([百度分享](http://share.baidu.com/help/installation?type=icon)代碼安裝也是這樣說明的)
為了簡單,確保程序按照我們預期的運行,我們一直以來就是這樣寫script標簽嗎,并且它也是按照我們所想的運行,沒有問題,但其實我們忽略了script標簽的更多細節。
他還有兩個很有用的參數,很多時候我們并沒有使用過,甚至不知道。因為在我們的印象里面,瀏覽器按照寫標簽的順序來依次加載,同時阻塞頁面,這似乎是天經地義的,但其實有一些場景我們還是需要用到異步加載,異步執行的,這是就不會阻塞瀏覽器解析html給用戶了,那么就不會顯示白屏了,此時只會瀏覽器一直顯示加載狀態,但是頁面已經呈現給用戶了。
* * * * *
### 思考
**如何實現js非阻塞、并行加載,甚至能保持執行順序呢?**
對于外部js我們的理解是“按照書寫順序依次加載并執行”(并且默認會阻塞瀏覽器的繼續解析和渲染),雖然是這樣的,但其實瀏覽器實際處理時不是這樣的,不過我們平時這么說也沒有錯,但是最好還是要理解瀏覽器究竟是怎么做的。(如果依次/串行加載資源那效率太低了)
瀏覽器是可以并行加載資源的,而網絡資源加載速度可能不同,那么如果是并行加載資源,就不可能是按順序的加載完成了,那么瀏覽器是怎么保證“按順序執行”呢?其實這里有一個機制,我們暫時稱**X機制**,X機制能夠保證瀏覽器最大效率的并行加載資源,但是資源加載完畢后并不立即被解析執行,而是被瀏覽器引擎“緩存”著了,直到最前依賴的加載完才會解析執行,比如同時加載1,2,3三個資源,2先返回,緩存著,3接著返回,繼續緩存著,1返回,由于1是最前依賴,所以執行1,2已經返回了,直接執行,3同理,否則等待返回。也就是說,X機制在并行加載資源時,**保證JS執行順序和書寫順序/依賴順序一致,盡管它們的加載順序不是一致的。** 即:瀏覽器要能夠實現js非阻塞、并行加載,并且能保持執行順序和書寫順序一致。
不過我們平常并不需要知道這個機制,這是瀏覽器內部的機制,**對我們來說,按照書寫順序依次加載并執行”這樣說也是沒錯的,至少我們看到的代碼就是這樣運行的。**
~~~text
阮老師請教下,外部js的加載方式是:“按照書寫順序依次加載并執行”(并且默認會阻塞瀏覽器的繼續解析和渲染),但其實瀏覽器并不是串行加載資源的,而是并行加載的(最大6個資源一起加載),如果是并行加載資源的,那么資源返回時間可能都不一樣,那怎么保證加載完成按照順序執行呢。這里面有些細節還不是很明白,不知道阮老師有沒有寫過類似的文章。謝謝。
不是“一起加載”,是“一起下載”。
(下載不等同于加載;下載:單純的網絡請求,文件下載。加載:包含下載和下載后的其它處理。)
~~~
> 或許這是我猜想的,對于普通的外部js,瀏覽器就是串行加載,依次加載并執行的。
[javascript在html中的加載順序 - CBDoctor - 博客園](https://www.cnblogs.com/CBDoctor/p/3745246.html)
[淺析JavaScript執行順序 ? 邵珠慶の博客](http://shaozhuqing.com/?p=2756)
[Javascript 裝載和執行 | | 酷 殼 - CoolShell](https://coolshell.cn/articles/9749.html)
> 對于IE來說,這個標簽會讓IE并行下載js文件,并且把其執行hold到了整個DOM裝載完畢(DOMContentLoaded),多個defer的\<script\>在執行時也會按照其出現的順序來運行。**(就是我上面說的X機制)**
[JavaScript并發下載 | 四火的嘮叨](http://www.raychase.net/123)
[js的并行加載與順序執行 - Hello.NET - 博客園](https://www.cnblogs.com/mfc-itblog/p/5938851.html)
[headjs實現網站并行加載但順序執行JS_javascript技巧_腳本之家](http://www.jb51.net/article/98595.htm)
[js并行加載,順序執行 - CSDN博客](http://blog.csdn.net/yemou_blog/article/details/50292339)
> 并行加載與順序執行
[JS異步加載的三種方式 - CSDN博客](http://blog.csdn.net/l522703297/article/details/50754695)
[JS模塊加載器加載原理是怎么樣的? - 知乎](https://www.zhihu.com/question/21157540)
> 原理我用大白話告訴你,通過一個入口,加載所有依賴,每次完成一次onload,查看是否還有未完成和未開始的腳本,一直到最后一個加載完畢(加載過程是不阻塞的,當然也還是會分級)之后,按照依賴關系依次執行,結果保存到cache,下次再跑,就不執行了,確保factory只執行一次。
[瀏覽器加載 JS 文件的先后順序同具體的解析和執行有什么關系? - 知乎](https://www.zhihu.com/question/20531965)
[前端 - 瀏覽器的并行加載機制是怎樣的? - SegmentFault](https://segmentfault.com/q/1010000008784923)
* * * * *
[【requireJS源碼學習03】細究requireJS的加載流程 - 葉小釵 - 博客園](https://www.cnblogs.com/yexiaochai/p/3650379.html)
> 執行checkLoaded方法,這里會開始遞歸的檢查模塊是否加載結束,一定要在主干模塊depCount為0 時候才會執行其回調。(每次onload都檢查就能知道是否全部加載完畢了)
[requireJS原理解析 - CSDN博客](http://blog.csdn.net/cde7070/article/details/65935888)
requireJS是通過動態創建\<script\>標簽的方式加載資源的,這樣雖然可以以 **異步不阻塞并行的方式加載文件** ,但是卻無法保持執行順序。不過也沒事,每次完成一次onload就檢查是否加載完全部依賴,等到全部加載完成后才執行回調,這樣也是沒問題的。但是對于不標準的AMD庫,那就沒辦法了,畢竟標準的庫都是define,factory在回調里面,所以即使加載完成也沒有執行factory,但是非標準的就不同了,只要加載了就會立即執行,不知道對于這種情況是怎么處理的。(關于模塊化怎么支持的可以看這里,[js.cookie.js](https://github.com/js-cookie/js-cookie/blob/master/src/js.cookie.js)、[layer.js](https://github.com/sentsin/layer/blob/master/src/layer.js))
估計對于非標準的AMD文件,requireJS不是采用的\<script\>標簽的方式加載資源的吧。
由于requireJS的加載機制,并行加載,加載就執行腳本(腳本文件執行了而是factory),所以執行順序是得不到保障的,保障的只是factory執行順序和入口的回調。所以這里就有一個問題需要注意,**模塊里面factory最好不要有單獨直接部分,即使有,一定不要有依賴,否則就會出現依賴不存在的問題,所以一定要注意這點。**
* * * * *
### 擴展
試想一下如果某個cdn壞了,那么頁面會一直顯示加載白屏嗎?
做個試驗就知道了,其實瀏覽器都有一個超時時間,如果超時沒有返回,那么會加載失敗,瀏覽器就會放棄加載這個js,直接跳過了,如果之后的js依賴這個文件,那么就有可能會出問題了。
```
加載失敗,報錯:
GET http://h.qhimg.com/js/iwt.js net::ERR_CONNECTION_TIMED_OUT
```
至于css的加載,可以參考link標簽,link標簽沒有這些復雜的其他參數,它就很簡單,很單純,那就是按標簽書寫順序依次加載,并且同步阻塞的,所以頁面重要樣式一定要寫在head里面,不然可能會出現用戶看到一個壞的頁面,然后突然又好了,所以樣式一般都放在頭部,這沒有什么可說的,對于cdn壞掉還是跟js一樣的,有一個超時時間,加載失敗接。
不過要注意上面有一些表現在不同瀏覽器上面可能是不同的。
#### 名詞解釋:
**同步(sync),是串行,阻塞的**
**異步(Asynchronous ),是并行,非阻塞的**
> 這兩組詞往往都是成組出現的
## 參考
```
處理腳本和樣式表的順序
腳本
網絡的模型是同步的。網頁作者希望解析器遇到 <script> 標記時立即解析并執行腳本。文檔的解析將停止,直到腳本執行完畢。如果腳本是外部的,那么解析過程會停止,直到從網絡同步抓取資源完成后再繼續。此模型已經使用了多年,也在 HTML4 和 HTML5 規范中進行了指定。作者也可以將腳本標注為“defer”,這樣它就不會停止文檔解析,而是等到解析結束才執行。HTML5 增加了一個選項,可將腳本標記為異步,以便由其他線程解析和執行。
預解析
Webkit 和 Firefox 都進行了這項優化。在執行腳本時,其他線程會解析文檔的其余部分,找出并加載需要通過網絡加載的其他資源。通過這種方式,資源可以在并行連接上加載,從而提高總體速度。請注意,預解析器不會修改 DOM 樹,而是將這項工作交由主解析器處理;預解析器只會解析外部資源(例如外部腳本、樣式表和圖片)的引用。
樣式表
另一方面,樣式表有著不同的模型。理論上來說,應用樣式表不會更改 DOM 樹,因此似乎沒有必要等待樣式表并停止文檔解析。但這涉及到一個問題,就是腳本在文檔解析階段會請求樣式信息。如果當時還沒有加載和解析樣式,腳本就會獲得錯誤的回復,這樣顯然會產生很多問題。這看上去是一個非典型案例,但事實上非常普遍。Firefox 在樣式表加載和解析的過程中,會禁止所有腳本。而對于 Webkit 而言,僅當腳本嘗試訪問的樣式屬性可能受尚未加載的樣式表影響時,它才會禁止該腳本。
```
- [前端文摘:深入解析瀏覽器的幕后工作原理 - 夢想天空(山邊小溪) - 博客園](http://www.cnblogs.com/lhb25/p/how-browsers-work.html#Webkit_CSS_parser)
- [HTML <link> 標簽](http://www.w3school.com.cn/tags/tag_link.asp)
- [HTML \<script\> 標簽](http://www.w3school.com.cn/tags/tag_script.asp)
- [JavaScript 使用](http://www.w3school.com.cn/js/js_howto.asp)
- [深入淺出JavaScript (五) 詳解Document.write()方法](http://blog.csdn.net/jiaolong724/article/details/8532828)
- [讓我們再聊聊瀏覽器資源加載優化](http://kb.cnblogs.com/page/211942/)
- [瀏覽器允許的并發請求資源數是什么意思?](https://www.zhihu.com/question/20474326)
- [“不同瀏覽器對于同一域名的并發獲取(加載)資源數是有限的” - 明明是悟空](http://www.tuicool.com/articles/maU7B3a)
- [詳解瀏覽器最大并發連接數](http://www.iefans.net/liulanqi-zuida-bingfa-lianjieshu/)
- [現代瀏覽器的工作原理](http://blog.jobbole.com/12749/)
- [前端必讀:瀏覽器內部工作原理](http://kb.cnblogs.com/page/129756/)
- [瀏覽器中Javascript的加載原理](http://blog.csdn.net/u012758088/article/details/54572673)
- [瀏覽器加載和渲染原理分析 ](http://blog.chinaunix.net/uid-24603373-id-220310.html)
- [html頁面加載原理和瀏覽器應用程序交互原理](http://blog.csdn.net/ndcnb/article/details/51473667)
- [JS模塊加載器加載原理是怎么樣的?](https://www.zhihu.com/question/21157540)
- [關于瀏覽器處理新加入的JS,CSS方式原理](http://www.iteye.com/problems/7598)
- [JS \<script\>標簽詳解](http://www.itxueyuan.org/view/6611.html)
- [瀏覽器中JavaScript執行原理](http://www.cnblogs.com/inJS/p/4912843.html)
- [動態加載script文件的兩種方法](http://www.jb51.net/article/40623.htm)
- [js在html中的加載執行順序](http://www.cnblogs.com/lindaWei/archive/2012/04/05/2433454.html)
- [前端必讀:瀏覽器內部工作原理](http://kb.cnblogs.com/page/129756/)
- [淺談Html的內容加載及JS執行順序](http://www.2cto.com/kf/201507/415672.html)
- [網站性能優化-將Script放到HTML文件中盡量靠近尾部原理](http://blog.csdn.net/spring21st/article/details/6192831)
- [瀏覽器加載、解析、渲染的過程](http://blog.csdn.net/xiaozhuxmen/article/details/52014901)
- [瀏覽器渲染頁面過程](http://www.cnblogs.com/chenlogin/p/5221562.html)
- [瀏覽器~加載,解析,渲染](http://www.jianshu.com/p/e141d1543143)
- [淺析瀏覽器渲染頁面過程](http://blog.csdn.net/yuhk231/article/details/53581212)
- [面試的時候人家問瀏覽器渲染過程 這個怎么答? ](https://zhidao.baidu.com/question/395315056469060285.html)
- [我的前端進階學習(一)—— 模塊化開發](http://www.imooc.com/m/wap/article/detail.html?aid=6911)
- [Javascript模塊化編程(一):模塊的寫法](http://www.ruanyifeng.com/blog/2012/10/javascript_module.html)
- [Javascript模塊化編程(二):AMD規范](http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html)
- [Javascript模塊化編程(三):require.js的用法](http://www.ruanyifeng.com/blog/2012/11/require_js.html)
- [瀏覽器加載 CommonJS 模塊的原理與實現](http://www.ruanyifeng.com/blog/2015/05/commonjs-in-browser.html)
- [SeaJS 所為何](http://cyj.me/why-seajs/zh/)
- [RequireJS 其一](http://cyj.me/why-seajs/requirejs/)
- [JS模塊化](http://www.hmoore.net/xiak/quanduan/254621)
- [DNS 原理入門](http://www.ruanyifeng.com/blog/2016/06/dns.html)
- [瀏覽器工作原理(瀏覽器內核 即渲染)](http://blog.sina.com.cn/s/blog_6fb22e5b010117s0.html)
- [瀏覽器的工作原理:現代網絡瀏覽器幕后揭秘](http://blog.sina.com.cn/s/blog_6deafdb2010146bt.html)
- [事件DOMContentLoaded和load的區別](http://www.jianshu.com/p/d851db5f2f30)
- [HTML 5 \<script\> async 屬性](http://www.w3school.com.cn/tags/att_script_async.asp)
> 如果既不使用 async 也不使用 defer:**在瀏覽器繼續解析頁面之前,立即讀取并執行腳本**
- [JS學習筆記(一)——JS的阻塞特性 - MeteorSeed - 博客園](http://www.cnblogs.com/MeteorSeed/articles/2283629.html)
> JS具有阻塞特性,當瀏覽器在執行js代碼時,不能同時做其它事情,即\<script\>每次出現都會讓頁面等待腳本的解析和執行(不論JS是內嵌的還是外鏈的),JS代碼執行完成后,才繼續渲染頁面。
- [現代瀏覽器性能優化-JS篇 · Issue #2 · GeoffZhu/geoffzhu.github.io](https://github.com/GeoffZhu/geoffzhu.github.io/issues/2)
- [現代瀏覽器性能優化-CSS篇 - 掘金](https://juejin.im/post/5a461f006fb9a0450408358f)
- [前端工程師必備——瀏覽器渲染原理詳解!](https://www.toutiao.com/a6506267555328426499/?tt_from=weixin&utm_campaign=client_share×tamp=1514909819&app=news_article&utm_source=weixin&iid=22069500288&utm_medium=toutiao_android&wxshare_count=1)
### 其它
正因為“按照書寫的script標簽的順序,依次加載并執行”,那么利用這個特性,可以實現,js腳本獲取自身路徑,[layer mobile](https://github.com/sentsin/layer/blob/2.x/src/mobile/layer.js)就是這么做的
里面有類似于這樣的代碼:
~~~javascript
var js = document.scripts, script = js[js.length - 1], jsPath = script.src;
var path = jsPath.substring(0, jsPath.lastIndexOf("/") + 1);
//如果合并方式,則需要單獨引入layer.css
if(script.getAttribute('merge')) return;
document.head.appendChild(function(){
var link = doc.createElement('link');
link.href = path + 'need/layer.css?2.0';
link.type = 'text/css';
link.rel = 'styleSheet'
link.id = 'layermcss';
return link;
}());
~~~
關鍵是這個`document.scripts`,巧妙的利用了“一次加載并執行”。
那么問題來了,如果使用了模塊化后,sea.js或者require.js這樣的加載方式之后,那么勢必就會改變這種情況,這種獲取當前腳本路徑的方式就不行了。
來看看,pc版的layer,也是這種方式。
好吧。
require.js其實沒什么問題,sea.js就不行了,因為他是,盡可能的懶啊,盡可能的懶解析(執行),所以就會存在問題。
從layer的暴露模塊支持代碼就可以看出來,它不支持sea.js哦:
~~~javascript
//加載方式
window.layui && layui.define ? (
layer.ready()
,layui.define('jquery', function(exports){ //layui加載
layer.path = layui.cache.dir;
ready.run(layui.jquery);
//暴露模塊
window.layer = layer;
exports('layer', layer);
})
) : (
(typeof define === 'function' && define.amd) ? define(['jquery'], function(){ //requirejs加載
ready.run(window.jQuery);
return layer;
}) : function(){ //普通script標簽加載
ready.run(window.jQuery);
layer.ready();
}()
);
~~~
它支持三種方式:layui、require.js,普通script標簽,唯獨不支持sea.js,我們去社區看看sea.js支持方面的問題,果不奇然。
[layui.all 用sea js 載入會提示 css 路徑不對的錯誤](https://fly.layui.com/jie/11504/)
[請問sea如何使用layer](http://fly.layui.com/jie/7458/)
> 不建議采用seajs
如果使用了sea.js那么需要自己配置腳本所在路徑了,這種方式就行不通了。
[加快構建 DOM: 使用預解析, async, defer 以及 preload](http://mp.weixin.qq.com/s/CCjhMqiNNvjo-46FykN0UA)
> 在過去,為了執行一個腳本,HTML 的解析必須暫停。只有在 JavaScript 引擎執行完代碼之后它才會重新開始解析。……
[Web圖片資源的加載與渲染時機](https://segmentfault.com/a/1190000010032501?v=2017082201)
[前端性能優化之 DOM 篇 - 關人潮的博客 | FSUX Blog](http://fsux.me/%E9%9A%8F%E7%AC%94/%E6%9E%B6%E6%9E%84/%E6%B5%85%E8%B0%88%E5%89%8D%E7%AB%AF/2017/04/13/Front-end-performance-optimization-dom.html)
[從輸入 URL 到頁面加載完成的過程中都發生了什么事情?](http://fex.baidu.com/blog/2014/05/what-happen/)
[HTTP 緩存機制一二三 - 知乎專欄](https://zhuanlan.zhihu.com/p/29750583?group_id=901822939576557568)
[漫畫揭秘一個超快的渲染引擎(上)](http://mp.weixin.qq.com/s/EAZUXq7RC6W9rWhRdE-7Ew)
[漫畫揭秘一個超快的渲染引擎(下)](http://mp.weixin.qq.com/s/u8xUnB8nXWv_cvnVScAwoQ)
[前端開發工程師必須關注的幾個性能指標](http://mp.weixin.qq.com/s/JV4yRQkkvsRxgwj3gw3zkQ)
[這么多前端優化點你都記得住嗎?](http://mp.weixin.qq.com/s/QSakBZH5i_CfkPz4RHeFKg)
[如何打造一個全滿分網站](http://mp.weixin.qq.com/s/NR_9y83sja-LjVzBs4viwA)
[如何打造一個安全滿分網站](http://mp.weixin.qq.com/s/5CdnIN3eeAkux7rGJHjiyQ)
[瀏覽器「內核」都做了些什么?](https://mp.weixin.qq.com/s/JwUoIM2jcxbOd_5Mox4r-w)
[Webpack HMR 原理解析](http://mp.weixin.qq.com/s/eHFAYzX9GnxcixIjeMqojQ)
[Web靜態資源緩存及優化](https://zhuanlan.zhihu.com/p/30780216)
[從Chrome源碼看瀏覽器如何加載資源 – 人人網FED博客](https://fed.renren.com/2017/10/29/chrome-fetch-resource/)
[文字編碼的那些事 – 人人網FED博客](https://fed.renren.com/2017/11/11/text-encode/)
[瀏覽器:一個家族的奮斗](http://mp.weixin.qq.com/s/5mOPs9Vcl0VNq4NAjdRPAg)
[火狐瀏覽器是如何又變快起來的?](https://mp.weixin.qq.com/s/ZTfqw_ECZCNqxifXGqfqwQ)
[【年底補課】HTTP緩存機制](https://mp.weixin.qq.com/s/HlJKEXk7q-f1n8va2RLZdA)
[曾是最強瀏覽器!Firefox是如何漸漸走向沒落的_觀點評論_太平洋電腦網PConline](http://pcedu.pconline.com.cn/938/9388346_all.html#content_page_2)
> 作為一個非營利性組織,Mozilla的目的是讓瀏覽器市場多姿多彩,避免一家獨大。Firefox一路走來,已經出色地詮釋了這個使命。
[從輸入網址到瀏覽器呈現頁面內容,中間發生了什么?](http://mp.weixin.qq.com/s/q9wDvplWysHCn_Bet8j5lA)
[標準模式與怪異模式對渲染頁面的影響](https://mp.weixin.qq.com/s/Y0l5YK68bi5A1KI2dhYf1w)
[瀏覽器家族的安全反擊戰](http://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665514143&idx=1&sn=28ea209c00309e6b93d8d1f76032d7a4&chksm=80d67cdcb7a1f5ca81d8d454a98af56d58b22f6058f100e21ff30e70867ea6e3e922a4f000bf&scene=21#wechat_redirect)
> 同源 & 安全:這些安全策略都是瀏覽器制定的,假如瀏覽器也不安全,我電腦的瀏覽器被黑客攻擊了,那么怎么辦?
>
> 沒轍了,你的核心被攻占, 除非你把瀏覽器或者OS重裝了
[HTML 文檔之 Head 最佳實踐](https://mp.weixin.qq.com/s/GF3HPhFrXll6eEI8crJCaw)
[談談web前端緩存](https://www.toutiao.com/a6505280890388611597/?tt_from=weixin&utm_campaign=client_share×tamp=1514707129&app=news_article&utm_source=weixin&iid=22069500288&utm_medium=toutiao_android&wxshare_count=1)
[淺談瀏覽器 http 的緩存機制](https://mp.weixin.qq.com/s/qSN5yaNmuMysG71229qC-Q)
[讓我們再聊聊瀏覽器資源加載優化 – 前端技術漫游指南](http://qingbob.com/let-us-talk-about-resource-load/)
[Range/Content-Range與斷點續傳,了解一下? - 掘金](https://juejin.im/post/5acac9f5f265da239531463f)
[web beacon - jvava - 博客園](https://www.cnblogs.com/jvava/p/3926539.html)
* * * * *
last update:2018-1-22 22:09:31
- 開始
- 微信小程序
- 獲取用戶信息
- 記錄
- HTML
- HTML5
- 文檔根節點
- 你真的了解script標簽嗎?
- 文檔結構
- 已經落后的技術
- form表單
- html實體
- CSS
- css優先級 & 設計模式
- 如何編寫高效的 CSS 選擇符
- 筆記
- 小計
- flex布局
- 細節體驗
- Flex
- Grid
- tailwindcss
- JavaScript
- javascript物語
- js函數定義
- js中的數組對象
- js的json解析
- js中數組的操作
- js事件冒泡
- js中的判斷
- js語句聲明會提前
- cookie操作
- 關于javascript你要知道的
- 關于innerHTML的試驗
- js引擎與GUI引擎是互斥的
- 如何安全的修改對象
- 當渲染引擎遇上強迫癥
- 不要使用連相等
- 修改數組-對象
- 算法-函數
- 事件探析
- 事件循環
- js事件循環中的上下文和作用域的經典問題
- Promise
- 最佳實踐
- 頁面遮罩加載效果
- 網站靜態文件之思考
- 圖片加載問題
- 路由及轉場解決方案
- web app
- 寫一個頁面路由轉場的管理工具
- 談編程
- 技術/思想的斗爭
- 前端技術選型分析
- 我想放點html模板代碼
- 開發自適應網頁
- 后臺前端項目的開發
- 網站PC版和移動版的模板方案
- 前后端分離
- 淘寶前后端分離
- 前后端分離的思考與實踐(一)
- 前后端分離的思考與實踐(二)
- 前后端分離的思考與實踐(三)
- 前后端分離的思考與實踐(四)
- 前后端分離的思考與實踐(五)
- 前后端分離的思考與實踐(六)
- 動畫
- 開發小技巧
- Axios
- 屏幕適配
- 理論基礎
- 思考
- flexible.js原理
- 實驗
- rem的坑,為什么要設置成百分比,為什么又是62.5%
- 為什么以一個標準適配的,其它寬度也能同等適配
- 自適應、響應式、彈性布局、屏幕適配
- 適配:都用百分比?
- 番外篇
- 給你看看0.5px長什么樣?
- 用事實證明viewport scale縮放不會改變rem元素的大小
- 為什么PC端頁面縮放不會影響rem元素
- 究竟以哪個為設備獨立像素
- PC到移動端初試
- 深入理解px
- 響應式之柵格系統
- 深入理解px(二)
- 一篇搞定移動端適配
- flex版柵格布局
- 其他
- 瀏覽器加載初探
- 警惕你的開發工具
- JS模塊化
- webpack
- 打包原理
- 異步加載
- gulp
- 命名規范
- 接口開發
- sea.js學習
- require.js學習
- react學習
- react筆記
- vue學習
- vue3
- 工具、技巧
- 臨時筆記
- 怎么維護好開源項目
- 待辦
- 對前端MVV*C框架的思考
- jquery問題
- 臨時
- 好文
- 節流防抖