端开发过程中常用的上拉刷新demo,下拉刷新与此原理类似
界面如下(有点丑的demo哈):
代码如下如示:
<style>
*{
padding: 0;
margin: 0;
}
.box{
height: 100%;
/* overflow: hidden auto; */
}
#refreshContainer{
width: 90%;
margin: 0 auto;
}
ul li{
outline-style: none;
outline: none;
}
#refreshContainer li{
height: 60px;
line-height: 60px;
padding: 0 10px;
background: green;
margin: 10px auto;
list-style:none;
}
</style>
</head>
<body>
<div class="box">
<ul id="refreshContainer">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
</ul>
<p class="refreshText"></p>
</div>
</body>
<script>
(function(window) {
// 获取当前滚动条的位置
function getScrollTop() {
var scrollTop=0;
if (document.documentElement && document.documentElement.scrollTop) {
scrollTop=document.documentElement.scrollTop;
} else if (document.body) {
scrollTop=document.body.scrollTop;
}
return scrollTop;
}
// 获取当前可视范围的高度
function getClientHeight() {
var clientHeight=0;
if (document.body.clientHeight && document.documentElement.clientHeight) {
clientHeight=Math.min(document.body.clientHeight, document.documentElement.clientHeight);
}
else {
clientHeight=Math.max(document.body.clientHeight, document.documentElement.clientHeight);
}
return clientHeight;
}
// 获取文档完整的高度
function getScrollHeight() {
return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
}
var _text=document.querySelector('.refreshText'),
_container=document.getElementById('refreshContainer');
// 节流函数
var throttle=function(method, context){
clearTimeout(method.tId);
method.tId=setTimeout(function(){
method.call(context);
}, 300);
}
function fetchData() {
setTimeout(function() {
_container.insertAdjacentHTML('beforeend', '<li>new add...</li>');
}, 1000);
}
window.onscroll=function() {
if (getScrollTop() + getClientHeight()==getScrollHeight()) {
_text.innerText='加载中...';
throttle(fetchData);
}
};
})(window);
</script>
代码可直接复制
每日一分享,感谢所有关注的粉丝们
读一开始我们的H5页面秒开率只有30%左右,现在我们的H5页面秒开率达到了 75%。这中间巨大的差异究竟有哪些黑科技在里面?我们为什么要做H5页面的秒开优化?我们的秒开指标是如何统计的?客户端和H5是怎么配合做到 1+1>2的?监控是如何发现H5页面可优化项的?我们又通过监控发现了哪些可优化的问题呢?
H5秒开优化是一个老生常谈的问题,本文将逐步介绍如何通过客户端 + H5 的优化手段(1+1>2)把秒开从 30% 提升到 75% ?后续接口预请求、客户端预渲染以及预加载2.0上线后还会再次助力指标提升。
为什么要做优化?
Global Web Performance Matters for ecommerce 的报告中指出:
整体系统架构图:
首先讲一下得物用来衡量秒开的指标 FMP,那为什么不选择 FCP 或者 LCP 呢?FCP 只有要渲染就会触发,LCP 兼容性不佳,得物希望站在用户的角度来衡量秒开这件事情,用户从点击打开一个WebView到首屏内容完整的呈现出来的时间点就是得物定义的FMP触发时机。
指标清楚了之后,再来看一下完整的 FMP 包含哪些耗时。
接下来将分为两大部分进行介绍,客户端优化部分和H5 优化部分。
通过 HTML 预加载、HTML 预请求、离线包、接口预请求、链接保活、预渲染等手段提升页面首屏打开速度,其中预加载、预请求、离线包分别可提升10%左右的秒开。
通过配置由客户端提前下载好HTML主文档,当用户访问时直接使用已经下载好的HTML文档,以此减少HTML网络请求时间,从而提升网页打开速度。
前人栽树后人乘凉,得物App有很多的资源位,banner、金刚位、中通位等,这些位置显示什么内容,早就已经是智能推荐算法产出的了,那么就可以直接指定这些资源位进行预加载。
页面被预加载之后,总不能一直不更新吧?那么什么时候更新页面的缓存呢?
被现实打脸:
但是在后面的灰度过程中被现实狠狠的教育了一顿,发现有些SSR的页面会涉及到状态的变更,比如说:领劵场景。这些状态都是经过SSR服务渲染好的,用户在进入页面时还没有领劵,这个时候去更新HTML文档,实属更新了个寂寞,在用户领劵之后关闭页面再次进入,发现页面中的状态仍是让用户领劵,点击领劵又告诉人家你已经领过了。
改进措施
至此问题也解决了,工程师的任务结束了吗?如果你认为功能做上去就算结束,那么此时此刻请你一定要转变思维,想一想我们的目标是什么?我们的目标是「提升秒开」,预加载只是一种提升秒开的手段,但是在功能做上去之后并不知道这个功能带来了多少秒开的收益,因此在把功能开发完成上线之后,就要开始关注上线之后的结果,来看看预加载的性能表现如何。从下图可以看到,预加载开启状态下可提升10%以上的秒开率。
(1)SSR服务扩容
要解决服务器压力问题,很自然就会想到增加机器,于是我们对SSR机器数量做了一次扩容,将机器数量提升了一倍,这个时候继续尝试扩大预加载的用户数量,但是仍然无法抗住这么大的QPS,而且此时还引发了第二个问题,算法部门的服务器发出了告警,于是放量计划又一次遇到了阻碍。
(2)破局者 CDN
利用CDN 服务器的缓存能力既可以减轻 SSR 服务器的压力又可以减少后端服务链路的压力,这么好的东西为什么不用呢?这里留个悬念,后面将H5优化部分会详细介绍。
(3)客户端配合改造
支持针对CDN域名进行全部开放预加载能力,针对非CDN域名保持原有放量比例。
在这个过程中还分析了页面的流量占比,发现开屏广告来源的页面流量占比也很高,那么是不是可以把开屏广告的HTML文档内容也给预加载下来呢?
开屏页面预加载策略
既然可以提前下载好HTML,那是不是可以更进一步,提前把页面内的资源加载好,这样在打开一个页面的时候可以减少大部分的网络请求从而更快速的把内容呈现给用户。这里还需要考虑如何跟下面讲到的离线包进行协作。
在WebView初始化同时,去请求HTML主文档,等待HTML文档下载完成 且 WebView初始成功后渲染,减少用户等待时间,客户端请求成功后,WebView加载本地 HTML,并保存以供下次使用。预请求HTML开启状态下可提升8%左右的秒开。
预请求 VS 预加载
本质上HTML预加载和HTML预请求的区别就是下载HTML文档的时机不同, 预加载是在App启动后用户无任何操作的情况下就会去下载,但是预请求只会在用户单击打开H5页面的时候才会去下载。如果用户是第二次打开某个H5页面,此时发现本地有已经下载好的HTML且尚未过期就会直接使用,这个时候的行为表现就跟预加载的功能是一致的了。
上线之后发现预请求只提升了2%左右的秒开,经过分析发现问题:
在本地用低端机对整个秒开耗时链路进行了分析,为什么要用低端机分析呢?低端机有个好处,天然的加上了慢放功能,可以最大程度发现问题。
从图中可以看出h5 页面加载之前 耗时 分布在 activityStart() 函数,该函数 包含了 onCreateView ,其中耗时最长是 布局填充 inflate(),因为 WebView 对象是提前创建好的,直接从对象池中取出的,所以耗时主要在 初始化过程,WebView 自身的初始化 WebViewChromiumFactoryProvider. startYourEngines (耗时 87 us,不到 1 ms),耗时还有 WebView 的一些其他初始化,jockey 的初始化 等等。
而秒开的计算是包含了 View 初始化到 WebVIew url 加载 的耗时,从而发现了优化点,可以将Webview loadUrl 前置,h5 页面加载 与 原生布局填充并行执行。在 onCreateView 时,创建 FrameLayout 进行返回,执行 WebView loadUrl 之后,主线程开始 对布局进行 inflate,布局加载成功后,将其 addView 到 FrameLayout 中,减少了 loadUrl 的阻塞时长。中高端机型有 15ms 左右优化,低端机型有 30 ~ 50 ms 优化 效果。
预请求HTML时机是在进入到 native 页面中,这个时间点距离用户单击事件已经过去100ms,那么是否可以将下载HTML的时机提前呢?经过一番探索,最终选择在路由阶段进行拦截,既可以统一收口而且距离用户点击的时间间隔可以忽略不计。通过这种方式将下载HTML时机提前了平均80ms+。
此时的流程变成了下面这样。
可能有的同学会问了,为什么不在用户点击的时候去下载呢?从用户点击到路由肯定还是有耗时的。
在上述问题解决后,将缓存时间修改为1天,发现预请求HTML开启状态下可提升8%左右的秒开,已经和预加载的效果相差不大了。
通过提前将H5页面内所需的css、js等资源聚合在一个压缩包内,由客户端在App启动后进行下载解压缩,在后续访问H5页面时,匹配是否有本地离线资源,从而加速页面访问速度。
资源拦截这块安卓这边实现比较简单,WebView支持 shouldInterceptRequest, 可以在该方法内检测是否需要进行资源拦截,需要的话返回 WebResourceResponse 对象,不需要直接返回 null。
但是在iOS 这边遇到了一些困难,调研了以下方案:
NSURLProtocol 拦截方式,使用WKBrowsingContextController和registerSchemeForCustomProtocol。通过反射的方式拿到了私有的 class/selector。通过把注册把 http 和 https 请求交给 NSURLProtocol 处理。通过这种方式确实可以拦截请求,但是发现post请求的body会出现丢失的问题。而且NSURLProtocol一经注册就是全局开启。我们希望他只会拦截接入了离线包的页面,但是没有办法控制他,他会拦截所有页面的请求,包括第三方合作页面,显然这是无法接受的。
在iOS 11及以上系统中, 拥有了加载自定义资源的API:WKURLSchemeHandler。
可以修改当前页面url为自定义 scheme 协议,比如:https://fast.dewu.com 修改为 duapp://fast.dewu.com 然后在客户端内注册该 scheme,前端配合修改页面内所有的资源请求未自适应协议,如:src="//fast.dewu.com/xxx" 就可以实现拦截。但是在测试过程中发现,接口为了安全起见只允许白名单内的域名发起跨域请求,且无法配置多个域名,导致该方案无法继续进行。
仍然是使用 WKURLSchemeHandler 然后通过 hook WKWebview 的 handlesURLScheme 方法来支持 http 和 https 请求的代理。通过这种方式虽然可以拦截请求了,但是遇到了以下问题:
(1)body丢失问题
不过在 iOS 11.3 之后对这种情况做了修复处理,只有 blob 类型的数据会丢失。需要由JS来代理 fetch 和 XMLHttpRequest 的行为,在请求发起时将 body 内容通过 JSBridge 告知 native,并将请求交给客户端进行发起,客户端在请求完成后 callback js 方法。
(2)Cookie 丢失、无法使用问题
通过代理 document.cookie 赋值和取值动作,交由客户端来进行管理,但是这里需要额外注意一点,需要做好跨域校验,防止恶意页面对cookie进行修改。
至此功能开发完成上线,先来一组线上收益数据,安卓开启离线情况有有10%左右的收益,但是iOS开启离线的反而秒开率更低。经过修复处理后iOS也可提升10%以上的秒开。
安卓和iOS实现差异
经过分析对比发现,安卓的拦截动作比较轻,可以判断是否需要拦截,不需要拦截可以交给WebView自己去请求。
但是iOS这边一旦页面开启拦截后,页面中所有的http和https请求都会被拦截掉,由客户端发起请求进行响应,无法将请求交还给WebView自己去发起。
iOS 缓存问题修复
页面中的资源经过客户端请求代理后原本第二次打开WebView本身会使用缓存的内存,现在缓存也失效了,于是只能在客户端内实现了一套缓存机制。
从下图可以看到离线包的下载错误率在 6% 左右浮动,这么高的下载错误率肯定是无法接受的, 经过一系列优化手段,把离线包下载错误率从6%左右浮动下降至 0.3%左右浮动。
先来看下优化前的流程图和问题点。
通过埋点发现大量 unknown host 、网络请求失败、网络连接断开的情况。分析代码发现下载未做队列控制,会同时并发下载多个离线包,从而导致多个下载任务争抢资源的情况。针对发现的问题点做出了以下优化:
下面是优化之后的流程图:
针对离线资源是直接存储在磁盘上的,每次访问都会有磁盘IO耗时,经过在低端机器上做测试发现这个耗时会在 0 - 10ms 之间进行波动,后面会把内存合理的利用起来,通过设置内存上限,文件数量上限,甚至是文件类型,并通过 LRU 策略进行内存文件的淘汰更新。
通过客户端发起H5页面首屏接口请求,远比等待客户端页面初始化、下载HTML、JS下载执行的时机更提前,从而节省用户的首屏等待时间。在本地测试过程中发现接口预请求可提前100+ms,用户也就可以更快的看到内容。
客户端会在App启动后获取配置,保存支持预请求的页面地址及对应的接口信息,在用户打开WebView时,会并行发起对应预请求的接口,并保存结果。当JS执行开始获取首屏数据时,会先询问客户端是否已经存有对应的响应数据,如果此时已经拿到数据则无需发起请求,否则 js 也会发起接口请求并开启竞速模式。以下是整体流程图:
那么客户端怎么知道这个页面需要请求什么接口呢?以及接口的参数是什么呢?那自然少不了配置平台,它支持以下功能:
首先即使是在 SSR 的情况下,首屏内容中仍然可能有部分组件是骨架直出的,需要等待页面渲染执行时才会去请求数据,另外还有一部分页面是SPA的。针对这两种情况都能做到很好的补充。
开启后DNS 90分位耗时从80ms降至0ms,TCP建连90分位耗时从65ms分位耗时降为0,DNS平均耗时从55ms降为4.3ms,TCP建连平均耗时从30ms降为2.5ms。
通过上图可以看到一个网络请求在经过DNS解析耗时、TCP建连耗时、SSL建连耗时阶段之后才能把请求发出去,那么是否可以节省这段时间的耗时呢?
客户端常用的网络请求框架如OkHttp等,都能完整支持http1.1与HTTP2的功能,也就支持连接复用。了解了这个连接复用机制优势,那就可以利用起来,比如在APP开屏等待的时候,就预先建立关键域名的连接,这样进入相应页面后可以更快的获取到网络请求结果,给予用户更好体验。在网络环境偏差的情况下,这种预连接理论上会有更好的效果。
可以通过对域名链接提前发起一个HEAD请求从而建立链接,网络框架会自动将连接放入连接池。并在默认无操作5分钟后进行释放,在五分钟内重复执行上述动作即可一直保持链接。
另外这里需要注意下连接池的数量问题,如果连接池的数据太小,但是域名比较多的话,通过预建连保持的链接很容易就会被释放掉,这就需要通过域名收敛或者调大连接池的数量来进行优化。
那预建连会不会增加服务器的压力呢?这个肯定是会的,首先会针对预建连功能本身就行灰度策略,在HTML页面通过CDN托管后,直接针对 cdn 域名进行全量开启,从而不用担心 cdn 域名扛不住压力。
来看一下线上效果,通过下图可以看到在开启后DNS 90分位耗时从80ms降至0ms,TCP建连90分位耗时从65ms分位耗时降为0,DNS平均耗时从55ms降为4.3ms,TCP建连平均耗时从30ms降为2.5ms。
客户端提前通过WebView将页面渲染好,等待用户访问时,可直接展示。从而达到瞬开效果。但是这种功能肯定不能对所有的页面进行开放,而且存在一定的弊端。
下图【开学季】是业务上已经进行预渲染的H5页面,可以看到在打开【开学季】页面时,页面已经渲染完毕,丝毫没有等待过程。
后面计划把这种能力放大到通用的webview上,针对大促以及PV量高的页面进行开放。
SSR服务端渲染(英语:server side render)一般情况下,一个H5页面的数据渲染完全由客户端来完成,先通过AJAX请求到页面数据并把相应的数据填充到模板,形成完整的页面来呈现给用户。而服务端渲染把数据的请求和模板的填充放在了服务端,并把渲染的完整的页面返回给客户端。
SSR对于秒开有平均15%的提升,既然是服务端渲染,就会对服务器造成压力,尤其是在预加载HTML功能开启后,那得物是如何解决的呢?
通过这么多优化手段仍然无法满足预加载的需求,并且通过分析发现网络阶段耗时较长,最终还是搬出了CDN这个大杀器,一直没上CDN的原因有很多,主要有以下几方面:
(1)得物的页面是千人千面的每个人看到的内容都不同
通过上述优化4即可解决,将原本SSR渲染的内容修改CSR,由于已经上了CDN了,后续计划将这部分内容再次修改回SSR,这样用户可以更快的看到商品而不是骨架,然后通过 CSR 的方式来更新内容。
(2)页面状态变更,无法及时更新缓存
这个问题在上述客户端预加载优化部分已经有解决方案了,可以通过在页面打开后针对有需要的组件再次请求接口刷新数据以确保数据的准确性,但是这部分工作量也是比较大的,梳理出来的需要刷新状态的组件就有30+,而且之后开发的组件都需要考虑状态更新的事情。
(3)HTML模板内容变更无法及时更新
引起模板内容变更的地方有两处,第一个场景就是在搭建器场景下,运营可以动态修改模板内容导致页面结构变更(低频次),第二个场景是项目发版后模板内容需要更新(高频)。
这个问题可以通过在感知到内容变更时自动调用CDN服务商的刷新缓存接口来更新CDN缓存内容。
通过puppeteer将SPA页面渲染出来并将HTML文档进行保存,配合上述页面刷新策略,并将HTML通过CDN进行托管,让你的 SPA 页面 像 SSR 一样丝滑。
主要实现方案是通过基于webpack的插件prerender-spa-plugin,并配置需要预渲染的路由,这样经过打包之后就会产出对应路由的页面。方案本身是通用的,但是每接入一个页面都需要人工check。
众所周知 css 加载会阻塞HTML渲染,最终将首屏公共css从118kb缩减至38kb,下图通过 chrome 模拟弱网环境下的SSR页面加载时序图。从图中可以看出 styles.fb201fce.chunk.css 下载耗时 18s,阻塞了页面的渲染,HTML 主文档耗时 2.38s 就已经下载完成了,但是实际渲染时间却是在 20s 之后。
优化思路也比较单间,将首屏所需要的css 文件通过内联方式内嵌到HTML中,由SSR服务一并返回,并对css文件进行拆分,按需加载。
思路有了,接下来就看怎么去实现了,最初尝试了MiniCssExtractPlugin 插件他可以把css分成单独的文件,并且每一个js会对应生成一个css文件,但是他需要建立在webpack5之上,然而项目中使用的next版本是9.5,于是就想着升级到最新版next12,升级后发现,在构建中其他包各种报错,发现有些包并不支持最新的next12,在尝试一天的修复之后,仍未解决,且升级到最新版不确定是否会引发其他稳定性问题,暂且搁置寻找其他方法。
经过不懈的努力,通过阅读 next 源码发现了端倪,发现在打包时将所有的公共css通过 splitChunks 进行分组,由于项目中组件都是动态引入的,这里直接在 next.config.js 中修改webpack打包参数,将 splitChunks.cacheGroups.styles 配置删除,使用默认的 chunks: async 配置,即可实现按需引入。
(1)避免图片src为空
虽然src属性为空字符串,但浏览器仍然会向服务器发起一个HTTP请求,尤其是在SSR服务器压力扛不住的情况下,因此这里需要特别注意一下。
(2)图片压缩以及格式选择
WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都相当优秀、稳定和统一。
通过向图片服务器传递参数选择合适的分辨率。
(1)打包优化
(2)非关键js、css延迟加载
(3)媒体资源加载优化
(4)其他资源优化
(5)页面渲染优化
(6)代码层面优化
为了帮助开发者更好地衡量和改进前端页面性能,W3C性能小组引入了 Performance API ,其中Navigation Timing API 实现了自动、精准的页面性能打点。得物前端性能监控指标也都是从 Performance API 中获取数据进行上报统计分析的。
SDK 数据采集完毕后,会上报到 阿里云 sls 日志平台,随后通过 flink 实时消费清洗数据后落库至 clickhouse 中,平台后端通过读取 clickhouse 数据并做各种聚合处理后使用。
做优化之前首先要建立监控指标,互联网称之为抓手,没有监控指标的情况下,任你怎么优化,都不知道优化的效果怎么样,更不知道下一步该做什么?以及还有哪些问题没解决。因此优化之前指标先行,当然一定要指标的准确性。
指标大盘主要包含以下功能:
在正常情况下,完成上述的优化措施后用户基本是可以秒开 H5 页面的了。但异常情况总是会有的,用户的网络环境和系统环境千差万别,甚至 WebView 也可能发生内部崩溃。当发生问题时,用户看到的可能就直接只是一个白屏页面了,所以进一步的优化手段就是需要去检测是否发生白屏以及相应的应对措施。
检测白屏最直观的方案就是对 WebView 进行截图,遍历截图的像素点的颜色值,如果非纯色的颜色点超过一定的阈值,就可以认为不是白屏。首先获取包含 WebView 视图的 Bitmap 对象,然后把截图缩小到指定的分辨率大小如:100*auto,遍历检测图片的像素点,当非纯色的像素点大于 5% 的时候就可以认为是非白屏的情况,但是还有很多列外的情况,我们通过图片识别技术对截图进行分析,可以很好的感知当前是否白屏、是不是在loading、是不是特殊页面等。
白屏是一个重要的指标,我们针对整体白屏率快速拉升、新增白屏页面发出告警通知,便于开发人员及时介入开始排查问题。
主要通过 CDN 未覆盖监控、http请求监控、网络监控(加载失败、耗时异常、传输大小异常)、图片监控(未压缩、分辨率异常)等监控手段发现页面中的潜在问题,同时还提供了问题分析能力,在问题分析页面输入页面url地址即可帮助您发现问题并给出修改建议。
CDN的重要性不言而喻,它可以加速资源访问速度,从而提升用户体验,我们通过对线上埋点数据分析,找出CDN未覆盖的资源列表,从而推动各业务同学优化。
为什么要监控HTTP请求呢?我们先来看一下HTTPS相对于HTTP新增的特点:
那么HTTP就容易被中间人查看到内容,甚至被篡改,既然如此为了我们服务的安全性就需要对现有的http协议统一进行升级改造,那就需要监控去发现。
某些页面秒开率低,那就要分析一下原因,是不是这个页面的接口响应比较慢呢,还是说页面本身有请求比较大的资源?如果发生网络请求失败的情况也要第一时间感知,不能被动等待用户反馈。
包含图片未压缩、图片分辨率异常、图片传输大小大于 300kb 异常、动图资源传输大小大于 1M 异常功能。
上面列出来一堆功能,对于业务的同学可能比较烦恼,我一个页面具体有哪些问题呢?你不能让我去上面的功能里面一个个看,哪个异常是我负责的页面的吧?这个功能本身就行将现有的功能利用起来,通过一个页面path进行聚合分析。
H5异常一直是使用 sentry 进行监控的,但是sentry系统因缺乏同PV、DAU数据的关联性,因此无法衡量产品异常发生后所带来的严重程度。在业务域关联上的缺失导致异常问题无法根据业务域进行划分。用户行为日志也尚未与Native 端侧打通,在问题分析时容易遇到上下文不全的瓶颈。还有一个问题是sentry会有限流措施,当qps较高时会丢弃一部分异常数据。
由于sentry已经可以帮助我们进行一定的问题排查分析能力,我们不打算做sentry同样的功能,而是做sentry不支持的部分,针对上述问题我们设计了以下功能:
虽然目前秒开率已经做到了75%以上,但是同时我们还有一个重要的指标,90分位耗时,致力于提升末尾用户H5页面使用体验,在90分位优化完成后,可能会考虑继续深入优化95分位耗时。
至此我们系统的讲解了背景以及从指标建立到秒开优化上线的全过程,全文分成了三个部分,客户端、H5、以及监控。如果阅读本文对您有所收获,麻烦您动一动发财的小手点个赞吧!如果阅读完还意犹未尽或者有什么问题和想法欢迎留言区评论交流。
最后奉上整体优化脑图:
*文/徐铭
欢迎关注「得物技术」微信公众号,每周一三五晚18:30更新技术干货
要是觉得文章对你有帮助的话,欢迎评论转发点赞~
端开发
软件开发是一个高度专业化的职业分工,根据所使用的编程语言的不同,会细分出多种岗位:前端开发、后端开发、客户端开发、iOS开发、Android开发、数据库开发等等,具体到每一个岗位,工作中常用的工具软件也存在着差别。
就前端开发或前端工程师来说,前端技术的发展可以说是日新月异,新工具和框架层出不穷,以应对不断变化的市场需求。在这篇文章中,我们将介绍前端开发中常用的8大类工具软件,以及每个类别下面最具代表性的产品,总计17款工具软件,帮助各位在选择前端工具时减少纠结,提高工作效率和开发质量。
前端开发常用的17款工具软件
选用哪个编辑器来写代码,与 IT 界由来已久的一个话题「XX语言是最好的编程语言」有点像,每个人都有自己的想法。工具本身本身并不是最重要的,能否写出简洁、优雅的代码,主要是取决于自己的个人经验和逻辑能力,代码思路没梳理清楚,代码编辑器雕出花来也没用哇。
① WebStorm
WebStorm,最智能的 JavaScript IDE 工具,是一个用于 JavaScript 和相关技术的集成开发环境。与 JetBrains 推出的其他 IDE 一样,它使你的开发体验更加愉快,使日常工作自动化,并帮助你轻松处理复杂的任务。
② VS Code
VS Code,微软推出的开源代码编辑器,支持 Windows、macOS 和 Linux 系统。单凭免费 + 轻量 + 大厂背景(光环)这些点,想必就吸引了不少人。
VS Code 虽然不像 WebStorm 定位为 IDE 工具,但它可以内置的扩展功能、可以安装不同的插件,也让 VS Code 在保证灵活性的同时,也能变得足够强大——软件本身没有的功能,可以用插件来弥补。
除了这里介绍的两个工具,其他可选的代码编辑器有 Sublime Text、Atom、Vim、CodePen(在线代码编辑工具) 等,这里就不展开介绍了。
① Git
Git 是目前最流行的分布式版本控制系统,它具有高效的分支管理和合并功能,可以支持大型项目的开发和维护。Git 使用简单,有强大的命令行工具和图形界面工具,例如 Git Bash 和 Sourcetree。程序员可以通过 Git 进行代码的提交、拉取、推送等操作,同时还可以方便地查看代码的历史记录和比较不同版本之间的差异。
② SVN
SVN 是一种集中式版本控制系统,与 Git 不同,它使用集中式的服务器来存储代码,并且需要通过网络连接才能进行代码的提交和更新。SVN 具有较为简单的操作和较好的稳定性,适合小型项目和对分支管理要求不高的团队使用。程序员可以通过 TortoiseSVN 等图形界面工具来进行 SVN 的操作,也可以通过命令行工具来进行更高级的操作。
当涉及前端开发时,npm(Node Package Manager)和Yarn都扮演着至关重要的角色,它们是包管理工具,用于管理JavaScript库和框架的依赖关系。
① npm
npm是JavaScript世界中最常见的包管理工具之一,它是Node.js的官方包管理器,囊括了各种用于前端和后端开发的包。npm提供了功能强大且灵活的命令行界面,用于执行各种操作,包括安装依赖项、更新包、运行脚本等。这使得前端开发者可以在命令行中快速而高效地完成各种任务。
② Yarn
Yarn是JavaScript世界中的另一款重要的包管理工具,尤其受到前端开发者的欢迎。它在某些方面与npm相似,但也有自己的独特特点:
出色的性能:Yarn被设计为更快的包管理工具。它支持并行下载和安装依赖项,从而提高了性能。这对于大型项目和具有多个依赖项的应用程序特别有帮助,能够显著加快构建和安装速度。
版本锁定:Yarn使用yarn.lock文件来确保依赖关系的一致性。这意味着在不同开发环境中的版本冲突问题将被大大减少,确保您的项目在不同的计算机上以相同的方式运行。
易于使用:Yarn的命令和操作更加直观,使新手可以更快地上手。它提供了更友好的命令行交互和更清晰的日志输出,帮助开发者更好地理解正在发生的事情。
自定义包源:Yarn允许配置自定义包源,这对于需要使用特定镜像或私有存储库的项目非常有帮助。这为开发者提供了更大的灵活性,以适应不同的项目要求。
Yarn提供了一种高性能、可靠且易于使用的包管理工具,适用于前端开发项目。它的版本锁定和离线模式等功能使其在复杂的项目环境中尤为有用。选择使用npm还是Yarn取决于您的项目需求和个人偏好,但无论您选择哪一个,都可以提高包管理的效率。
① boardmix
boardmix是一款跨平台的笔记工具,有点接近微软推出的OneNote,但功能比OneNote更强大。
boardmix可以帮助程序员将各种信息和想法整理成文档、文档卡片、思维导图、便签等形式,支持文字、代码块、图片、表格、链接等多种内容的插入,还可以通过标签和容器来组织和分类笔记。此外,boardmix还支持手写和音视频通话功能,方便程序员在会议或讨论中进行记录。
*跨平台笔记工具boardmix
跨平台笔记工具boardmix的特点:
② Evernote
Evernote是一款功能强大的云端笔记应用,它可以帮助程序员随时随地记录和整理自己的想法、代码片段、技术文档等。Evernote支持多种格式的笔记,包括文字、图片、音频和视频等,还可以通过标签和笔记本来组织和分类笔记。
③ Typora
Markdown笔记软件是程序员常用的一种笔记工具,它使用简洁的标记语法来编写和格式化文本,可以帮助程序员记录和整理代码片段、技术文档、项目文档等信息。
市面上可选择的Markdown笔记软件非常多,其中最具代表性的是Typora。Typora是一款跨平台的Markdown编辑器,它提供了实时预览功能,可以让程序员在编写的同时实时查看渲染后的效果。Typora支持多种导出格式,如PDF、HTML等,方便用户分享和发布笔记。
① Webpack
说到前端构建工具,不得不提许多前端工程师都逃不过的 Webpack,我们先来看一下 Webpack 中文文档对 Webpack 的介绍:
Webpack,是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 Webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。
如果是第一接触 Webpack 的朋友,看完这段介绍应该还是一脸懵逼,不知道 Webpack 到底能用来干什么。
随着前端变得越来越复杂,我们在使用框架编写项目时,可能会有下面这些行为:
以其中的 Sass 样式文件为例,浏览器默认情况下只能渲染 CSS 文件,而不认识这里的 Sass 文件,要想将 Sass 文件转换为浏览器可读取的 CSS 文件,就需要用到 Webpack,实现 Sass 到 CSS 的自动转换。
除了 Sass 文件,Webpack 还可以将 ES6 语法的 JS 代码转换为 ES5,将 TypeScript 代码转换为 JavaScript,也可以对图片、字体等进行打包优化,减少文件占用的空间,可以这么说,有了 Webpack,原先我们要处理的一系列问题,都可以让它自动帮我们完成。
② Vite
Vite是一个快速、现代的前端构建工具,专为Vue.js框架设计,但也支持其他现代JavaScript框架和库。
快速开发:Vite是为了提高前端开发的速度而创建的。它利用ES模块的特性,将开发服务器保持在本地开发环境中,实现了快速的冷启动和热模块替换(HMR),这意味着您可以在几乎没有构建等待时间的情况下迅速查看更改。
Vue 3支持:Vite是Vue 3的官方开发工具,它紧密集成了Vue 3的特性和生态系统。这使得使用Vite来构建Vue 3应用程序变得非常高效。
支持其他框架和库:尽管最初是为Vue.js设计的,但Vite也支持React、Preact、Svelte等现代JavaScript框架和库。这意味着开发者可以在不同项目中使用Vite,而不仅仅限于Vue.js。
插件系统:Vite具有灵活的插件系统,可以通过插件扩展其功能。这使得开发者可以根据项目需求轻松自定义构建过程。
构建优化:尽管Vite在开发环境下快速运行,但它也提供了用于生产构建的工具,以优化和压缩代码,减小文件大小。
开发者体验:Vite注重开发者体验,提供清晰的错误消息和有用的调试工具,以帮助开发者更轻松地诊断和解决问题。
Vite是一个面向现代前端开发的快速工具,它通过利用ES模块、本地开发服务器和HMR等特性,提供了出色的开发体验。它适用于Vue.js项目,同时也能够支持其他流行的JavaScript框架和库,使其成为前端开发者的强大工具。
浏览器开发工具
对于前端Web开发,浏览器开发工具是非常有用的调试工具。浏览器开发工具可以帮助程序员查看网页的HTML结构、CSS样式和JavaScript代码,同时还可以监控网络请求和调试JavaScript代码。常见的浏览器开发工具有Chrome开发者工具、Edge开发者工具、Firefox开发者工具等。
① Bootstrap
Bootstrap是由Twitter开发的开源前端框架,它提供了一组CSS和JavaScript工具,用于创建现代、响应式的Web页面和Web应用程序。
② Material-UI
Material-UI是一个基于Google的Material Design理念的React组件库。它旨在提供Material Design的外观和感觉,以及与React的深度集成。
① easy auto refresh
easy auto refresh,一个自动刷新浏览器页面的插件,比较适合刚接触前端的新人。
在未使用前端框架或 Webpack 打包项目的情况下,每当我们想预览代码在浏览器中的运行效果,都需要手动刷新页面,操作起来比较繁琐。
对于这个问题,可以使用这里介绍的浏览器插件 ,提前设置一个刷新的频率,就能实现页面的自动刷新。
② FeHelper(前端助手)
FeHelper,一个可以格式化 json 数据的浏览器插件。
在浏览器中查看服务器返回的 json 数据时,由于它们被压缩过,去除了数据中原有的换行,会呈现为「乱成一团」的状态,不便于查看我们想要的数据。
而 FeHelper 插件,就可以让被压缩后的 json 数据还原为压缩前的状态,即对数据进行格式化,美化压缩后的数据文件,让我们可以更方便地查看服务器返回的数据。
③ Vue Devtools
Vue Devtools(Vue.js开发者工具)是专门为Vue.js开发者设计的浏览器扩展,它提供了强大的调试和开发工具,有助于更好地理解、分析和调试Vue.js应用程序。
*请认真填写需求信息,我们会在24小时内与您取得联系。