金山云

深拷貝/淺拷貝

Object.assign可以實(shí)現(xiàn)淺拷貝
后面突然想起來(lái)的,追加的時(shí)候追忘了說(shuō)的啥

原生對(duì)象

應(yīng)該是高程,對(duì)js對(duì)象分原生對(duì)象和引用對(duì)象
說(shuō)道原生對(duì)象我容易忽略object與function

對(duì)象

面向?qū)ο笕筇攸c(diǎn),繼承,多態(tài)與封裝

其中

繼承

指子類繼承父類的特征和行為,使得子類對(duì)象具有父類的實(shí)例域和方法,以達(dá)到復(fù)用的目的,是面向?qū)ο笳Z(yǔ)言的基礎(chǔ)特性

在面向?qū)ο蟊皇袌?chǎng)接收后,js選擇了強(qiáng)行面向?qū)ο笠簿褪且蕾囋玩湹睦^承方式

原型鏈繼承實(shí)現(xiàn)

針對(duì)面向原型鏈繼承的驗(yàn)證包括幾個(gè)關(guān)鍵函數(shù)
constructor,__proto__,prototype

原型鏈繼承驗(yàn)證

針對(duì)驗(yàn)證,主要幾個(gè)關(guān)鍵函數(shù)
isPrototypeOf,hasOwnProperty,instanceof,typeof

甚至包括ie系列的isXXX系列

原型鏈繼承驗(yàn)證bug

但問(wèn)題在于,整體的驗(yàn)證體系
1.屬于鴨辨式
2.兩套體系,主要指ie的isXXX系列
即使到了Object.prototype.toString為止,也沒(méi)有填完原型鏈繼承驗(yàn)證的坑
(主要指宿主環(huán)境下的對(duì)象,跨域下對(duì)象比較(這個(gè)類似與不同jvm解析對(duì)對(duì)象是否相同))

原型鏈繼承使用

最后在使用上,基于原型鏈繼承實(shí)現(xiàn),除了框架上的掛載外,很少主動(dòng)使用
比如vue任意組件內(nèi)部的this依次繼承VueComponent,Vue,允許this可直接使用Vue掛載的其他實(shí)例
但是諸如其他熱插拔式的組件,則不會(huì)繼承Vue,比如VueRouter等
大部分組件庫(kù)或框架也是如此,比如jq組件,可以通過(guò)this使用jq的實(shí)例化方法

但也僅限于此,更多的方式使用組合,本身繼承就有屬性污染或者非必要的創(chuàng)建等很已被證明的冗余的內(nèi)容(這里尤其值java,以及java針對(duì)繼承爆炸所設(shè)計(jì)的23中設(shè)計(jì)模式)

針對(duì)ui組件庫(kù),一般都不會(huì)選擇完整的繼承,類似于混合或者閹割的概念,無(wú)視對(duì)象的判斷,更像是依賴原型鏈進(jìn)行復(fù)用的技巧,比如easyui

    $.fn.combobox = function(options, param){
        if (typeof options == 'string'){
            var method = $.fn.combobox.methods[options];
            if (method){
                return method(this, param);
            } else {
              //此處this指向的是jquery的實(shí)例,而非是combobox的實(shí)例,如果按照任意一款關(guān)于js原型鏈繼承的demo去參考,這里絕對(duì)會(huì)怪怪的
                return this.combo(options, param);
            }
        }
    }

原型鏈繼承使用原則

結(jié)合prototype.js針對(duì)原生原型拓展的槽點(diǎn),我一般會(huì)表達(dá)如下意思
1.自己給自己開(kāi)發(fā)的可以繼承
2.使用別人開(kāi)發(fā)的只能組合
除非打補(bǔ)丁,或者有特定的解決方案,比如Ext

因?yàn)楸旧聿⒎菑?qiáng)類型語(yǔ)言,所以這塊問(wèn)題不大

js繼承的替代

繼承是為了代碼復(fù)用,而代碼復(fù)用的方式有兩種
1.組合
2.繼承
而組合一定會(huì)談到的就是閉包

閉包

針對(duì)閉包,引用犀牛書,包含兩個(gè)部分
1.函數(shù)對(duì)象通過(guò)作用域進(jìn)行關(guān)聯(lián)
2.函數(shù)體內(nèi)變量保存在函數(shù)作用域內(nèi)
簡(jiǎn)單地說(shuō)的確是解決變量污染
但問(wèn)題是,閉包來(lái)自詞法作用域,這個(gè)是現(xiàn)代編程語(yǔ)言都有的,他不算js的特性

