首页
统计
墙纸
留言
Search
1
PVE8优化
43 阅读
2
mysql创建数据库
41 阅读
3
jenkins根据分支、文件夹打包
37 阅读
4
vue-cli注册全局方法
23 阅读
5
ContOS安装jdk
22 阅读
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
登录
/
注册
Search
标签搜索
vue+elementui
Cicaba
累计撰写
146
篇文章
累计收到
23
条评论
首页
栏目
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
页面
统计
墙纸
留言
搜索到
137
篇与
的结果
2019-07-05
CSS优化
1.内联首屏关键CSS大家应该都习惯于通过link标签引用外部CSS文件。但需要知道的是,将CSS直接内联到HTML文档中能使CSS更快速地下载。而使用外部CSS文件时,需要在HTML文档下载完成后才知道所要引用的CSS文件,然后才下载它们。所以说,内联CSS能够使浏览器开始页面渲染的时间提前,因为在HTML下载完成之后就能渲染了。既然内联CSS能够使页面渲染的开始时间提前,那么是否可以内联所有的CSS呢?答案显然是否定的,这种方式并不适用于内联较大的CSS文件。因为初始拥塞窗口存在限制(TCP相关概念,通常是 14.6kB,压缩后大小),如果内联CSS后的文件超出了这一限制,系统就需要在服务器和浏览器之间进行更多次的往返,这样并不能提前页面渲染时间。因此,我们应当只将渲染首屏内容所需的关键CSS内联到HTML中。不过内联CSS有一个缺点,内联之后的CSS不会进行缓存,每次都会重新下载。不过如上所说,如果我们将内联后的文件大小控制在了14.6kb以内,这似乎并不是什么大问题。2.异步加载CSSCSS会阻塞渲染,在CSS文件请求、下载、解析完成之前,浏览器将不会渲染任何已处理的内容。有时,这种阻塞是必须的,因为我们并不希望在所需的CSS加载之前,浏览器就开始渲染页面。那么将首屏关键CSS内联后,剩余的CSS内容的阻塞渲染就不是必需的了,可以使用外部CSS,并且异步加载。3.有选择地使用选择器大多数朋友应该都知道CSS选择器的匹配是从右向左进行的,这一策略导致了不同种类的选择器之间的性能也存在差异。相比于#box-content-h3,显然使用#box .content h3时,浏览器生成渲染树(render-tree)所要花费的时间更多。因为后者需要先找到DOM中的所有h3元素,再过滤掉祖先元素不是.content的,最后过滤掉.content的祖先不是#box的。试想,如果嵌套的层级更多,页面中的元素更多,那么匹配所要花费的时间代价自然更高。优化方案保持简单,不要使用嵌套过多过于复杂的选择器。通配符和属性选择器效率最低,需要匹配的元素最多,尽量避免使用。4.减少使用昂贵的属性在浏览器绘制屏幕时,所有需要浏览器进行操作或计算的属性相对而言都需要花费更大的代价。当页面发生重绘时,它们会降低浏览器的渲染性能。所以在编写CSS时,我们应该尽量减少使用昂贵属性,如box-shadow/border-radius/filter/透明度/:nth-child等。
2019年07月05日
1 阅读
0 评论
0 点赞
2019-07-05
HTML优化
JavaScript中使用document.write生成页面内容会效率较低,可以找一个容器元素,比如指定一个div,并使用innerHTML来将HTML代码插入到页面中。当link标签的href属性为空、script标签的src属性为空的时候,浏览器渲染的时候会把当前页面的URL作为它们的属性值,从而把页面的内容加载进来作为它们的值。为文件头指定Expires。使内容具有缓存性,避免了接下来的页面访问中不必要的HTTP请求。重构HTML,把重要内容的优先级提高。Post-load(次要加载)不是必须的资源。利用预加载优化资源。合理架构,使DOM结构尽量简单。利用LocalStorage合理缓存资源。尽量避免CSS表达式和滤镜。尝试使用defer方式加载Js脚本。新特性:will-change,把即将发生的改变预先告诉浏览器。新特性Beacon,不堵塞队列的异步数据发送。不同之处:网络缓慢,缓存更小,不令人满意的浏览器处理机制。尽量多地缓存文件。使用HTML5 Web Workers来允许多线程工作。为不同的Viewports设置不同大小的Content。正确设置可Tap的目标的大小。使用响应式图片。支持新接口协议(如HTTP2)。未来的缓存离线机制:Service Workers。未来的资源优化Resource Hints(preconnect, preload, 和prerender)。使用Server-sent Events。设置一个Meta Viewport。
2019年07月05日
6 阅读
0 评论
0 点赞
2019-07-04
JavaScript的DOM编程性能优化
DOM是Document Object Model的缩写,中文叫做文档对象模型,是一个与语言无关的,用户操作XML和HTML文档的应用程序接口。在浏览器中,主要与HTML文档打交道,在Web应用中也经常需要检索XML文档,DOM API用于访问文档中的数据。我们把DOM和JavaScript各自想象成一个岛屿,它们直接用收费桥梁连接,ECMAScript每次访问DOM,都要经过这个桥,并交纳“过桥费”,过的桥越多交的费用也越多,因此要想减少费用就得少过桥,我们这里就来如何来优化这个问题最小化DOM访问次数,尽可能在JavaScript端处理访问DOM元素是有代价的–前面提到的过桥费。修改元素则更加昂贵,因为它会导致浏览器重新计算页面的集合变化。也就是说访问DOM次数越多,代码的运行速度就越慢,因此一般的经验法则是:减少DOM的访问次数,把运算尽量留在ECMAScript这一段处理。 //最坏的情况是在循环中访问和修改元素 //尤其是对HTML元素集合循环操作。 //方法一 function innerHTMLLoop() { for (var count = 0; count < 15000; count++) { document.getElementById('here').innerHTML += 'a'; } } //方法二 function innerHTMLLoop() { var content = ''; for (var count = 0; count < 15000; count++) { content += 'a'; } document.getElementById('here').innerHTML += content; } //显然方法二的实现要好很多多次访问DOM节点,使用局部变量存储它的引用这些方法返回值是一个集合document.getElementByName()document.getElementByClassName()document.getElementByTagName()下面属性也同样返回HTML集合document.imagesdocument.linksdocument.formsdocument.forms[0].elements这些集合是一些昂贵的东西,一般来说,对于任何类型的DOM访问,当同一个DOM属性或方法需要多次访问时候,最好把一个局部变量缓存此成员。当遍历一个集合时,首先优化原则是把集合存储在局部变量中,并把length缓存在循环外部,然后使局部变量访问这些需要多次访问的元素。使用速度最快的API浏览器提供了一个名为querySelectorAll()的原生DOM方法,这种方法自然比使用JavaScript和DOM来遍历查找元素要快很多。//查找id="menu"的元素中的所有a元素 //我们习惯做法 var elements=document.getElementById('menu').getElementsByTagName('a'); //建议做法 var elements=document.querySelectAll('#menu a');还有一个遍历方法–querySelector()来获取第一个匹配的节点。留意重绘和重排DOM树:表示页面结构渲染树:表示DOM节点如何显示一旦DOM和渲染树构建完成,浏览器就开始显示(绘制)页面元素了,当DOM的变化影响的元素的几何属性(宽或高),比如修改边框宽度或给段落增加元素,导致行数增加–浏览器需要重新计算元素的集合属性,同样其他元素的几何属性和位置也会因此受到影响,浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程就称为“重排(reflow)”。完成重排后,浏览器重新绘制受影响的部分到屏幕中,这个过程就叫做重绘(repaint)重排和重绘操作都是代缴昂贵的操作,应当减少发生,为了减少发生次数,应当合并DOM和样式的修改,然后一次性处理掉。还可以通过缓存布局信息的方法:尽量减少布局信息的获取次数,获取后把它赋值给局部变量,然后再操作局部变量。减少在循环内进行DOM操作,在循环外部进行DOM缓存//优化前代码 var _li = $("<li>"), _dom = $("<div>"), timer = null; for (var i = 0; i < 50; i++) { //随机生成50个li,插入到ul列表中 $(".list-ul").append(_li.clone()); }//优化后代码 var _li = $("<li>"), _dom = $("<div>"), _lis = document.getElementsByTagName("li"), timer = null, _arr = []; for (var i = 0; i < 50; i++) { //随机生成50个li,存入到数组中 _arr.push(_li.clone()); } //将生成好的全部li一次性append到ul中 $(".list-ul").append(_arr);优化前的代码中,对于 $(".list-ul") 元素进行了50次的append,即进行了50次的DOM操作。而对于优化后的代码,在append操作前,先将所有 存入数组中,最后只进行了一次append,因此性能会有所提高。操作DOM前,先把DOM节点删除或隐藏list.style.display = "none"; for (var i=0; i < items.length; i++){ var item = document.createElement("li"); item.appendChild(document.createTextNode("Option " + i); list.appendChild(item); } list.style.display = "";display属性值为none的元素不在渲染树中,因此对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行多次DOM操作,可以先将其隐藏,操作完成后再显示。这样只在隐藏和显示时触发2次重排,而不会是在每次进行操作时都出发一次重排。
2019年07月04日
7 阅读
0 评论
0 点赞
2019-06-20
动态创建script标签
使用动态创建的标签元素来下载并执行代码var script = document.createElement('script'); script.type = "text/javascript"; script.src = "file.js"; document.querySelector("head").appendChild(script);这种方式加载脚本好处。无论何时启动下载,文件的下载和执行过程不会阻塞页面其他进程。缺点:你无法处理脚本加载失败。使用XHR对象下载JS代码注入页面var xhr = new XMLHttpRequest(); xhr.open("get", "script1.js", true); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){ var script = document.createElement ("script"); script.type = "text/javascript"; script.text = xhr.responseText; document.body.appendChild(script); } } }; xhr.send(null); 此代码向服务器发送一个获取 script1.js 文件的 GET 请求。onreadystatechange 事件处理函数检查readyState 是不是 4,然后检查 HTTP 状态码是不是有效(2XX 表示有效的回应,304 表示一个缓存响应)。如果收到了一个有效的响应,那么就创建一个新的<script>元素,将它的文本属性设置为从服务器接收到的 responseText 字符串。这样做实际上会创建一个带有内联代码的<script>元素。一旦新<script>元素被添加到文档,代码将被执行,并准备使用。 这种方法的主要优点是,您可以下载不立即执行的 JavaScript 代码。由于代码返回在<script>标签之外(换句话说不受<script>标签约束),它下载后不会自动执行,这使得您可以推迟执行,直到一切都准备好了。另一个优点是,同样的代码在所有现代浏览器中都不会引发异常。 此方法最主要的限制是:JavaScript 文件必须与页面放置在同一个域内。
2019年06月20日
12 阅读
0 评论
0 点赞
2019-06-03
TS的命名空间和装饰器
命名空间以namespace关键值定义命名空间.namespace Obj{ export interface Person{ name:string; age:number; getMsg(name:string):string{} } } new Obj.Serson()装饰器装饰器是一种特殊类型的声明,它可以用在类声明、方法、属性或者参数上。顾名思义,它是用来给附着的主体进行装饰,添加额外的行为。装饰器使用@expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。类装饰器类装饰器:类装饰器在类声明之前被声明(紧靠着类声明)。类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。 传入一个参数function run(target: any) { return class extends target { type: string = 'Web开发工程师' getType() { console.log(this.type) } } } @run class Person { type: string | undefined; constructor(type: string = "工程师") { this.type = type; } getType() { console.log(this.type) } } new Person().getType()属性装饰器属性装饰器接收两个参数(原型对象,参数)属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。2、成员的名字。function test(params: any) { return function (target: any, attr: any) { debugger target[attr] = params; } } class Person { @test('工人') type: string | undefined; constructor(type: string = "工程师") { } getType() { console.log(this.type) } } new Person().getType()方法装饰器它会被应用到方法的属性描述符上,可以用来监视,修改或者替换方法定义。方法装饰会在运行时传入下列3个参数:1、对于静态成员来说是类的构造函数,对于实例成员类的原型对象。2、成员的名字。3、成员的属性描述符。function test(parems?: any): Function { return function (target: any, name: string, desc: any) { let fn: Function = desc.value; desc.value = (...arr: Array<any>): void => { arr = arr.map(v => String(v)); fn(arr); }; }; } class Person { type: string | undefined; constructor(type: string = "工程师") { } @test() getType( ...arr: Array<any>) { console.log(arr) } } new Person().getType(1,"2",3)方法参数装饰器参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据, 传入下列3个参数: 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。2、方法的名字。3、参数在函数参数列表中的索引。
2019年06月03日
8 阅读
0 评论
0 点赞
2019-05-24
table表头固定
HTML部分<div style="width: 800px;"> <div class="table-head"> <table> <colgroup> <col style="width: 80px;" /> <col /> </colgroup> <thead> <tr><th>序号</th><th>内容</th></tr> </thead> </table> </div> <div class="table-body"> <table> <colgroup><col style="width: 80px;" /><col /></colgroup> <tbody> <tr><td>1</td><td>我只是用来测试的</td></tr> <tr><td>2</td><td>我只是用来测试的</td></tr> <tr><td>3</td><td>我只是用来测试的</td></tr> <tr><td>4</td><td>我只是用来测试的</td></tr> <tr><td>5</td><td>我只是用来测试的</td></tr> <tr><td>6</td><td>我只是用来测试的</td></tr> <tr><td>7</td><td>我只是用来测试的</td></tr> <tr><td>8</td><td>我只是用来测试的</td></tr> <tr><td>9</td><td>我只是用来测试的</td></tr> <tr><td>10</td><td>我只是用来测试的</td></tr> <tr><td>11</td><td>我只是用来测试的</td></tr> <tr><td>12</td><td>我只是用来测试的</td></tr> <tr><td>13</td><td>我只是用来测试的</td></tr> <tr><td>14</td><td>我只是用来测试的</td></tr> <tr><td>15</td><td>我只是用来测试的</td></tr> </tbody> </table> </div> </div>Css部分.table-head{padding-right:17px;background-color:#999;color:#000;} .table-body{width:100%; height:300px;overflow-y:scroll;} .table-head table,.table-body table{width:100%;} .table-body table tr:nth-child(2n+1){background-color:#f2f2f2;}
2019年05月24日
2 阅读
0 评论
0 点赞
2019-05-13
TypeScript多态和抽象类
多态父类定义的一个方法不去实现, 让继承的子类去实现.(多态属于继承)class Person{ name:string; run():void{} } Class Mi extends Person{ super('小米'); run():string{ return this.name+'手机' } } new Mi().run()抽象类typescript中的抽象类: 它是提供给其它类继承的基类, 不直接实例化.用abstract关键字定义抽象类和抽象方法. 抽象类中的抽象方法不包含具体实现并必须在派生类中实现.abstract抽象方法只能放在抽象类中.abstract class Person{ name:string; abstract run():void; } Class Mi extends Person{ super('小米'); run():string{ return this.name+'手机' } } new Mi().run()
2019年05月13日
5 阅读
0 评论
0 点赞
2019-04-22
typescript学习笔记二
函数返回值的类型定义fu(): void{}函数的参数必须定义类型fu(name: string, age: number){}函数的默认值fu(name: string = "小米", age: number = 9) {}接口接口的作用: 在面向对象的编程中, 接口是一种规范的定义, 它定义了行为和动作的规范, 在程序设计里面,接口起定义标准的作用.接口的可选属性, 在属性的名的后面添加一个问号(?).只读属性, 在属性名前添加一个readonly.只读数组类型, readonly Array<数组元素类型>. 注意把一个普通数组赋值给readonlyArray后普通数组也只可读.interface Job { type: string; jobTime?: string; description(): string; } class Mi implements Job { readonly type: string; jobTime: string; constructor(type: string, jobTime: string = "8") { this.type = type; this.jobTime = jobTime; } description() { return this.type + '工作' + this.jobTime + "小时;" } } console.log(new Mi("小米").description());函数类型接口, 用来定义函数的参数列表,和返回值的类型的定义.参数列表使用小括号():返回值的类型. 如:(height:string,width:string):boolean;interface Job { (jobTime: string, type?: string): string; } class Mi { readonly type: string; jobTime: string; constructor(type: string, jobTime: string = "8") { this.type = type; this.jobTime = jobTime; } description: Job = (jobTime: string, type: string) => { this.jobTime = jobTime; return this.type + '工作' + this.jobTime + "小时;"; } } console.log(new Mi("小米").description("9"));可索引的类型, 它具有一个索引签名, 签名的类型只有两种(number,string). 还有相应的索引返回值类型.如:readonly [index:number]:string. (只读索引)interface Job { [index: string]: string; } class Mi { readonly type: string; jobTime: string; constructor(type: string, jobTime: string = "8") { this.type = type; this.jobTime = jobTime; } description(jobTime: string, type?: string): object { this.jobTime = jobTime; let obj: Job = { type: this.type, jobTime: this.jobTime } return obj } } console.log(new Mi("小米").description("9"));
2019年04月22日
3 阅读
0 评论
0 点赞
2019-04-22
typescript 学习笔记一
typescript环境的搭建安装环境npm install -g typescript配置typescript 在项目的更目录下新建一个tsconfig.json 配置如下{ "compilerOptions": { "target": "es5", "noImplicitAny": false, "module": "commonjs", "removeComments": true, "sourceMap": false, "outDir": "Golang/TypeScript/" } //"include":[ // "ts" // ], //"exclude": [ // "js" // ] } // target:编译之后生成的JavaScript文件需要遵循的标准。有三个候选项:es3、es5、es2015。 // noImplicitAny:为false时,如果编译器无法根据变量的使用来判断类型时,将用any类型代替。为true时,将进行强类型检查,无法推断类型时,提示错误。 // module:遵循的JavaScript模块规范。主要的候选项有:commonjs、AMD和es2015。为了后面与node.js保持一致,我们这里选用commonjs。 // removeComments:编译生成的JavaScript文件是否移除注释。 // sourceMap:编译时是否生成对应的source map文件。这个文件主要用于前端调试。当前端js文件被压缩引用后,出错时可借助同名的source map文件查找源文件中错误位置。 // outDir:编译输出JavaScript文件存放的文件夹。 // include、exclude:编译时需要包含/剔除的文件夹。编译ts执行tsc -w 会自动检查变化并自动编译typescript类型约束typescript 是超javascript有着类型的检测 let str :string; //这里定义str必须为一个字符串类型,否则会报错 str = '小米' console.log(str) //数组的类型定义 let arr :number[];//在[]前面定义数组元素的类型 arr = [1,2] console.log(arr) //第二种方式是使用数组泛型,Array<元素类型>: let list: Array<number> = [1, 2, 3]; //第三种方式是使用数组泛型,any类型 let list: any[] = [1, 2, 3]; //元组 let arr :[string,number,boolean]; arr = ['min',2,true] console.log(arr) //any let flag :any = null;//any类型可以赋值任何类型 //vold 某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void: fn():vold{ alert("TS") } //never never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。 // 返回never的函数必须存在无法达到的终点 function error(message: string): never { throw new Error(message); } // 推断的返回值类型为never function fail() { return error("Something failed"); } // 返回never的函数必须存在无法达到的终点 function infiniteLoop(): never { while (true) { }接口接口的定义 interfaceinterface Person { firstName: string; lastName: string; }接口的作用:用来检测类型function allname(str:Person){ //str必须是Person的类型(接口一般配合类使用) console.log(str.firstName+str.lastName) } allname({firstName:"小",lastName:"米"})类类的定义classclass Name{ //类名必须大写 age:number;//类型必须提前定义 constructor(public firstName, public lastName){ this.age=18 } }接口和类的结合使用interface Person { firstName: string; lastName: string; } class Name{ age:number; constructor(public firstName, public lastName){ this.age=18 } } function allname(str:Person){ console.log(str) } allname(new Name('',''))枚举enum Color {Red, Green=0, Blue}; let ColorName:string = Color[0]; console.log(ColorName);使用enum定义默认是从0开始可以手动指定枚举值也可以通过枚举值获得它的名字Any类型Any类型及任何类型,在编译过程中不会检测类型.知道部分类型比如:let arr:Any[] = ["小米"];类型断言使用尖括号方式//("小米").indexOf('小');as方式//("小米" as string).indexOf('米');总结接口: 用来检测类型.类: 用来生成实例.多类型定义使用 | 隔开.
2019年04月22日
7 阅读
0 评论
0 点赞
2019-04-09
vue-cli集成TypeScript
1- 安装ts-loader和typescriptnpm install --save-dev ts-loader@3
[email protected]
使用的webpack为3, 所以必须使用ts-loader@32- 修改webpack.base.conf.js配置文件修改webpack.base.conf.js下的entry>app为'./src/main.ts' extensions: ['.js', '.vue', '.json', '.ts', '.tsx']//添加'.ts', '.tsx' 文件引入不用写后缀 rules: [ { test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, options: { appendTsSuffixTo: [/\.vue$/], } },//添加tsloader加载器 ...其他 ]3- 在src目录下新建一个文件vue-shims.d.ts,用于识别单文件vue内的ts代码declare module "*.vue" { import Vue from "vue"; export default Vue; }4- 在项目根目录下建立TypeScript配置文件tsconfig.json{ "compilerOptions": { "strict": true, "module": "es2015", "moduleResolution": "node", "target": "es5", "allowSyntheticDefaultImports": true, "lib": [ "es2017", "dom" ] } } //"jsx": "preserve" jsx支持5- 修改main.js后缀改为ts, 添加引入文件的的后缀.6- 修改router.js后缀改为ts.7- 测试//下面可以测试是否集成成功,编辑src/components/Hello.vue文件,修改 <script lang="ts"> import Vue, {ComponentOptions} from 'vue' export default { name: 'hello', data() { return { msg: 'this is a typescript project now' } } } as ComponentOptions<Vue> </script>8- 配置官方推荐的,vue-class-component修改ts配置文件,增加以下两项配置"allowSyntheticDefaultImports": true,"experimentalDecorators": true,使用vue-class-component后,初始数据可以直接声明为实例的属性,而不需放入data() {return{}}中,组件方法也可以直接声明为实例的方法,如官方实例,更多使用方法可以参考其官方文档import Vue from 'vue' import Component from 'vue-class-component' // @Component 修饰符注明了此类为一个 Vue 组件 @Component({ // 所有的组件选项都可以放在这里 template: '<button @click="onClick">Click!</button>' }) export default class MyComponent extends Vue { // 初始数据可以直接声明为实例的属性 message: string = 'Hello!' // 组件方法也可以直接声明为实例的方法 onClick (): void { window.alert(this.message) } }问题1- ts 无法识别 requireyarn add @types/webpack-env -D
2019年04月09日
3 阅读
0 评论
0 点赞
1
...
4
5
6
...
14