我想描述的意思應(yīng)該是閉包可以實(shí)現(xiàn)代碼復(fù)用,代替繼承

url執(zhí)行發(fā)生了什么

這是我做java的時(shí)候做的總結(jié)

1.瀏覽器請(qǐng)求前過(guò)濾-- 每個(gè)瀏覽器并不相同,可能會(huì)包括
- 補(bǔ)全url
如默認(rèn)http協(xié)議,最后的字符串/去掉
- 驗(yàn)證url
如非法協(xié)議會(huì)轉(zhuǎn)換為http
- 沒(méi)有網(wǎng),直接默認(rèn)404
- 脫機(jī)/離線數(shù)據(jù)
- 網(wǎng)址關(guān)聯(lián)
- 地址記錄
- 安全警告
等等基于體驗(yàn)或惡意的功能,最后是發(fā)送請(qǐng)求
2.發(fā)送請(qǐng)求
- DNS解析
- TCP連接
- 請(qǐng)求
- 反饋【瀏覽器處理請(qǐng)求頭】
比如根據(jù)后臺(tái)傳遞類型與系統(tǒng)關(guān)聯(lián),以進(jìn)行下一步比如自帶瀏覽器下載,第三方插件如迅雷下載或頁(yè)面加載
- 內(nèi)容傳輸
- 連接結(jié)束
- 處理內(nèi)容
1.包括進(jìn)行關(guān)聯(lián),如自動(dòng)打開(kāi)word,圖片等,國(guó)企常見(jiàn)需求,通過(guò)url請(qǐng)求,自動(dòng)打開(kāi)某軟件
2.檢測(cè)同源協(xié)議,主要指xhr,通過(guò)瀏覽器一般沒(méi)有
3.自定義的如頁(yè)面渲染
- 第三方插件,比如chrome下的json美化
- 也可能有惡意攔截或惡意劫持,參考360

內(nèi)存泄漏與溢出

描述

無(wú)用內(nèi)存無(wú)法釋放

實(shí)例

經(jīng)常在jq的兩套數(shù)據(jù)緩存上進(jìn)行對(duì)比,jq針對(duì)數(shù)據(jù)緩存,即

$.fn.setData()

為什么要修改實(shí)現(xiàn)

代碼規(guī)范

操作上一般強(qiáng)調(diào),減少對(duì)dom的數(shù)據(jù)掛載

vue訂閱與發(fā)布

Object.defineProperty,配合代理,攔截array系列各種增刪改函數(shù),針對(duì)對(duì)象屬性的新增與刪除使用$set,這個(gè)在2.0應(yīng)該依然沒(méi)有變化
更早的angular,avalon則會(huì)使用臟檢

vue不監(jiān)聽(tīng)對(duì)象的新增

對(duì)接接口的時(shí)候,后臺(tái)有次優(yōu)化,針對(duì)所有undefined數(shù)據(jù),全部不返回,以節(jié)省流量,所以所有對(duì)象,全都要求有默認(rèn)數(shù)據(jù)(兩組默認(rèn)數(shù)據(jù),一類正常的默認(rèn)數(shù)據(jù),以面對(duì)產(chǎn)品,一類為數(shù)據(jù)結(jié)構(gòu),屬性為undefined,以面對(duì)后臺(tái)),而后通過(guò)Object.assign的方式一層層進(jìn)行修正,本身考慮過(guò)如何讓vue監(jiān)聽(tīng)對(duì)象屬性的新增或者在操作是使用Vue.set的方式進(jìn)行動(dòng)態(tài)添加

而Vue3則會(huì)計(jì)劃使用new Proxy來(lái)重新進(jìn)行實(shí)現(xiàn)
所以對(duì)vue不能監(jiān)聽(tīng)數(shù)據(jù)的屬性新增比較執(zhí)念

vue組件內(nèi)props與data命名沖突

因?yàn)楹笈_(tái)語(yǔ)言,比如java的原因,數(shù)據(jù)與事件是在類的同一級(jí)下,類似于

{
    ...data,
    ...methods
}

的形式,這種形式依賴命名或者說(shuō)代碼實(shí)施檢測(cè)
如果前端這么使用,如果有重名,一定會(huì)依照順序被覆蓋
比如banckbone,用友的iuap
這里強(qiáng)調(diào)一下,因?yàn)閐ata的監(jiān)聽(tīng),類似于rsjx,為開(kāi)發(fā)人員主動(dòng)監(jiān)聽(tīng),不存在結(jié)構(gòu)轉(zhuǎn)換的問(wèn)題
結(jié)構(gòu)如下

{
    name:ko.observable(''),
    getName(){

    }
}

所以很容易出現(xiàn)

{
    ...data,
    ...methods
}

這種形式

沖突處理

我在把iuap改成vue寫法的時(shí)候遇見(jiàn)過(guò)這個(gè)問(wèn)題,假設(shè)真的重名了,怎么處理,應(yīng)該是忽略,假設(shè)data中已存在并處理過(guò)改name,則在其他地方如methods時(shí),不在處理,那么針對(duì)vue就是,假設(shè)props已經(jīng)被監(jiān)聽(tīng),則忽略data,

vue源碼

//初始化執(zhí)行順序
export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  //依次進(jìn)行初始化
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

//初始化data函數(shù)
function initData (vm: Component) {
    //...
    if{
        //...
    }else if (!isReserved(key)) {
        //當(dāng)屬性并未被訂閱過(guò),即非props屬性
      proxy(vm, `_data`, key)
    }
  }
    //...
}

ajax

異步j(luò)s與xml,并不局限于數(shù)據(jù),在jq中一直是可以用來(lái)獲取后臺(tái)json數(shù)據(jù),xml結(jié)構(gòu),文本結(jié)構(gòu),jsonp甚至script,最早的組件加載器都是用ajax加載script實(shí)現(xiàn)的,比如easyui,ext自帶的loader,一般會(huì)配合如下代碼

loader('tableUI')
$(function(){
  //1.業(yè)務(wù)代碼
})

loader中會(huì)重新代理$(),已達(dá)到組件正確加載的目的
也包括百度,高德等第三方軟件商提供的各種loader

amd與cmd

談到async和ajax的時(shí)候大概是想描述這類代碼

//同步的
async function main()=>{
    //1.初始化代碼
    ....
    //2.初始化組件
    //按需加載
    //await $.getScript('xxx')
    await loader('tableUI')
    $.tableUi('#table');
}

//或者

//異步的
function main()=>{
    //1.初始化代碼
    //2.初始化組件
    loader('tableUI').then(()=>{
        $.tableUi('#table');
    })
}

requirejs與seajs的確有寫法上的區(qū)別或者叫原理上的區(qū)別,問(wèn)題是在具體實(shí)現(xiàn)時(shí),盡量會(huì)要求同步為主,否則會(huì)有不必要的麻煩

比如金山云控制臺(tái),點(diǎn)擊數(shù)據(jù)庫(kù)【關(guān)系數(shù)據(jù)庫(kù)】,再點(diǎn)擊數(shù)據(jù)庫(kù)【表格數(shù)據(jù)庫(kù)】,業(yè)務(wù)層無(wú)發(fā)正常渲染,應(yīng)該就是table組件沒(méi)有家在上的原因

i加載順序

回流與重繪

在用java做dom解析的時(shí)候,遇見(jiàn)的一個(gè)問(wèn)題,dom的屬性可以修改,但節(jié)點(diǎn)類型無(wú)法修改,應(yīng)該怎么處理

對(duì)應(yīng)的其實(shí)就是回流與重繪

重繪
$0.align="right"

dom節(jié)點(diǎn)并沒(méi)有修改,可以重復(fù)使用,使用后臺(tái)也很好處理,Render樹保持不變,相應(yīng)的dom進(jìn)行重繪即可

回流

對(duì)應(yīng)的,如果將h2標(biāo)簽改成h3標(biāo)簽如何處理
無(wú)論是js還是java都需要通過(guò)函數(shù)處處理,一定是新增和刪除dom,而新增與刪除會(huì)修改Render樹的坐標(biāo),故稱為回流
針對(duì)java上,我可能會(huì)描述為
1.局部更新
調(diào)用實(shí)例對(duì)象的set系列
2.全局更新
調(diào)用靜態(tài)函數(shù)changeDom系列

概念借用

圖表系列,比如highchart或者某些圖行處理上會(huì)引用類似的概念,比如只是修改了data,調(diào)用repaint,而修改了title或者整體的結(jié)構(gòu),那就是reflow

vm描述

其實(shí)用vm描述大概這樣

    export default {
        data(){
            return {
                //監(jiān)聽(tīng)dom樹
                domTree:[]
            }
        },
        watch:{
            renderTree(){
                reflow();
            }
        },
        computed:{
            //獲取render樹
            renderTree(){
                return _.map(domTree,(dom)=>{
                    return {
                        dom:dom,
                        x:getX(dom),
                        y:getY(dom)
                    }
                })
            }
        }
    }
類似結(jié)構(gòu)

而這個(gè)結(jié)構(gòu)又類似于iview的table組件
使用iview的table組件不能進(jìn)行編輯,要么重寫一個(gè)EditTable,直接進(jìn)行數(shù)據(jù)的綁定,但是會(huì)丟失很多配置性的功能,要么修改內(nèi)部的rebuildData

我在寫knockout下的table組件時(shí),也遇見(jiàn)過(guò)類似的問(wèn)題

抖動(dòng)與節(jié)流

throttle/debounce這兩個(gè)函數(shù)我也是今天才知道叫抖動(dòng)和節(jié)流,我一般是放在高頻處理上描述
原文如下


重復(fù)提交(高頻處理)

  • 重復(fù)提交

單位時(shí)間內(nèi),多次非冪等(post)請(qǐng)求,造成的后臺(tái)重復(fù)錄入現(xiàn)象

此處重點(diǎn)討論前端的防重復(fù)提交的方式

  • 快速點(diǎn)擊

單位時(shí)間內(nèi),快速點(diǎn)擊,觸發(fā)異步事件,照成數(shù)據(jù)與ui混亂的現(xiàn)象

如導(dǎo)航,分頁(yè)等,當(dāng)導(dǎo)航快速點(diǎn)擊,會(huì)使內(nèi)容區(qū)異常抖動(dòng),且可能會(huì)與導(dǎo)航具體標(biāo)簽不一致

屬于高頻,但比較獨(dú)特,包含了異步操作,故單獨(dú)拿出來(lái)處理

  • 高頻事件

單位時(shí)間內(nèi),觸發(fā)的各類事件,且響應(yīng)速度低于請(qǐng)求,照成的卡頓或其他混亂現(xiàn)象,如快速點(diǎn)擊,鼠標(biāo)移動(dòng)

以上三種情況之后統(tǒng)一描述重復(fù)提交

最終效果

  • 阻止過(guò)多的ajax請(qǐng)求(post/get)
  • 正確響應(yīng)最后一次結(jié)果

關(guān)鍵技術(shù)點(diǎn)

  • Aborted

xhr的abort函數(shù)

  • setTimeout

  • 限制性UI

修改按鈕/UI,彈菊花

重復(fù)判斷

保存正在進(jìn)行的ajax操作(0<readyState<4)及其url,當(dāng)該操作存在,且又要發(fā)送相同請(qǐng)求時(shí),視為重復(fù)提交

實(shí)現(xiàn)

實(shí)現(xiàn)的方式有很多,此處會(huì)盡量做到減少污染和依賴(變化)

根據(jù)影響范圍,做以下區(qū)分

ajax攔截/包裹/封裝

此處使用lodash的函數(shù)式寫法,如果喜歡es7的裝飾方式,需要做細(xì)微的調(diào)整

abort函數(shù)

對(duì)原有xhr(ajax),進(jìn)行abort處理

對(duì)于post,并沒(méi)有阻止ajax請(qǐng)求,請(qǐng)求已經(jīng)發(fā)送,后臺(tái)依然在處理請(qǐng)求

對(duì)于get,可以保證當(dāng)前請(qǐng)求為正確的結(jié)果(解決快速點(diǎn)擊)

實(shí)現(xiàn)
var global={};

$.ajaxSetup({
  beforeSend:function(jqXHR, s ){
  //為jqXHR注入url
    var callbackContext = this;
    jqXHR._url=callbackContext.url
  }
});


function abort(ajax){
  //獲取上一個(gè)請(qǐng)求
  var preajax = global[ajax._url];
  preajax&&preajax.abort();
  global[ajax._url]=ajax
};

var abort_ajax=_.flow($.get,abort);

abort_ajax('/');
abort_ajax('/');
abort_ajax('/');
abort_ajax('/');

此種實(shí)現(xiàn)默認(rèn)url獲取數(shù)據(jù)后,會(huì)對(duì)數(shù)據(jù)進(jìn)行分發(fā)

分頁(yè),導(dǎo)航,搜索(度娘)均可使用


ajax提交
其他

若為傳統(tǒng)(10年前-。-)的組件+url的形式,如

<select url="api/students"></select>
<select url="api/students"></select>

此時(shí),會(huì)產(chǎn)生兩條相同請(qǐng)求,獲取數(shù)據(jù)后并不分發(fā),需要改寫代碼

若對(duì)ajax進(jìn)行了封裝,使用注入Store/Model,vuex,flux之類的模型

根據(jù)不同的場(chǎng)景描述不同的action,性質(zhì)是一樣的

裝飾

如果非要用es7裝飾,注意,promise(現(xiàn)在)沒(méi)有abort,以下寫法,不好實(shí)現(xiàn)(單指寫法,不探討是否適合)

@abort
async  submit(){
    var data=await Store.load('');
    console.log(data);
}

abort思路,可以解決異步交互(get)下,最后一次響應(yīng)的問(wèn)題

js是同步的,無(wú)法解決同步的多次提交(同步為卡頓,響應(yīng)順序并不會(huì)錯(cuò)誤)

忽略(單例)

根據(jù)url,對(duì)ajax實(shí)現(xiàn)單例,即當(dāng)前url正在通訊時(shí),返回上一個(gè)ajax,不在創(chuàng)建信息ajax

實(shí)現(xiàn)
var ignore_ajax=function(params){
    var preajax = global[params.url];
    if(preajax){
      return preajax
    }
    var ajax = $.ajax(params)
    ajax.then(function(){
        global[this.url]=undefined;
    })
    global[params.url] = ajax;
    return ajax;
}

ignore_ajax({url:'/'});
ignore_ajax({url:'/'});
ignore_ajax({url:'/'});
ignore_ajax({url:'/'});

例子中省略global,ajaxSetup步奏,下同

一般由Store,Model等封裝ajax的模塊,配合readyState進(jìn)行操作,即將ajax改成單例

無(wú)法保證最后一次請(qǐng)求的響應(yīng),故本身會(huì)配合ui進(jìn)行限制性操作

保存系列,均可使用

其他
  • 對(duì)于后臺(tái)超級(jí)接口,需要個(gè)性化處理
  • 會(huì)無(wú)視,結(jié)果未返回時(shí),請(qǐng)求參數(shù)(body內(nèi))已變更的請(qǐng)求(配合ui)

throttle/debounce

高頻(鼠標(biāo)移動(dòng),窗口大小)請(qǐng)求中,調(diào)整請(qǐng)求和響應(yīng)速度的方式,屬于setTimeout的花樣使用

實(shí)現(xiàn)
var debounce_ajax = _.debounce($.ajax,5000);
debounce_ajax('/')
其他
  • throttle

優(yōu)先執(zhí)行,之后放啞炮,類似于忽略(單例),無(wú)法保證能夠準(zhǔn)確的響應(yīng)最后一次操作

不依賴最后一次響應(yīng)的事件,比如mousemove,對(duì)于異步需要配合ui限制(也可以改用忽略的方式),總之,不是最好的選擇

  • debounce

單位時(shí)間內(nèi)收集數(shù)據(jù),而后進(jìn)行請(qǐng)求,

包含數(shù)據(jù)收集的輸入框,都可以使用比如觸發(fā)框,富文本自動(dòng)保存

另:度娘的服務(wù)器就是屌

memoize

get冪等

實(shí)現(xiàn)
var memoize_ajax =_.memoize($.ajax)
其他

沒(méi)錯(cuò),就是緩存,主要用于數(shù)據(jù)更新頻率低的冪等異步操作

比如requireJS,加載導(dǎo)航數(shù)據(jù),菜單欄,甚至各種樹結(jié)構(gòu)

validate/error/timeout

禁止訪問(wèn)(權(quán)限),異常處理,超時(shí)等情況,雖然不屬于重復(fù)提交,但處理上類似

限制ui

此處ajax依賴ui,屬于ajax處理后臺(tái)進(jìn)階表現(xiàn),尤其是單例的情況下

當(dāng)然,只用ui控制也無(wú)所謂,多入口保存的情況還是比較少的

disabled/active系列/轉(zhuǎn)菊花

將整個(gè)操作函數(shù)封裝為promise,并通過(guò)e獲取相應(yīng)ui

export function buttonDisable(promise){
    //尋找依賴ui
    var e=arguments[arguments.length-1]
    var btn=e.target.parentElement;
    //設(shè)置類 or 屬性 or 轉(zhuǎn)菊花
    btn.setAttribute('disabled','')
    promise()
      .then(()=>{
        btn.removeAttribute('disabled');
      })
      .catch(()=>{
        btn.removeAttribute('disabled');
      })
}

@buttonDisable
async  submit(){
    var data=await Post('/');
    console.log(data);
}

es6寫法(es5略)

整體包裹/限制的范圍為submit的執(zhí)行過(guò)程,若單獨(dú)對(duì)ajax進(jìn)行限制,對(duì)于嵌套/并行等各種花式ajax完全無(wú)愛(ài)

當(dāng)然,如果強(qiáng)迫必須視圖屬性代替視圖,也可以做如下操作

export function buttonDisable(vm){
  return function(promise){
    vm(false);
    promise()
      .then(()=>{
        vm(true);
      })
      .catch(()=>{
        vm(true);
      })
    }
}

@buttonDisable(vm.submitFlag)
async  submit(){
    var data=await Post('/');
    console.log(data);
}
<button class="u-button u-button-info " data-bind="{click:submit,attr:{disabled:submitFlag}}">提交</button>

submitFlag,需要提前定義,轉(zhuǎn)菊花監(jiān)聽(tīng)submitFlag變化即可

封裝ajax,監(jiān)聽(tīng)readyState

async  submit(){
    var data=await Store.load('');
    console.log(data);
}
<button class="u-button u-button-info " data-bind="{click:submit,attr:{disabled:Store.readyState}}">提交</button>

Store為ajax的封裝,其中readyState為監(jiān)聽(tīng)對(duì)象(屬性),如果沒(méi)有這一層...那就有一個(gè),算一個(gè)-。-

其他

將整個(gè)執(zhí)行函數(shù)處理為promise,而后進(jìn)行個(gè)性化處理

最好不要在ajax處理中,包含ui操作

后臺(tái)重復(fù)驗(yàn)證

提前提供id,將創(chuàng)建,改寫為"修改",防止一對(duì)一的關(guān)系轉(zhuǎn)換為一對(duì)多

ssh系列的token防重復(fù)提交,指的是該系列

緩存系列與數(shù)據(jù)庫(kù)平級(jí),不討論

其他情況并不處理...


原文結(jié)束

我想說(shuō)的應(yīng)該是clearTimeout

線程

瀏覽器是多線程
html自身的至少三個(gè)
1.事件
比如setTimeout和dom1中的事件流
2.渲染/GUI
html/css
3.xhr
以及最后網(wǎng)景后來(lái)增加的
4.js引擎

以我個(gè)人的角度看,應(yīng)該還有個(gè)主線程,去分配GUI與JS,順便保證他們的互斥性,這個(gè)應(yīng)該就是瀏覽器本身

我以前做java的時(shí)候,會(huì)說(shuō)就當(dāng)js與GUI在一個(gè)線程里即瀏覽器頁(yè)面主線程,所以造成的GUI與js的互斥,這點(diǎn)的確是描述的有問(wèn)題

而針對(duì)css與html包括js的并行,主要想描述的是依順序運(yùn)行,針對(duì)單核,多線程屬于按順序或按優(yōu)先級(jí),依次進(jìn)行運(yùn)算,這個(gè)屬于強(qiáng)行解釋

16ms

針對(duì)16ms,大概還有個(gè)14K,script壓縮保持14K倍數(shù)的傳說(shuō)吧,tcp傳輸,每包起步14K
即某種意義上看1k與10k傳輸速度相同

300ms是測(cè)試的要求,大致是頁(yè)面不能白屏超過(guò)300ms,否則按bug算

12-11補(bǔ)充

加載器

針對(duì)加載器(amd/cmd),除了開(kāi)發(fā)過(guò)loader或者使用過(guò)外,針對(duì)UI組件,主要是ext與easyui,有過(guò)細(xì)節(jié)的優(yōu)化
主要要針對(duì)的是不需要返回組件對(duì)象的組件,比如彈出層,模態(tài)框這些
屬于在業(yè)務(wù)代碼風(fēng)格不變的情況下按需加載,類似于dll的動(dòng)態(tài)引用

不需要返回結(jié)構(gòu)的加載器

整體結(jié)構(gòu)如下

//種子
$.modal = (config)=>{
    if(!$.widgets.modal){
        //加載模態(tài)框組件代碼
        loader('modal').then(()=>{
            //生成模態(tài)框組件
            $.widgets.modal(config);
        }) 
    }else{
        $.widgets.modal(config);
    }
} 

其實(shí)更像是代理,如果其他需要返回的組件也這么處理,本身來(lái)講與loader整體語(yǔ)法上是重復(fù)的,最主要是針對(duì)組件通訊或組件依賴完全無(wú)解,大致風(fēng)格如下,

$('#xxx').tableUI({
    
})
.then(tableUI){
    
}

模態(tài)框加載

后續(xù)對(duì)模態(tài)框的加載又做了一次處理,這里類似業(yè)務(wù)代碼的動(dòng)態(tài)加載,現(xiàn)在基本上由路由統(tǒng)一處理,問(wèn)題不大
模態(tài)框組將相當(dāng)其他組件來(lái)講,在交互上更依賴結(jié)構(gòu)(data)而不是dom,尤其是在模態(tài)框由iframe或者window.open實(shí)現(xiàn)的時(shí)候
比如使用時(shí)

    {
        //業(yè)務(wù)使用
        methods:{
            async getUser(){
                try{
                    var res = await UserModal(config);
                    cosnole.log('已選擇',res)
                }catch(e){
                    console.log('未選擇')
                }
            }
        }
    }

模態(tài)框--UserModal,這里可以用繼承,組合甚至裝飾

import ModalComponent from './ModalComponent'

export default function Modal(config) {
    return new Promise((resolve, reject) => {
        const Instance = new Vue({
            render(h) {
                return h(ModalComponent)
            },
            methods: {
                ok(data) {
                    resolve(data);
                    this.destroy();
                },
                remove() {
                    reject();
                    this.destroy();
                },
                destroy() {
                    document.body.removeChild(this.$el);
                }
            }
        });
        const component = Instance.$mount();
        document.body.appendChild(component.$el);
    })
}

最終業(yè)務(wù)實(shí)現(xiàn)

<template>
    <Modal v-model="show" @on-ok="ok">
        模態(tài)框
    </Modal>
</template>
<script>
    export default {
        data(){
            return {
                show:true
            }
        },
        methods:{
            ok(){
                this.$parent.ok({
                    name:'xx'
                })
            }
        }
    }
</script>

按需加載dom

這里其實(shí)是按需加載dom,把js再次Promse就是按需加載js與dom

應(yīng)該說(shuō)所有的串性交互的組件都可以這么實(shí)現(xiàn)(平行的也可以,或者依賴反饋,或者多次發(fā)送,比如導(dǎo)航模塊和業(yè)務(wù)模塊),以實(shí)現(xiàn)動(dòng)態(tài)加載的目的,比如復(fù)雜的下拉或詳情等

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一:什么是閉包?閉包的用處? (1)閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在本質(zhì)上,閉包就 是將函數(shù)內(nèi)部和函數(shù)外...
    xuguibin閱讀 10,027評(píng)論 1 52
  • 2018web前端最新面試題總結(jié) 一、Html/Css基礎(chǔ)模塊 基礎(chǔ)部分 什么是HTML?答:? HTML并不是...
    duans_閱讀 4,711評(píng)論 3 27
  • 如果,僅是如果 歸園田居 世外桃源 能不能 與你一起 看花開(kāi)花落 忘卻紅塵往事 如果,僅是如果 拋棄名利 祛除邪念...
    綠色視界閱讀 225評(píng)論 0 0
  • 最近啊,發(fā)現(xiàn)很多人訂閱付費(fèi)知識(shí)。一點(diǎn)也不便宜還沒(méi)效果。我一個(gè)都沒(méi)訂。來(lái),讓我給你盤一下,第一,買書可以裝飾家居環(huán)境...
    富山居閱讀 258評(píng)論 0 1
  • 當(dāng)下懶人開(kāi)發(fā)越來(lái)越流行,本地的數(shù)據(jù)保存是每個(gè)項(xiàng)目必然會(huì)遇到的,之前我項(xiàng)目中也有使用GreenDao來(lái)進(jìn)行對(duì)象化的數(shù)...
    野生大P閱讀 492評(píng)論 2 2

友情鏈接更多精彩內(nèi)容